在日常开放中,经常会用到一些设计模式,进行我们代码的优化处理,一个很好的设计思想

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(){}// 封锁外部cloneprivate 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信息信息信息');

转载于:https://www.cnblogs.com/xingxia/p/php_modes.html

PHP之常用设计模式相关推荐

  1. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  2. 打死都要记住!微服务架构的常用设计模式!

    作者:duanxz 来源:cnblogs.com/duanxz/p/3514895.html 大家好,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许我休息一下哈).今天跟大家分享微服务架 ...

  3. 原型模式的应用场景_前端常用设计模式

    求关注 前端常见的设计模式主要有以下几种:1. 单例模式2. 工厂模式3. 策略模式4. 代理模式5. 观察者模式6. 模块模式7. 构造函数模式8. 混合模式 单例模式 这种设计模式的思想是确保一个 ...

  4. Java常用设计模式————原型模式(一)

    介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式用于创建重复的对象,同时又能保证性能.当直接创建对象的代价比较大时,则采用 ...

  5. 模板设计模式_C常用设计模式——模板方法模式

    C常用设计模式系列,我们是以策略模式开头的,因为它太简单太实用了,本篇讲的模板方法模式(Template Method),同样简单又实用.模板方法模式堪称局部代码分离关注点的神器. 代码里有个流程A, ...

  6. 23种常用设计模式的UML类图

    23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...

  7. Spring常用设计模式--简单工厂模式

    本专栏内容参考自:咕泡学院Tom老师的<Spring5核心原理与30个类手写实战>,仅作个人学习记录使用,如有侵权,联系速删. 工厂模式的由来:   在现实生活中我们都知道,原始社会自给自 ...

  8. 初学Java常用设计模式之——原型模式

    声明:转载请附上原文链接 提示:标题序号从3开始,是照应不同设计模式笔记发布的顺序而定的,比如,第上一篇文章 初学Java常用设计模式之--工厂模式 序号从2开始. 标题后面之所以加上了解,是因为相对 ...

  9. java常用设计模式文章收集

    java常用设计模式文章收集 java设计模式--接口模式 java设计模式--抽象工厂模式 java设计模式--工厂模式 Java设计模式--迭代器模式 Java设计模式--原型模式 JAVA设计模 ...

  10. 九大常用设计模式学习-装饰者模式

    设计模式学习记录:一句话+代码体会设计模式. 九大常用设计模式 单例模式:https://blog.csdn.net/qq_37902949/article/details/87903569 简单工厂 ...

最新文章

  1. SQLSERVER系统数据库工作原理
  2. ubuntu 安装OpenBLAS
  3. python专科找工作难吗-本人小白,想学python,大专不知道好不好找工作?
  4. HDU4084 插头dp
  5. nfs服务器与客户端配置
  6. CBitMap的用法 from http://www.cnblogs.com/toconnection/archive/2012/08/04/mfc.html
  7. 深度学习和目标检测系列教程 11-300:小麦数据集训练Faster-RCNN模型
  8. 从运维的角度理解Iaas、Paas、Saas云计算
  9. java判断或_Java 条件判断
  10. $nextTick 源码
  11. java++记录+运行_记录java+testng运行selenium(三)---xml、ini、excel、日志等配置
  12. apex英雄机器人探路者怎么玩_Apex英雄探路者机器人实战技巧攻略[多图]
  13. JavaScript判断访问终端
  14. android可以root的版本,Android8.0以上系统ROOT时,Magisk框架替代SpuerSU
  15. 《三联生活周刊》2017年第26期:3星。终南山隐士现状。
  16. Docker的基本管理命令!!!学会docker的第一步
  17. Mac 用久了空间不足?教你如何清理磁盘空间
  18. ZCU104开发板:开发板介绍1
  19. 容器与Servlet生命周期
  20. 马少平、周枫、王小川、楼天城、唐文斌:清华计算机系与人工智能的40年

热门文章

  1. Devexpress中Tdxnavbar的使用
  2. 实验二:SET-UID程序漏洞实验
  3. 旅游解说系统 VS 旅游信息系统
  4. CISCO无线AP配置手册
  5. 苹果6系统怎么更新不了_苹果App Store登录不了怎么办_登录不了App Store的解决办法?...
  6. 0x80070035找不到网络路径_ln -s 创建软链接时的路径问题
  7. linux没有那个文件或目录_Linux安装python faiss模块
  8. PostgreSQL13逻辑备份pg_dump
  9. Python机器学习:多项式回归与模型泛化005学习曲线
  10. Python机器学习:线型回归法008实现多元线性回归