PHP培训
美国上市PHP培训机构

400-111-8989

热门课程

PHP设计模式-工厂/单例/观察者模式

  • 发布:PHP培训
  • 来源:网络
  • 时间:2018-07-17 17:12

学习设计模式的意义

1:更深入的理解面向对象的思想.

2:有利于开发出扩展性强的程序

首先看看工厂模式是什么鬼

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

简单工厂:

<?php/** * @authors BaAGee (asm19950109@hotmail.com) * @date 2017-09-22 08:37:00 *//** * 定义数据库接口 */interface DB { public function conn();}/** * 
实现DB接口的mysql类 */class mysqlDB implements DB{ public function conn(){ echo '连接到mysql数据库'; }}/** * 
实现DB接口的sqlite类 */class sqLiteDB implements DB{ public function conn(){ echo '连接到了sqlite数据库'; }}/** * 
简单工厂模式 */class DBFactory{ static $dbObj=null; public static function createDB($type){ switch ($type) { case 'mysql': self::$dbObj = new mysqlDB();
 break; case 'sqlite': self::$dbObj = new sqLiteDB(); break; default: exit('unknow $type'); } return self::$dbObj; }}// 测试$mysqlClient=DBFactory::createDB('mysql');
$mysqlClient->conn();$sqliteClient=DBFactory::createDB('sqlite');$sqliteClient->conn();

以上简单工厂模式代码,要是新增mongodb数据库,就要修改DBFactory类了,违反开闭原则:

1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。通俗的说: 添加新类/接口等进来行,修改不行.

我们就将上例中DBFactory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现,下面就是将上例中的DBFactory拓展成抽象工厂:

抽象工厂:

<?php/** * @authors BaAGee (asm19950109@hotmail.com) * @date 2017-09-22 08:37:00 *//** * 定义数据库接口 */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();

这样就不违反了开闭规则了,不修改已有的代码,直接添加新的代码,提高了程序的扩展性。

单例模式:

可以保证系统中一个类只有一个实例。即一个类只有一个对象实例

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);

观察者模式:

观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。下面的图详细的描述了这样一种过程:

PHP设计模式-工厂/单例/观察者模式

观察者

(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。

被观察

被观察对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。

撤销观察

观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。

以下实例展示了安全验证和广告推送这两个观察者观察用户登录,登录后用户通知各个观察者执行自己的代码。

<?php/** * @authors BaAGee (asm19950109@hotmail.com) * @date 2017-09-22 10:30:39 */// 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();

运行结果:

PHP设计模式-工厂/单例/观察者模式

原文:微信公众号  php在线

预约申请免费试听课

上一篇:新手如何学习php
下一篇:8 个 PHP 的软件质量控制工具

最新的web前端开发框架整合

如何搭建个人博客网站

PHP程序员土?只要4招,帮你改头换面大变身!

你不能不了解的PHP日期常用技巧!

选择城市和中心
贵州省

广西省

海南省