<<一天一个设计模式>>
转自phpchina论坛 作者ID:kakashilw
一、工厂模式
1、先看一个简单的例子
<?php interface IUser { function getName(); } class User implements IUser { public static function Load( $id ) { return new User( $id ); } public static function Create( ) { return new User( null ); } public function __construct( $id ) { } public function getName() { return "Jack"; } } $uo = User::Load( 1 ); echo( $uo->getName()."n" ); ?> |
2、一个稍微复杂但却相当经典的例子
<?php //BT种子的接口 interface BT { public function process(); } //BT种子的下载处理类 class BTdown implements BT { public function process() { //输出BT种子 echo '输出BT种子'; } } //BT种子的上传处理类 class BtUpload implements BT { public function process() { //保存上传的BT种子 echo '保存上传的BT种子'; } } --------------------------------------------------------------- //生产BT种子处理对象的设备的接口 interface BTcreator { public function createBTObject(); } //生产BT种子下载处理对象的设备 class BTdownCreator implements BTcreator { public function createBTObject() { /** * 如果不是管理员,送10点积分 */ //然后返回BT种子下载处理对象 return new BTdown(); } } //生产BT种子上传处理对象的设备 class BTUploadCreator implements BTcreator { public function createBTObject() { /** * 如果不是管理员,扣10点积分 */ //然后返回BT种子下载处理对象 return new BtUpload(); } } ------------------------------------------------------------------ //生产BT种子处理对象的工厂 class BtFactory { //获取电影处理类的对象,参数为类名 public function getBtObject($name) { switch ($name) { case 'BTdown': $creator = new BTdownCreator(); break; case 'BtUpload': $creator = new BtUploadCreator(); break; } return $creator->createBTObject(); } } --------------------------------------------------------------------- //获取bt工厂 $btFactory = new BtFactory(); //BT种子的下载处理 $what = 'BTdown'; $btObject = $btFactory->getBtObject($what); $btObject->process(); //BT种子的上传处理 $what = 'BtUpload'; $btObject = $btFactory->getBtObject($what); $btObject->process(); ?> |
二、单件模式
<?php class userInfo { private $userName; //唯一的实例 private static $instance; //构造方法 private function __construct() { //查询数据库,获得用户名 $this->userName = 'lightsaber'; } //获取对象实例 public static function getInstance() { if (self::$instance=='') self::$instance = new userInfo(); return self::$instance; } //返回用户信息 public function getUserInfo() { return $this->userName; } } //获取唯一的实例 $userInfo = userInfo::getInstance(); //显示用户名 echo '用户名是'.$userInfo->getUserInfo().'<br>'; //天气播报 echo '向用户'.$userInfo->getUserInfo().'播报天气<br>'; ?> |
其实单件模式还是比较好理解的一个模式,比如上面这个例子,用在数据库链接上,就可以保证数据库的唯一连接了。
而单件模式也可以用于减少数据库的查询,感觉这个作用也是大大地~~~~,如下:
<?php class userInfo { private static $userName; //查询数据库,获得用户名 private static function findUserInfo() { //查询数据库,获得用户名 self::$userName = 'lightsaber'; } public static function getUserInfo() { //判断是否已经获取了用户数据 if (self::$userName=='') self::findUserInfo(); return self::$userName; } } //显示用户名 echo '用户名是'.userInfo::getUserInfo().'<br>'; //天气播报 echo '向用户'.userInfo::getUserInfo().'播报天气<br>'; ?> |
三、备忘模式
今天学的是备忘模式,简单理解比喻下就是类似平时我们用的word”撤销”,”恢复”…
1.UNDO
<?php //备忘类 class Memento { public function backup() { //保存现有的分页样式 echo '样式已经保存<br>'; } public function restore() { //用保存的样式去覆盖 echo '样式已经恢复<br>'; } } ---------------------------------------------------- //设置分页样式 class ListStyle { //备忘对象 private $memento; //构造方法 public function __construct() { $this->memento = new Memento(); } //设置样式 public function setStyle() { //开始先备份样式 $this->memento->backup(); //设置样式 echo '设置了样式<br>'; } //撤销方法 public function undo() { $this->memento->restore(); } } ---------------------------------------------------- $listStyle = new ListStyle(); //设置样式,同时备份 $listStyle->setStyle(); //撤销设置 $listStyle->undo(); ?> |
2.REDO
<?php //备忘类 class Memento { public function backup() { //保存现有的分页样式 echo '样式已经保存<br>'; } public function restore() { //用保存的样式去覆盖 echo '样式已经恢复<br>'; } } //设置分页样式 class ListStyle { //备忘对象 private $memento; //构造方法 public function __construct() { $this->memento = new Memento(); } //设置样式 public function setStyle() { //开始先备份样式 $this->memento->backup(); //设置样式 echo '设置了样式<br>'; } //撤销方法 public function undo() { //先保存,为了redo $this->memento->backup(); $this->memento->restore(); } //重做方法 public function redo() { $this->memento->restore(); } } $listStyle = new ListStyle(); //设置样式,同时备份 $listStyle->setStyle(); //撤销设置 $listStyle->undo(); //重做设置 $listStyle->redo(); ?> |
简单总结下,就是有相应的一个类,来做backup和restore用的…
四、策略模式
策略模式(Strategy),将不同情况的算法分拆到不同的类(比如advanceDiscountor类),然后调用者(discountor类)根据具体的情况,用算法类的对象来处理。
<? php //打折接口 interface IDiscountor { public function getDiscount(); } ------------------------------------------------------------------------------------ //普通用户打折类 class commonDiscountor implements IDiscountor { public function getDiscount() { $discount = 1; return $discount; } } //高级用户打折类 class advanceDiscountor implements IDiscountor { public function getDiscount() { $discount = 0.9; return $discount; } } //vip用户打折类 class vipDiscountor implements IDiscountor { public function getDiscount() { $discount = 0.8; return $discount; } } ---------------------------------------------------------------------------------- //打折类 class discountor { public function getDiscount($rank) { switch ($rank) { case 'common': $discountor = new commonDiscountor(); break; case 'advance': $discountor = new advanceDiscountor(); break; case 'vip': $discountor = new vipDiscountor(); break; } return $discountor->getDiscount(); } } $discountor = new discountor(); echo $discountor->getDiscount('advance'); ?> |
五、状态模式
<?php //积分基础类 class Point { //积分 public $point; public function showPoint() { //列出用户的积分 } public function showUseRecord() { //列出用户的积分使用记录 } } -------------------------------------------------------------------------- //积分低于500的类 class Point500 extends Point { //显示提示 public function showTips() { echo "客户发帖等行为可以增加积分"; } //显示按钮 public function showButton() { echo ""; } } //积分大于500,低于1000的类 class Point600 extends Point { //显示提示 public function showTips() { echo "可以行使标准用户的权利"; } //显示按钮 public function showButton() { echo "标准用户功能的按钮"; } } //积分大于1000的类 class Point1000 extends Point { //显示提示 public function showTips() { echo "可以行使高级用户的权利"; } //显示按钮 public function showButton() { echo "高级用户的按钮"; } } -------------------------------------------------------------------------- //应用环境类,简单的理解为调用环境就可以了 class Context { //积分对象 public $pointObj; //设置一个积分对象 public function setPointObj($point) { //低于500 if ($point<500) { $this->pointObj = new Point500(); } //大于1000 elseif ($point>1000) { $this->pointObj = new Point1000(); } //大于500,低于1000 else { $this->pointObj = new Point600(); } } public function showPoint() { $this->pointObj->showPoint(); } public function showUseRecord() { $this->pointObj->showUseRecord(); } //显示提示 public function showTips() { $this->pointObj->showTips(); } //显示按钮 public function showButton() { $this->pointObj->showButton(); } } -------------------------------------------------------------------------- $context = new Context(); $context->setPointObj(780); //显示提示 $context->showTips(); ?> |
优点:更好的阅读,扩展,已经封装