PHP常用设计模式,PHP常用设计模式详解,PHP详解设计模式,PHP设计模式
程序员文章站
2022-06-19 10:37:20
PHP常用设计模式详解 单例模式: php交流群:159789818 特性:单例类只能有一个实例 类内__construct构造函数私有化,防止new实例 类内__clone私有化,防止复制对象 设置一个$instance私有静态属性,为了保存当前类的实例 设置一个getInstance公有方法,为 ......
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(); }
上一篇: 前端HTML基础知识学什么?