17.访问者模式
貌似这是螃蟹学的最后一个设计模式了,可能还有其他的,不过常用的也够了。所谓访问者设计模式,其实也好理解,就是通过访问者实现访对象的访问和处理。就像我计划要去旅游,好多国家都想去,但是我可能是一次游完,最佳就是一次去一个好好玩一下。访问者设计模式在于对象的功能处理,不需要全部定义在原对象里,而是拆分处理,便于更多的开发者参与进来,也可以很好拓展。
参考项目模块:商品排序
由于商品对象是固定的,但经常要对商品进行不同的排序,而不同的排序得出的商品列表格式都是相同的,那么使用访问者设计模式来实现对商品的处理就是很好的方式。这里螃蟹再次尝试用新的方式来实现商品排序。
商品对象:Goods.class.php
<?php class Goods{ public $title = ''; public $price = 0; public $distance = 0; public function __construct($goods){ $this->title = $goods['title']; $this->price = $goods['price']; $this->distance = $goods['distance']; } public function getArray(){ return array('title'=>$this->title,'price'=>$this->price,'distance'=>$this->distance); } } ?>
<?php require_once('Goods.class.php'); class GoodsList{ public $goods_objs = ''; public $goods_array = ''; public function __construct(){ $this->goods_objs = array(); $this->goods_array = array(); } public function addGoods(Goods $goods){ array_push($this->goods_objs, $goods); array_push($this->goods_array, $goods->getArray()); } public function getDefaultList(){ foreach ($this->goods_objs as $goods){ echo ' 商品名:'.$goods->title; echo ' 价格:'.$goods->price; echo ' 距离:'.$goods->distance; echo '<br><br>'; } } public function getOrderList(){ foreach ($this->goods_array as $goods){ echo ' 商品名:'.$goods['title']; echo ' 价格:'.$goods['price']; echo ' 距离:'.$goods['distance']; echo '<br><br>'; } } public function getVisitor($visitor,$sortType='ASC'){ if($sortType=='ASC'){ $this->goods_array = $visitor->AscSort($this->goods_array); }else{ $this->goods_array = $visitor->DescSort($this->goods_array); } } } ?>
价格排序访问类:PriceSort.visitor.php
<?php require_once('Sort.fun.php'); class PriceSort{ public function AscSort($goodslist){ return SortFun::subSort($goodslist, 'price','ASC'); } public function DescSort($goodslist){ return SortFun::subSort($goodslist, 'price','DESC'); } } ?>
<?php require_once('Sort.fun.php'); class DistanceSort{ public function AscSort($goodslist){ return SortFun::subSort($goodslist, 'distance','ASC'); } public function DescSort($goodslist){ return SortFun::subSort($goodslist, 'distance','DESC'); } } ?>
<?php class SortFun{ //二维数组排序算法 public static function subSort($arr,$keys,$type='ASC'){ $keysvalue = $new_array = array(); foreach ($arr as $k=>$v){ $keysvalue[$k] = $v[$keys]; } if($type == 'ASC'){ asort($keysvalue); }else{ arsort($keysvalue); } reset($keysvalue); $i=0; foreach ($keysvalue as $k=>$v){ $new_array[$i] = $arr[$k]; $i++; } return $new_array; } } ?>
<?php function __autoload($className){ if(file_exists($className.'.class.php')){ require_once($className.'.class.php'); } if(file_exists($className.'.visitor.php')){ require_once($className.'.visitor.php'); } } //模拟商品数据 $goods = array(); $goods[0] = array('title'=>'六神花露水','price'=>12.99,'distance'=>3.04); $goods[1] = array('title'=>'七神花露水','price'=>10.99,'distance'=>1.14); $goods[2] = array('title'=>'八神花露水','price'=>8.99,'distance'=>5.24); $goods[3] = array('title'=>'九神花露水','price'=>23.29,'distance'=>0.74); $goods[4] = array('title'=>'十神花露水','price'=>1.99,'distance'=>13.64); //添加到商品集合 $goodsLists = new GoodsList(); foreach ($goods as $goodsData){ $goodsobj = new Goods($goodsData); $goodsLists->addGoods($goodsobj); } echo '<h3>正常输出</h3>'; $goodsLists->getDefaultList(); echo '<h3>按价格从高到低</h3>'; $goodsLists->getVisitor(new PriceSort(),'DESC'); $goodsLists->getOrderList(); echo '<h3>按价格从低到高</h3>'; $goodsLists->getVisitor(new PriceSort(),'ASC'); $goodsLists->getOrderList(); echo '<h3>按距离从近到远</h3>'; $goodsLists->getVisitor(new DistanceSort(),'ASC'); $goodsLists->getOrderList(); ?>
正常输出 商品名:六神花露水 价格:12.99 距离:3.04 商品名:七神花露水 价格:10.99 距离:1.14 商品名:八神花露水 价格:8.99 距离:5.24 商品名:九神花露水 价格:23.29 距离:0.74 商品名:十神花露水 价格:1.99 距离:13.64 按价格从高到低 商品名:九神花露水 价格:23.29 距离:0.74 商品名:六神花露水 价格:12.99 距离:3.04 商品名:七神花露水 价格:10.99 距离:1.14 商品名:八神花露水 价格:8.99 距离:5.24 商品名:十神花露水 价格:1.99 距离:13.64 按价格从低到高 商品名:十神花露水 价格:1.99 距离:13.64 商品名:八神花露水 价格:8.99 距离:5.24 商品名:七神花露水 价格:10.99 距离:1.14 商品名:六神花露水 价格:12.99 距离:3.04 商品名:九神花露水 价格:23.29 距离:0.74 按距离从近到远 商品名:九神花露水 价格:23.29 距离:0.74 商品名:七神花露水 价格:10.99 距离:1.14 商品名:六神花露水 价格:12.99 距离:3.04 商品名:八神花露水 价格:8.99 距离:5.24 商品名:十神花露水 价格:1.99 距离:13.64
PHP的设计到这里就告一段落了,螃蟹也感觉收货不少,面向对象的很多概念又重温了一遍,后面肯定会在项目中尝试使用各种设计模式,提高项目的质量,也算是提高螃蟹自身的价值吧。好吧,还有一会下班,周末愉快~~