PHP常用设计模式,PHP常用设计模式详解,PHP详解设计模式,PHP设计模式
PHP常用设计模式详解
单例模式:
php交流群:159789818
特性:单例类只能有一个实例
- 类内__construct构造函数私有化,防止new实例
- 类内__clone私有化,防止复制对象
- 设置一个$instance私有静态属性,为了保存当前类的实例
- 设置一个getInstance公有方法,为了获取当前类的实例
- 减少new对象操作,合理使用内存
通常使用在获取某个全局配置项,或者数据库连接、操作等类上
Demo:
1 <?php 2 Class Demo{ 3 //用于保存当前类的实例 4 private static $instance; 5 //构造函数私有化,防止直接new当前对象 6 private function __construct(){} 7 //析构函数私有化,防止从外部直接复制当前对象 8 private function __clone(){} 9 //getInstance公有函数用于获取当前类的实例 10 public static function getInstance() 11 { 12 //判断当前类成员变量instance是否为空 13 //如果不为空,则直接返回类的实例 14 //如果为空,则new一个当前类的实例,并保存到类成员变量 15 //instance中,然后直接返回成员变量 16 if(empty(self::$instance)) 17 { 18 //将实例保存到instance成员变量中 19 self::$instance = new static(); 20 //直接返回成员变量 21 return self::$instance; 22 }else{ 23 //直接返回类实例 24 return self::$instance; 25 } 26 } 27 } 28 $demo1 = Demo::getInstance();//获取到实例 29 $demo2 = new Demo();//报错
工厂模式(Factory Design Pattern)
特性:
- 降低系统耦合度
- 遵循开发-封闭原则 对修改封闭, 对扩展开放
- 通过工厂创建类的实例,而不是直接操作new关键字创建类的实例
- 已经使用的类内部发生改变,哪不需要在所有的地方都改变,只需要在类工厂类里改变既可
- 例如,支付宝微信银行等对接就可以写个工厂模式来对接
抽象工厂Demo:
<?php //PaymentFactory.php interface PaymentFactory { //请求收款码 public function QRcode(); //监听收款 public function Listen(); } interface createPay { //将对象的创建抽象成一个接口 function createOpen($class,$data);//内向创建 function createIntro($class,$data);//外向创建 } //微信支付类 Class WxPay implements PayMentFactory { public function QRcode() { //微信业务逻辑代码 //返回收款码以及订单相关参数 return "我是微信二维码"; } public function Listen() { //微信业务逻辑代码 //返回订单结果 return "正在监听"; } } //阿里支付类 Class aliyun implements PayMentFactory { public function QRcode() { //业务逻辑代码 //返回收款码以及订单相关参数 return "我是支付宝二维码"; } public function Listen() { //业务逻辑代码 //返回订单结果 return "正在监听"; } } //实现createPay接口 class CreateP implements createPay { public function createOpen($class,$data =[]) { return new $class($data); } public function createIntro($class,$data = []) { return new $class($data); } } //开发者类 class Client{ static function Get($class,$data = []) { $fac = new CreateP(); // var_dump($fac); return $fac->createOpen($class,$data); } } $pay = Client::Get("WxPay"); echo $pay->QRcode(); //输出,我是微信二维码
注册模式 Register
特性:
- 解决全局共享和交换对象
- 创建好的对象,挂到某个全局数组上
- 需要的时候直接去该数组上获取即可
- 将对象实例注册到全局树上
Demo:
<?php //全局注册类 Class Register { //存储类的实例 public static $maps; //注册操作 public static function Set($name,$cla) { //判断是否已经存储 if(array_key_exists($name,self::$maps)) { //如果全局maps内已有则直接返回 return true; }else{ //如果没有name 则将实例和name按键值对存储到成员变量内 self::$maps[$name] = $cla; return true; } } //获取类实例 public static function Get($name) { //判断name值是否存在 if(array_key_exists($name,self::$maps)) { //如果存在则直接返回对应的类的实例 return self::$maps[$name]; }else{ //如果不存在,则返回false或者其他 return false; } } }
适配器模式 Adapter :
特性:
- 将各种不同的函数接口封装到统一的api
- 降低因为接口底层代码的不同,而导致的调用?(个人理解)
Demo(网上直接copy来的):
接口 IDatabase <?php namespace IMooc; interface IDatabase { function connect($host, $user, $passwd, $dbname); function query($sql); function close(); } MySQL <?php namespace IMooc\Database; use IMooc\IDatabase; class MySQL implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysql_connect($host, $user, $passwd); mysql_select_db($dbname, $conn); $this->conn = $conn; } function query($sql) { $res = mysql_query($sql, $this->conn); return $res; } function close() { mysql_close($this->conn); } } MySQLi <?php namespace IMooc\Database; use IMooc\IDatabase; class MySQLi implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysqli_connect($host, $user, $passwd, $dbname); $this->conn = $conn; } function query($sql) { return mysqli_query($this->conn, $sql); } function close() { mysqli_close($this->conn); } } PDO <?php namespace IMooc\Database; use IMooc\IDatabase; class PDO implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd); $this->conn = $conn; } function query($sql) { return $this->conn->query($sql); } function close() { unset($this->conn); } }
通过以上案例,PHP与MySQL的数据库交互有三套API,在不同的场景下可能使用不同的API,那么开发好的代码,换一个环境,可能就要改变它的数据库API,那么就要改写所有的代码,使用适配器模式之后,就可以使用统一的API去屏蔽底层的API差异带来的环境改变之后需要改写代码的问题
观察者模式
特性:
- 观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新
- 一个事件发生后,要执行一连串更新操作。传统的编程思想,就是在这个事件的代码后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
- 观察者模式实现了低耦合,非侵入式的通知与更新机制
Demo:
<?php //EventGenerator //事件触发抽象类 abstract class EvemtGenerator { //存储观察者类 private $observer =[]; //添加观察者操作 public function AddOb(Observer $observer) { $this->observer[] = $observer; } //观察者通知操作 public function notify() { //循环类成员变量,并执行对应的观察者更新方法 foreach ($this->observer as $observer) { //执行每个观察者类内的更新操作 $observer->update(); } } } //定义观察者接口 interface Observer { public function update(); } //实现一个被观察者类 Class Test extends EvemtGenerator { //实现一个登陆方法 public function login() { return "登陆成功"; } } //实现一个观察者 Class Observer1 implements Observer { //定义一个逻辑更新操作 例如:添加了csrf验证 public function update() { if($_POST['csrf'] == getCsrf()) { return true; }else{ exit("csrf验证不正确"); } } } //实例化Test类 被观察 $event = new Test(); $event->AddOb(new Observer1()); $event->login(); //更新通知操作 $event->notify();
策略模式:
特性:
- 将一组特定的行为和算法封装成类,以适应某些特定的上下文环境
- 方便系统维护,例如:为每一个用户登陆时展现不同的页面
- 解耦
Demo:
//定义策略接口,规范策略行为 interface UserStrategy { public function show(); public function message(); } //定义一个喜欢买西装的用户类 Class SuitUser implements UserStrategy { public function show() { //为用户跳转到西装页面 return "跳转到西装页面"; } public function message() { //发送message echo "即将为您展示最新的西装某某某"; } } //定义一个喜欢买裙子的用户类 Class skirtUser implements UserStrategy { public function show() { //为用户跳转到西装页面 return "跳转到裙子推荐页面"; } public function message() { //发送message echo "即将为您展示最新的裙子某某某"; } } //定义一个业务类 Class Users { //存储对应的用户类 private $userCla; //执行策略接口 public function Start() { echo "跳转页面是:".$this->strategy->show(); echo "消息是:".$this->strategy->message(); } //注册对应的用户类 public function SetStrategy(UserStrategy $strategy) { $this->$userCla = $strategy; } } //业务逻辑代码 判断用户习性 $user1 = "西装"; $user2 = "裙子"; $userL = new Users(); //如果用户习性为喜欢看西装或者买西装则 if ($user1 == "西装"){ $userL->SetStrategy(new SuitUser()); $userL->Start(); }
世人慌慌张张,不过图碎银几两
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)