PHP之常用设计模式
在日常开放中,经常会用到一些设计模式,进行我们代码的优化处理,一个很好的设计思想
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之常用设计模式相关推荐
- 7 种 Javascript 常用设计模式学习笔记
7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...
- 打死都要记住!微服务架构的常用设计模式!
作者:duanxz 来源:cnblogs.com/duanxz/p/3514895.html 大家好,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许我休息一下哈).今天跟大家分享微服务架 ...
- 原型模式的应用场景_前端常用设计模式
求关注 前端常见的设计模式主要有以下几种:1. 单例模式2. 工厂模式3. 策略模式4. 代理模式5. 观察者模式6. 模块模式7. 构造函数模式8. 混合模式 单例模式 这种设计模式的思想是确保一个 ...
- Java常用设计模式————原型模式(一)
介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 原型模式用于创建重复的对象,同时又能保证性能.当直接创建对象的代价比较大时,则采用 ...
- 模板设计模式_C常用设计模式——模板方法模式
C常用设计模式系列,我们是以策略模式开头的,因为它太简单太实用了,本篇讲的模板方法模式(Template Method),同样简单又实用.模板方法模式堪称局部代码分离关注点的神器. 代码里有个流程A, ...
- 23种常用设计模式的UML类图
23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...
- Spring常用设计模式--简单工厂模式
本专栏内容参考自:咕泡学院Tom老师的<Spring5核心原理与30个类手写实战>,仅作个人学习记录使用,如有侵权,联系速删. 工厂模式的由来: 在现实生活中我们都知道,原始社会自给自 ...
- 初学Java常用设计模式之——原型模式
声明:转载请附上原文链接 提示:标题序号从3开始,是照应不同设计模式笔记发布的顺序而定的,比如,第上一篇文章 初学Java常用设计模式之--工厂模式 序号从2开始. 标题后面之所以加上了解,是因为相对 ...
- java常用设计模式文章收集
java常用设计模式文章收集 java设计模式--接口模式 java设计模式--抽象工厂模式 java设计模式--工厂模式 Java设计模式--迭代器模式 Java设计模式--原型模式 JAVA设计模 ...
- 九大常用设计模式学习-装饰者模式
设计模式学习记录:一句话+代码体会设计模式. 九大常用设计模式 单例模式:https://blog.csdn.net/qq_37902949/article/details/87903569 简单工厂 ...
最新文章
- SQLSERVER系统数据库工作原理
- ubuntu 安装OpenBLAS
- python专科找工作难吗-本人小白,想学python,大专不知道好不好找工作?
- HDU4084 插头dp
- nfs服务器与客户端配置
- CBitMap的用法 from http://www.cnblogs.com/toconnection/archive/2012/08/04/mfc.html
- 深度学习和目标检测系列教程 11-300:小麦数据集训练Faster-RCNN模型
- 从运维的角度理解Iaas、Paas、Saas云计算
- java判断或_Java 条件判断
- $nextTick 源码
- java++记录+运行_记录java+testng运行selenium(三)---xml、ini、excel、日志等配置
- apex英雄机器人探路者怎么玩_Apex英雄探路者机器人实战技巧攻略[多图]
- JavaScript判断访问终端
- android可以root的版本,Android8.0以上系统ROOT时,Magisk框架替代SpuerSU
- 《三联生活周刊》2017年第26期:3星。终南山隐士现状。
- Docker的基本管理命令!!!学会docker的第一步
- Mac 用久了空间不足?教你如何清理磁盘空间
- ZCU104开发板:开发板介绍1
- 容器与Servlet生命周期
- 马少平、周枫、王小川、楼天城、唐文斌:清华计算机系与人工智能的40年
热门文章
- Devexpress中Tdxnavbar的使用
- 实验二:SET-UID程序漏洞实验
- 旅游解说系统 VS 旅游信息系统
- CISCO无线AP配置手册
- 苹果6系统怎么更新不了_苹果App Store登录不了怎么办_登录不了App Store的解决办法?...
- 0x80070035找不到网络路径_ln -s 创建软链接时的路径问题
- linux没有那个文件或目录_Linux安装python faiss模块
- PostgreSQL13逻辑备份pg_dump
- Python机器学习:多项式回归与模型泛化005学习曲线
- Python机器学习:线型回归法008实现多元线性回归