欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP常用设计模式,PHP常用设计模式详解,PHP详解设计模式,PHP设计模式

程序员文章站 2022-03-10 16:28:19
PHP常用设计模式详解 单例模式: php交流群:159789818 特性:单例类只能有一个实例 类内__construct构造函数私有化,防止new实例 类内__clone私有化,防止复制对象 设置一个$instance私有静态属性,为了保存当前类的实例 设置一个getInstance公有方法,为 ......

php常用设计模式详解

 

单例模式:

php交流群:159789818

特性:单例类只能有一个实例

  1. 类内__construct构造函数私有化,防止new实例
  2. 类内__clone私有化,防止复制对象
  3. 设置一个$instance私有静态属性,为了保存当前类的实例
  4. 设置一个getinstance公有方法,为了获取当前类的实例
  5. 减少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)

特性:

  1. 降低系统耦合度
  2. 遵循开发-封闭原则 对修改封闭, 对扩展开放
  3. 通过工厂创建类的实例,而不是直接操作new关键字创建类的实例
  4. 已经使用的类内部发生改变,哪不需要在所有的地方都改变,只需要在类工厂类里改变既可
  5. 例如,支付宝微信银行等对接就可以写个工厂模式来对接

抽象工厂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

特性:

  1. 解决全局共享和交换对象
  2. 创建好的对象,挂到某个全局数组上
  3. 需要的时候直接去该数组上获取即可
  4. 将对象实例注册到全局树上

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 :

特性:

  1. 将各种不同的函数接口封装到统一的api
  2. 降低因为接口底层代码的不同,而导致的调用?(个人理解)

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差异带来的环境改变之后需要改写代码的问题

观察者模式

特性:

  1. 观察者模式(observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新
  2. 一个事件发生后,要执行一连串更新操作。传统的编程思想,就是在这个事件的代码后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
  3. 观察者模式实现了低耦合,非侵入式的通知与更新机制

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();

 

 

策略模式:

特性:

  1. 将一组特定的行为和算法封装成类,以适应某些特定的上下文环境
  2. 方便系统维护,例如:为每一个用户登陆时展现不同的页面
  3. 解耦

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();
}