


PHP common design patterns singleton, factory, observer, chain of responsibility, decoration, strategy, adaptation, bridge mode
// 多态, 在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 '不是一个对象'; }
<!DOCTYPE HTML> <html> <head> <title>colour_blue</title> <meta name="description" c /> <meta name="keywords" c /> <meta http-equiv="content-type" c /> <style> div{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } </style> <script> 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区, 如何能不改原来的代码, 而只增加 */ </script> </head> <body> <h1>面向过程, 不用任务来切换</h1> <select name="" name="code">// 比如登录, 在登录的时候出于安全考虑要记录上次登录时间 // 出于商业考虑, 给你推荐商品 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 < 3) { echo '这是第'.$subject->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();
<!DOCTYPE HTML> <html> <head> <title>colour_blue</title> <meta name="description" c /> <meta name="keywords" c /> <meta http-equiv="content-type" c /> <style> div{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } </style> </head> <body> <h1>观察者模式</h1> <select name=""> <option value="male">男式风格</option> <option value="female">女式风格</option> </select> <input type="button" value="观察尾部" /> <input type="button" value="别观察尾部了" /> <div>我是内容</div> <div>我是广告</div> <div>学习</div> <script> // 服务器端 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'); } </script> </body> </html>
.html <!DOCTYPE HTML> <html> <head> <title>colour_blue</title> <meta name="description" c /> <meta name="keywords" c /> <meta http-equiv="content-type" c /> <style> div{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } </style> </head> <body> <h2>责任链模式举报过程</h2> <form action="10.php" method="post"> <select name="jubao"> <option value="1">粗口</option> <option value="2">黄赌毒</option> <option value="3">分裂国家</option> </select> <button type="submit">举报</button> </form> </body> </html> .php <?php header('Content-type: text/html; charset=utf-8'); //版主 class board { protected $power = 1; protected $top = 'admin'; public function process($lev) { if($lev <= $this->power) { echo '版主删贴'; } else { $top = new $this->top; $top->process($lev); } } } class admin { protected $power = 2; protected $top = 'police'; public function process($lev) { if($lev <= $this->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);
.html <!DOCTYPE HTML> <html> <head> <title>colour_blue</title> <meta name="description" c /> <meta name="keywords" c /> <meta http-equiv="content-type" c /> <style> div{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } </style> </head> <body> <h2>面向过程完成举报过程</h2> <form action="09.php" method="post"> <select name="jubao"> <option value="1">粗口</option> <option value="2">黄赌毒</option> <option value="3">分裂国家</option> </select> <button type="submit">举报</button> </form> </body> </html> .php <?php header('Content-type: text/html; charset=utf-8'); $lev = $_POST['jubao']; //版主 class board { public function process() { echo '版主删贴'; } } class admin { public function process() { echo '管理员封账号'; } } class police { public function process() { echo '抓起来'; } } if ($lev == 1) { $judge = new board(); $judge->process(); } elseif($lev==2) { $judge = new admin(); $judge->process(); } elseif($lev==3) { $judge = new police(); $judge->process(); } // 处理的不够优雅, 现在还是面向过程的写法, 面向过程和面向对象混合了 // 如果以后在两个等级中间要添加一个等级应该怎么办
.html <!DOCTYPE HTML> <html> <head> <title>colour_blue</title> <meta name="description" c /> <meta name="keywords" c /> <meta http-equiv="content-type" c /> <style> div{ margin:10px; width:500px; height:200px; border: 1px solid green; } #content { } #ad { } </style> </head> <body> <h2>策略模式 和工厂方法的区别只是在逻辑上的区别, 也叫聚合</h2> <form action="11.php" method="post"> <input type="text" name="op1" /> <select name="op"> <option value="add">+</option> <option value="sub">-</option> <option value="mul">*</option> <option value="div">/</option> </select> <input type="text" name="op2" /> <button type="submit">计算</button> </form> </body> </html> .php <?php /** * Created by PhpStorm. * User: michaeldu * Date: 15/7/15 * Time: 上午12:11 */ interface Math { public function calc($op1, $op2); } class MathAdd implements Math{ public function calc($op1, $op2) { return $op1 + $op2; } } class MathSub implements Math{ public function calc($op1, $op2) { return $op1 - $op2; } } class MathMul implements Math{ public function calc($op1, $op2) { return $op1 * $op2; } } class MathDiv implements Math{ public function calc($op1, $op2) { return $op1 / $op2; } } //封装一个虚拟计算器, 统一计算接口 class CMath { protected $calc = null; public function __construct($type) { $calc = 'Math'. ucfirst($type); $this->calc = 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']);
// 装饰器模式 decorator class 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() . '小编摘要'; } } // SEO class 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 = [ 'tep' => 28, 'wind' => 7, 'sun' => 'sunny', ]; return serialize($today); } } // 客户端调用 $weather = unserialize(weather::show()); echo '温度: ',$weather['tep'],'<br />'; echo '风力: ',$weather['wind'],'<br />'; echo 'sun: ',$weather['sun'],'<br />'; // 来了一批手机上的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,'<br />'; echo '风力: ',$w->wind,'<br />'; echo 'sun: ',$w->sun,'<br />'; // 没有修改旧的方法, 这样就没有影响旧的客户端 // 没有修改旧的类, 说明没有违反开闭原则
The above has introduced the common PHP design patterns of singleton, factory, observer, chain of responsibility, decoration, strategy, adaptation, and bridge mode, including the content. I hope it will be helpful to friends who are interested in PHP tutorials.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Many users will choose the Huawei brand when choosing smart watches. Among them, Huawei GT3pro and GT4 are very popular choices. Many users are curious about the difference between Huawei GT3pro and GT4. Let’s introduce the two to you. . What are the differences between Huawei GT3pro and GT4? 1. Appearance GT4: 46mm and 41mm, the material is glass mirror + stainless steel body + high-resolution fiber back shell. GT3pro: 46.6mm and 42.9mm, the material is sapphire glass + titanium body/ceramic body + ceramic back shell 2. Healthy GT4: Using the latest Huawei Truseen5.5+ algorithm, the results will be more accurate. GT3pro: Added ECG electrocardiogram and blood vessel and safety

Function means function. It is a reusable code block with specific functions. It is one of the basic components of a program. It can accept input parameters, perform specific operations, and return results. Its purpose is to encapsulate a reusable block of code. code to improve code reusability and maintainability.

Why Snipping Tool Not Working on Windows 11 Understanding the root cause of the problem can help find the right solution. Here are the top reasons why the Snipping Tool might not be working properly: Focus Assistant is On: This prevents the Snipping Tool from opening. Corrupted application: If the snipping tool crashes on launch, it might be corrupted. Outdated graphics drivers: Incompatible drivers may interfere with the snipping tool. Interference from other applications: Other running applications may conflict with the Snipping Tool. Certificate has expired: An error during the upgrade process may cause this issu simple solution. These are suitable for most users and do not require any special technical knowledge. 1. Update Windows and Microsoft Store apps

Every year before Apple releases a new major version of iOS and macOS, users can download the beta version several months in advance and experience it first. Since the software is used by both the public and developers, Apple has launched developer and public versions, which are public beta versions of the developer beta version, for both. What is the difference between the developer version and the public version of iOS? Literally speaking, the developer version is a developer test version, and the public version is a public test version. The developer version and the public version target different audiences. The developer version is used by Apple for testing by developers. You need an Apple developer account to download and upgrade it.

In this article, we will learn about enumerate() function and the purpose of “enumerate()” function in Python. What is the enumerate() function? Python's enumerate() function accepts a data collection as a parameter and returns an enumeration object. Enumeration objects are returned as key-value pairs. The key is the index corresponding to each item, and the value is the items. Syntax enumerate(iterable,start) Parameters iterable - The passed in data collection can be returned as an enumeration object, called iterablestart - As the name suggests, the starting index of the enumeration object is defined by start. if we ignore

Part 1: Initial Troubleshooting Steps Checking Apple’s System Status: Before delving into complex solutions, let’s start with the basics. The problem may not lie with your device; Apple's servers may be down. Visit Apple's System Status page to see if the AppStore is working properly. If there's a problem, all you can do is wait for Apple to fix it. Check your internet connection: Make sure you have a stable internet connection as the "Unable to connect to AppStore" issue can sometimes be attributed to a poor connection. Try switching between Wi-Fi and mobile data or resetting network settings (General > Reset > Reset Network Settings > Settings). Update your iOS version:

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

Detailed explanation of the role and function of the MySQL.proc table. MySQL is a popular relational database management system. When developers use MySQL, they often involve the creation and management of stored procedures (StoredProcedure). The MySQL.proc table is a very important system table. It stores information related to all stored procedures in the database, including the name, definition, parameters, etc. of the stored procedures. In this article, we will explain in detail the role and functionality of the MySQL.proc table
