1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > PHP常用设计模式单例 工厂 观察者 责任链 装饰 策略 适配 桥接模式

PHP常用设计模式单例 工厂 观察者 责任链 装饰 策略 适配 桥接模式

时间:2021-04-01 12:09:29

相关推荐

PHP常用设计模式单例  工厂  观察者  责任链  装饰  策略 适配 桥接模式

后端开发|php教程

function,gt,public,content,lt

后端开发-php教程

asp考勤管理系统源码,vscode缩放快捷键,ubuntu 护眼模式,tomcat 统计线程数,python 爬虫太慢,php sql注入修复,seo推广平台怎么选,手机网站充值模板,wap网站模板源码lzw

// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法abstract class Tiger { public abstract function climb();}class XTiger extends Tiger { public function climb() { echo 摔下来; }}class MTiger extends Tiger { public function climb() { echo 爬到树顶; }}class Client { public static function call(Tiger $animal) { $animal->climb(); }}Client::call(new XTiger());Client::call(new MTiger());

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头// 共同接口interface db { function conn();}// 服务端开发(不知道将会被谁调用)class dbmysql implements db{ public function conn() { echo 连上了MySQL; }}class dbsqlite implements db{ public function conn() { echo 连上了sqlite; }}// 客户端, 看不到dbmysql, dbsqlite的内部细节的, 只知道上两个类实现了db接口.$db = new dbmysql();$db->conn();// 因为知道这个类实现了db接口, 所以知道有这个conn类$sqlite = new dbsqlite();$sqlite->conn();// 我连我有哪些类我都不希望告诉客户端, 那么怎么进一步进行封装// 发生连接的双方知道的越少越好, 你还知道我有两个类

// 简单工厂// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头// 共同接口interface db { function conn();}// 服务端开发(不知道将会被谁调用)class dbmysql implements db{ public function conn() { echo 连上了MySQL; }}class dbsqlite implements db{ public function conn() { echo 连上了sqlite; }}// 简单工厂class Factory { public static function createDB($type) { if($type == mysql) { return new dbmysql(); } elseif ($type==sqlite) { return new dbsqlite(); } else { throw new Exception("Error db type", 1); } }}// 客户端现在不知道对方到底有哪些类名了// 只知道对方开放了一个Factory::createDB方法// 方法允许传递数据库名称$mysql = Factory::createDB(mysql);$mysql->conn();$sqlite = Factory::createDB(sqlite);$sqlite->conn();// 原本你知道服务器端的两个类名, 觉得你知道的太多, 再封装起来, 只给一个通道, 更好的适应变化// 如果以后新增oracle类型, 怎么办?// 我们PHP随手改了就行, 像JAVA打包一次很麻烦, 又要修改服务端内容// 服务端要修改Factory的内容(在java, c++中, 改后还得再编译)// 这个时候就想如何来改进呢// 在OOD(面向对象设计)的法则中, 有重要的开闭原则--对于修改是封闭的, 对于扩展是开放的.// 你可以新增一个源代码, 不要修改旧的代码//现在用第二种办法, 叫工厂方法

// 共同接口interface db { function conn();}interface Factory { function createDB();}// 服务端开发(不知道将会被谁调用)class dbmysql implements db{ public function conn() { echo 连上了MySQL; }}class dbsqlite implements db{ public function conn() { echo 连上了sqlite; }}class mysqliFactory implements Factory{ public function createDB() { return new dbmysql(); }}class sqliteFactory implements Factory { public function createDB() { return new dbsqlite(); }}// 服务器端添加oracle类// 前面的代码不用改// 我就新增一个数据库驱动类和一个工厂, 这样就避免了对源代码的修改class dboracle implements db { public function conn() { echo 连接上了oracle; }}class oracleFactory implements Factory { public function createDB() { return new dboracle(); }}// 客户端开始, 对方给了两个api, 一个db的api, 一个是创造数据库的api$fact = new mysqliFactory();$db = $fact->createDB();$db->conn();$fact = new sqliteFactory();$db = $fact->createDB();$db->conn();

// 单例// 一般来说一个中小型网站一个db去连接数据库就行了// 想想, 能不能只有一个db类, 一个upload类, 一个cookie类// 类肯定只有一个, 如何保证类的实例也只有一个// 2个对象是同一个的时候才全等// 单例模式class single { protected static $ins = null; // 控制权限, 封锁new操作, 把大门关上了, 需要留一个小窗户 // 方法前加final, 则方法不能被覆盖, 类前加final, 则类不能被继承 final protected function __construct() {} // 防clone final protected function __clone(){} //留一个接口来new对象 public static function getIns() { if(self::$ins == null) { self::$ins = new self(); } return self::$ins; }}$s1 = single::getIns();$s2 = single::getIns();if ($s1 === $s2) { echo 是一个对象;} else { echo 不是一个对象;}

colour_bluediv{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { }function t() { var sel = document.getElementsByTagName(select)[0];// alert(sel.value); if(sel.value == male) {document.getElementById(content).style.backgroundColor = gray;document.getElementById(ad).innerHTML = 汽车; } else if(sel.value==female) {document.getElementById(content).style.backgroundColor = pink;document.getElementById(ad).innerHTML = 减肥; } } /** * * 观察上述代码, 如果新增了一个study区, 在切换时, 学习内容也要随之切换, 那么, 就需要改动T函数! 对于修改又开放了. * 思考---如果需要新监听footer区, 如何能不改原来的代码, 而只增加 */

面向过程, 不用任务来切换

// 比如登录, 在登录的时候出于安全考虑要记录上次登录时间// 出于商业考虑, 给你推荐商品class user implements SplSubject { public $lognum; public $hobby; protected $observers = null; public function __construct($hobby) { $this->lognum = rand(1, 10); $this->hobby = $hobby; $this->observers = new SplObjectStorage(); } public function login() { // 操作session $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(); $observer->update($this); $this->observers->next(); } }}class secrity implements SplObserver { public function update(SplSubject $subject) { if($subject->lognum lognum.次安全登录; } else { echo 这是第.$subject->lognum.次登录,异常; } }}class ad implements SplObserver { public function update(SplSubject $subject) { if($subject->hobby == sports) { echo 台湾英锦赛; } else { echo 好好学习天天向上; } }}// 实施观察$user = new user(sports);$user->attach(new secrity());$user->attach(new ad());$user->login();

colour_bluediv{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { }

观察者模式

男式风格 女式风格

我是内容

我是广告

学习

// 服务器端 var sel = document.getElementsByTagName(select)[0]; sel.observers = {}; sel.attach = function(key, obj) { sel.observers[key] = obj; } sel.detach = function(key) { delete this.observers[key]; } sel.onchange = sel.notify = function(){ for(var key in this.observers) { this.observers[key].update(this); } } // 客户端 var content = document.getElementById(content); content.update = function(observer) { if(observer.value == male){ this.style.backgroundColor = gray; } else if(observer.value==female){ this.style.backgroundColor = pink; } } sel.attach(content, content); var ad = document.getElementById(ad); ad.update = function(observer) { if(observer.value == male){ this.innerHTML = 汽车; } else if(observer.value==female){ this.innerHTML = 减肥; } } sel.attach(ad, ad); // 客户端和服务端实现了解耦 // 后面有一个学习区, 如果状态改变了, 学习区也要变化 var study = document.getElementById(study); study.update = function(observer) { if(observer.value == male){ this.innerHTML = 学习计算机; } else if(observer.value==female){ this.innerHTML = 学习美容; } } sel.attach(study, study); //如果想不观察尾部了 function t1() { sel.atach(study, study); } function t2() { sel.detach(study); }

.htmlcolour_bluediv{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } 责任链模式举报过程 粗口 黄赌毒 分裂国家.php<?phpheader(Content-type: text/html; charset=utf-8);//版主class board { protected $power = 1; protected $top = admin; public function process($lev) { if($lev power) { echo 版主删贴; } else { $top = new $this->top; $top->process($lev); } }}class admin { protected $power = 2; protected $top = police; public function process($lev) { if($lev power) { echo 管理员封账号; } else { $top = new $this->top; $top->process($lev); } }}class police { protected $power; protected $top = null; public function process($lev) { echo 抓起来; }}$lev = $_POST[jubao]+0;$judge = new board();$judge->process($lev);

.htmlcolour_bluediv{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } 面向过程完成举报过程 粗口 黄赌毒 分裂国家.phpprocess();} elseif($lev==2) { $judge = new admin(); $judge->process();} elseif($lev==3) { $judge = new police(); $judge->process();}// 处理的不够优雅, 现在还是面向过程的写法, 面向过程和面向对象混合了// 如果以后在两个等级中间要添加一个等级应该怎么办

.htmlcolour_bluediv{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } 策略模式 和工厂方法的区别只是在逻辑上的区别, 也叫聚合+ - * /.phpcalc = new $calc(); } public function calc($op1, $op2) { return $this->calc->calc($op1, $op2); }}$type = $_POST[op];$cmath = new CMath($type);echo $cmath->calc($_POST[op1], $_POST[op2]);

// 装饰器模式 decoratorclass article { protected $content; public function __construct($content) { $this->content = $content; } public function decorator() { return $this->content; }}$art = new article("好好学习");echo $art->decorator();// 文章需要小编加摘要class BianArticle extends article { public function summary() { return $this->content.小编加了摘要; }}$art = new BianArticle(好好学习);echo $art->summary();// 又请了SEO人员, 要对文章进行description处理...class SEOArticle extends BianArticle { public function seo() { //... }}// 又有了广告部class ADArticle extends SEOArticle { // 层次越来越深, 目的却只是给文章加各种内容}

// 装饰器模式做文章修饰功能class BaseArt { protected $content; protected $art; public function __construct($content) { $this->content = $content; } public function decorator() { return $this->content; }}//编辑文章摘要class BianArt extends BaseArt { public function __construct(BaseArt $art) { $this->art = $art; } public function decorator() { return $this->content = $this->art->decorator() . 小编摘要; }}// SEOclass SEOArt Extends BaseArt { public function __construct(BaseArt $art) { $this->art = $art; } public function decorator() { return $this->content = $this->art->decorator() . SEO关键词; }}$b = new SEOArt(new BianArt(new BaseArt(天天向上)));echo $b->decorator();$b = new BianArt(new SEOArt(new BaseArt(天天向上)));echo $b->decorator();// 装饰的先后顺序可以随便换, 新增多少个装饰者都很方便// 基类负责创建对象// 子类负责装饰

// 适配器模式// 服务器端代码class weather { public static function show() { $today = [ ep => 28, wind => 7, sun => sunny, ]; return serialize($today); }}// 客户端调用$weather = unserialize(weather::show());echo 温度: ,$weather[ ep],

;echo 风力: ,$weather[wind],

;echo sun: ,$weather[sun],

;// 来了一批手机上的java客户端 , 不认识PHP的串化行后的字符串, 怎么办?// 把服务器端代码改了? 旧的客户端会受影响// 旧的类和函数都不让修改, 如何来进行扩展// 增加一个适配器class AdapterWeather extends weather { public static function show() { //拿到旧数据 $today = parent::show(); // 然后开始转换 $today = unserialize($today); $today = json_encode($today); return $today; }}// ==== java, python再来调用就不怕了, 通过适配器调用$weather = AdapterWeather::show();$w = json_decode($weather);echo 温度: ,$w->tep,

;echo 风力: ,$w->wind,

;echo sun: ,$w->sun,

;// 没有修改旧的方法, 这样就没有影响旧的客户端// 没有修改旧的类, 说明没有违反开闭原则

// 桥接模式 bridge 尝试// 论坛给用户发信息, 可以是站内短信, email, 手机// 本来只需要发站内短信, 后来又需要发email// 一个类只做一件事, 我们把他做成一个接口或者抽象类, 具体的发送由具体的子类实现interface msg { public function send($to, $content);}class zn implements msg { public function send($to, $content) { echo 站内信给, $to, 内容是: , $content; }}// 有一天要改造, 要发emailclass email implements msg { public function send($to, $content) { echo email给, $to, 内容是: , $content; }}// 后来要发短信class sms implements msg { public function send($to, $content) { echo 短信给, $to, 内容是: , $content; }}// 后来内容也丰富了, 分普通, 加急, 特急// 子类就爆炸了, 像数据的三范式一样, 如果完全遵循解耦是不行了/*class zncommon extends zn;class znwarn extends zn;class zndanger extends zn;class emailcomm extends email;class emailwarn extends email;class emaildanger extends email;....*//** * 思考: * 信的发送方式是一个变化因素 * 信的紧急程度是一个变化因素, * 为了不修改父类, 只好考虑2个因素的组织, 不停产生新类.... */

abstract class info { protected $send = null; public function __construct($send) { $this->send = $send; } abstract public function msg($content); public function send($to, $content){ $content = $this->msg($content); $this->send->send($to, $content); }}class zn { public function send($to, $content) { echo 站内给: , $to, 内容是: , $content; }}class email { public function send($to, $content) { echo email给: , $to, 内容是: , $content; }}class sms { public function send($to, $content) { echo sms给: , $to, 内容是: , $content; }}class commoninfo extends info{ public function msg($content) { return 普通. $content; }}class warninfo extends info{ public function msg($content) { return 紧急.$content; }}class dangerinfo extends info{ public function msg($content) { return 紧急.$content; }}// 用站内发普通信息$commoninfo = new commoninfo(new zn());$commoninfo->send(小明, 吃饭了);//给小刚发紧急手机短信消息$dangerinfo = new dangerinfo(new sms());$dangerinfo->send(小刚, 失火了);// 本来需要3x3个类// 现在只需要3+3个类了// 现在耦合了, view中不写逻辑, 数据库三范式, 老有相同的字段, 为了速度, 之前的设计模式都是在解耦, 现在反而增加了耦合, 是为了防止子类爆炸

卖鞋子的网站源码,vscode调试多进程,ubuntu 桌面选择,mac下运行tomcat,shopify爬虫,php内存池,设计公司seo推广营销,c web网站源码下载,成人用品html模板lzw

以上就介绍了PHP常用设计模式单例, 工厂, 观察者, 责任链, 装饰, 策略,适配,桥接模式,包括了方面的内容,希望对PHP教学有兴趣的朋友有所帮助。

android雷霆战机源码,ubuntu降低屏幕亮度,西瓜视频反爬虫,php叫号,盱眙企业seolzw

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。