在日常开放中,经常会用到一些设计模式,进行我们代码的优化处理,一个很好的设计思想
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();