在日常开放中,经常会用到一些设计模式,进行我们代码的优化处理,一个很好的设计思想
1) 工厂模式
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
/** * 定义数据库接口 */ interface DB { // 连接数据库 public function conn(); } /** * 工厂接口 */ interface Factory{ // 创建数据库接口 function createDB(); } /** * 实现DB接口的mysql类 */ class mysqlDB implements DB{ public function conn(){ echo '连接到mysql数据库'; } } /** * 实现DB接口的sqlite类 */ class sqLiteDB implements DB{ public function conn(){ echo '连接到了sqlite数据库'; } } /** * 创建对应的数据库对象工厂类 */ class mysqlFactory implements Factory{ public function createDB(){ return new mysqlDB(); } } /** * 创建对应的数据库对象工厂类 */ class sqliteFactory implements Factory{ public function createDB(){ return new sqLiteDB(); } } //////////////////// // 假设新增MongoDB数据库 // //////////////////// // 1:要新增mongoDB() /** * 实现DB接口的mongo类 */ class mongoDB implements DB{ public function conn(){ echo '连接到了mongodb数据库'; } } // 2:新增对应的工厂方法 class mongoFactory implements Factory{ public function createDB(){ return new mongoDB(); } } // 测试 $mysqlfactory=new mysqlFactory(); $mysqldb=$mysqlfactory->createDB(); $mysqldb->conn(); $sqlitefactory=new sqliteFactory(); $sqlitedb=$sqlitefactory->createDB(); $sqlitedb->conn(); $mongofactory=new mongoFactory(); $mongodb=$mongofactory->createDB(); $mongodb->conn();
这样就不违反了开闭规则了,不修改已有的代码,直接添加新的代码,提高了程序的扩展性。
2)单例模式
可以保证系统中一个类只有一个实例。即一个类只有一个对象实例
class sigle{ // 保存唯一对象 private static $selfObj=null; // 目的:封锁外部new操作 private function __construct(){} // 封锁外部clone private function __clone(){} public static function getObj(){ if(self::$selfObj===null){ self::$selfObj=new self(); } return self::$selfObj; } } $q=sigle::getObj(); $w=sigle::getObj(); var_dump($q==$w);
3)观察者模式
// php5中提供SplObserver与被观察者SplSubject的接口 /////////////////////////////// // 定义被观察者,实现SplSubject被观察者对象 // /////////////////////////////// class User implements SplSubject{ // 登陆次数 public $loginNum; // 用户爱好 public $hobby; // 用户名字 public $name; public function __construct($name,$hobby=''){ $this->loginNum=rand(1,10); $this->hobby=$hobby; $this->name=$name; // 用来保存观察者的对象 $this->observers=new SplObjectStorage(); } // 用户登录入口 public function login(){ echo '登录成功后通知:'; $this->notify(); } // 添加观察者 public function attach(SplObserver $observer){ $this->observers->attach($observer); } // 删除观察者 public function detach(SplObserver $observer){ $this->observers->detach($observer); } /** * 循环遍历观察者发送通知 */ public function notify(){ // 指针指向头部 $this->observers->rewind(); while ($this->observers->valid()) { // 当前观察者 $observer=$this->observers->current(); // var_dump($observer); // 传递当前用户 $observer->update($this); $this->observers->next(); } } } /////////////// // 定义安全验证观察者 // /////////////// class Secrity implements SplObserver{ /** * 本观察者通知的具体方法 * @param SplSubject $subject [被观察者user] */ public function update(SplSubject $subject){ if($subject->loginNum<=3){ echo $subject->name.',这是第'.$subject->loginNum.'登录.'; }else{ echo $subject->name.',这是第'.$subject->loginNum.'登录,登录次数过多.'; } } } /////////////// // 定义广告推荐观察者 // /////////////// class Commend implements SplObserver{ public function update(SplSubject $subject){ if($subject->hobby=='car'){ echo '给你推荐汽车广告'.PHP_EOL; }else if($subject->hobby=='php'){ echo '推荐php培训广告'.PHP_EOL; }else{ echo '好好学习,天天向上'.PHP_EOL; } } } // 测试 $ming=new User('小明','php'); // 添加观察者 $secrity=new Secrity(); $ming->attach($secrity); $commend=new Commend(); $ming->attach($commend); $ming->login(); echo '------------------------------------------------------'.PHP_EOL; $hong=new User('小红'); // 添加观察者 $secrity=new Secrity(); $hong->attach($secrity); $commend=new Commend(); $hong->attach($commend); // 删除广告推荐 $hong->detach($commend); $hong->login();
4)责任链模式
// 领班 class Foreman{ // 自己的等级 private $level=1; // 上级 protected $superior='Director'; public function process($level){ if($this->level>=$level){ // 自己能处理问题的级别大于等于当前事情级别,就自己处理 echo '领班处理'.PHP_EOL; }else{ (new $this->superior)->process($level); } } } // 主管 class Director{ // 自己的等级 private $level=2; // 上级 protected $superior='Manager'; public function process($level){ if($this->level>=$level){ echo '主管处理'.PHP_EOL; }else{ (new $this->superior)->process($level); } } } // 经理 class Manager{ // 自己的等级 private $level=3; // 上级 protected $superior='TopManager'; public function process($level){ if($this->level>=$level){ echo '经理处理'.PHP_EOL; }else{ (new $this->superior)->process($level); } } } // 总经理 class TopManager{ // 自己的等级 private $level=4; // 上级 protected $superior='President'; public function process($level){ if($this->level>=$level){ echo '总经理处理'.PHP_EOL; }else{ (new $this->superior)->process($level); } } } // 董事长 class President{ // 自己的等级 private $level=5; public function process($level){ echo '董事长处理'.PHP_EOL; } } // 责任链模式处理问题 $level=rand(1,5); print('问题级别:'.$level); $foreman=new Foreman(); $foreman->process($level);
5)策略模式
// 计算的接口 interface Calc{ public function process($num1,$num2); } // 加法计算 class AddCalc implements Calc{ public function process($num1,$num2){ return $num1+$num2; } } // 减法计算 class SubtractCalc implements Calc{ public function process($num1,$num2){ return $num1-$num2; } } // 乘法计算 class MultiplyCalc implements Calc{ public function process($num1,$num2){ return $num1*$num2; } } // 除法计算 class DivideCalc implements Calc{ public function process($num1,$num2){ return $num1/$num2; } } // 计算器类 class Calculator{ // 保存计算类 private $calc=null; /** * @param [string] $operator [计算器运算方法] */ public function __construct($operator){ $operCalc=$operator.'Calc'; $this->calc=new $operCalc(); } // 计算 public function calc($num1,$num2){ return $this->calc->process($num1,$num2); } } $operators=array('Add','Subtract','Divide','Multiply'); $oper=$operators[rand(0,3)]; $calculator=new Calculator($oper); $res=$calculator->calc(100,2); echo '100 '.$oper.' 2 res:'.$res;
6)装饰器模式
// 装饰器模式做文章修饰功能 // 基本的文章类 class BaseArticle{ // 文章内容 protected $text; // 文章对象 protected $artObj=null; public function __construct($text){ $this->text=$text; } public function decorator(){ return $this->text; } } // 添加文章摘要,继承基础文章 class SummaryArticle extends BaseArticle{ // 传递一个文章对象 public function __construct(BaseArticle $artObj){ $this->artObj=$artObj; $this->decorator(); } public function decorator(){ return $this->text='【加了摘要】'.$this->artObj->text; } } // 添加文章写作时间,继承基础文章 class TimeArticle extends BaseArticle{ public function __construct(BaseArticle $artObj){ $this->artObj=$artObj; $this->decorator(); } public function decorator(){ return $this->text=$this->artObj->text.'【时间:'.date('Y-m-d H:i:s').'】'; } } $ba=new BaseArticle('文章主体-文章主体-文章主体-文章主体。'); $sa=new SummaryArticle($ba); $ta=new TimeArticle($sa); echo $ba->decorator().PHP_EOL; echo $sa->decorator().PHP_EOL; echo $ta->decorator().PHP_EOL;
7)适配器模式
// 假设天气接口 class Weather{ public static function show(){ $today=array( "city"=>"北京", "cityid"=>"101010100", "temp1"=>"24℃", "temp2"=>"11℃", "weather"=>"雷阵雨转多云" ); // 将数据序列化,只能是php才能反序列化操作 /*a:5:{s:4:"city";s:6:"北京";s:6:"cityid";s:9:"101010100";s:5:"temp1";s:5:"24℃";s:5:"temp2";s:5:"11℃";s:7:"weather";s:18:"雷阵雨转多云";}城市:北京*/ return serialize($today); } } /** * 适配器将php序列化后的数据反序列化后转化成json格式,这样其他语言就能处理了 */ class AdapterWeather extends Weather{ public static function show(){ return json_encode(unserialize(parent::show())); } } // php客户端调用 print(Weather::show()); $weather=unserialize(Weather::show()); echo '城市:'.$weather['city'].PHP_EOL; echo '城市ID:'.$weather['city'].PHP_EOL; echo '最高温:'.$weather['temp1'].PHP_EOL; echo '最低温:'.$weather['temp2'].PHP_EOL; echo '天气:'.$weather['weather'].PHP_EOL; echo '--------------以下假设是python通过适配器获取天气数据----------'.PHP_EOL; // 假设python处理天气,通过适配器获取天气数据 $weather=json_decode(AdapterWeather::show(),true); echo '城市:'.$weather['city'].PHP_EOL; echo '城市ID:'.$weather['city'].PHP_EOL; echo '最高温:'.$weather['temp1'].PHP_EOL; echo '最低温:'.$weather['temp2'].PHP_EOL; echo '天气:'.$weather['weather'].PHP_EOL;
8)桥接模式
// 抽象消息接口 abstract class Message{ // 发送器 protected $sender; public function __construct($sender){ $this->sender=$sender; } // 发送消息 public function send($to,$msg){ $msg=$this->msg($msg); // 通过发送器发送消息 $this->sender->send($to,$msg); } } // 普通消息类型 class NormalMessage extends Message{ public function msg($msg){ return '【普通】'.$msg; } } // 警告消息类型 class WarningMessage extends Message{ public function msg($msg){ return '【警告】'.$msg; } } // 危险消息类型 class DangerMessage extends Message{ public function msg($msg){ return '【危险】'.$msg; } } // 发送站内消息发送器 class SiteMessageSender{ public function send($to,$msg){ echo '给"'.$to.'"发送站内消息: '.$msg.PHP_EOL; } } // 发送email消息发送器 class EmailMessageSender{ public function send($to,$msg){ echo '给"'.$to.'"发送Email消息: '.$msg.PHP_EOL; } } // 发送短信消息发送器 class SMSMessageSender{ public function send($to,$msg){ echo '给"'.$to.'"发送短信消息: '.$msg.PHP_EOL; } } // 总共有9种组合方式,但是仅仅需要6个类 $normal_msg=new NormalMessage(new SiteMessageSender()); $normal_msg->send('小红','normal信息信息信息'); $normal_msg=new NormalMessage(new EmailMessageSender()); $normal_msg->send('小红','normal信息信息信息'); $normal_msg=new NormalMessage(new SMSMessageSender()); $normal_msg->send('小红','normal信息信息信息'); $warning_msg=new WarningMessage(new SiteMessageSender()); $warning_msg->send('小绿','warning信息信息信息'); $warning_msg=new WarningMessage(new EmailMessageSender()); $warning_msg->send('小绿','warning信息信息信息'); $warning_msg=new WarningMessage(new SMSMessageSender()); $warning_msg->send('小绿','warning信息信息信息'); $danger_msg=new DangerMessage(new SiteMessageSender()); $danger_msg->send('小花','danger信息信息信息'); $danger_msg=new DangerMessage(new EmailMessageSender()); $danger_msg->send('小花','danger信息信息信息'); $danger_msg=new DangerMessage(new SMSMessageSender()); $danger_msg->send('小花','danger信息信息信息');