返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP 设计模式之最全面,最简单的讲解
  • 190
分享到

PHP 设计模式之最全面,最简单的讲解

php设计模式单例模式 2023-09-25 05:09:49 190人浏览 八月长安
摘要

1.单例模式 单例模式是指只创建一个资源(对象、数据库链接等),防止外部实例+判断是否有返回或创建后返回对象。 三个要点: 1.需要一个保存类的唯一实例的静态成员变量2.构造函数和克隆函数必须声

1.单例模式

单例模式是指只创建一个资源(对象、数据库链接等),防止外部实例+判断是否有返回或创建后返回对象。

三个要点:
1.需要一个保存类的唯一实例的静态成员变量2.构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义3.必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用
优点:

单例模式减少资源浪费,保证整个环境只有一个实例对象,特别适合编写资源连接类

代码:
#代码:class RedisServer{    #创建一个静态变量 保存类的唯一实例的静态成员变量    private static $instance=[];    private $redis;    private $host='127.0.0.1';#ip    private $post=6379;#端口号    private $timeout=0;#闲置时间后关闭    private $table=0;#指定哪个库    private $connect=1;# 1 长连接 0 短连接    //私有的构造方法,禁止外部使用new创建对象 走完这里 3再走方法    #指定 ip 端口 这两个是基本不会变的 但是 库的会变 所以根据库的不同 可以new 不同的对象    private function __construct($config){        $this->redis = new Redis();        if(isset($config['host']))  $this->host = $config['host'];        if(isset($config['post']))  $this->post = $config['post'];        if(isset($config['timeout']))  $this->timeout = $config['timeout'];        if(isset($config['table']))  $this->table = $config['table'];        if(isset($config['connect']))  $this->connect = $config['connect']>=1 ?1:0;        # 连接        if($this->connect){            $this->redis->pconnect($this->host,$this->post,$this->timeout);        }else{            $this->redis->connect($this->host,$this->post,$this->timeout);        }        if($this->table>15 || $this->table<0 || !is_int($this->table) ){            echo '数据库表只能填写0~15的整数';            exit;        }        #选择库        $this->redis->select($config['table']);    }    #1先走这里    public static function getInstance($config=[]){        $table = array_key_exists('table',$config) ?$config['table']:0;        #为啥这里的私有变量 需要加数组呢 如果不加的话 他已经存在了 但他指定的表可能不是你所需要的 就会存在bug        if(!isset(self::$instance[$table])){            # 这里创建一个对象 赋值给变量            echo '重新新建一个表为'.$table.'的对象!';            self::$instance[$table] = new self($config);//2然后再走 __construct        }        return self::$instance[$table];    }    //私有的克隆函数 将克隆方法设为私有,禁止外部克隆对象    private function __clone(){}    # 4 方法                public function close(){            return $this->redis->close();        }        public function getString($str){           return $this->redis->get($str);        }        public function setString($key,$value){            return $this->redis->set($key,$value);        }}$config =[    'host'=>'127.0.0.1',#ip    'post'=>'6379',#端口号    'timeout'=>'0',#闲置时间后关闭    'table'=>1,#指定哪个库    'connect'=>0,# 1 长连接 0 短连接];$config1 =[    'host'=>'127.0.0.1',#ip    'post'=>'6379',#端口号    'timeout'=>'0',#闲置时间后关闭    'table'=>2,#指定哪个库    'connect'=>0,# 1 长连接 0 短连接];$Server = RedisServer::getInstance($config);$Server1 = RedisServer::getInstance($config1);

2.工厂模式

工厂模式其实是一种类,它具有创建对象的某些方法。我们可以使用工厂类来创建对象,而不直接使用 new。这样做的好处是,如果你想要更改所实例化的类名,则只需更改该工厂方法内容即可,不需要逐一寻找代码中具体实例化的地方来修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。

优点:

帮助封装:简单工厂虽然简单,但是非常友好地帮助我们实现了组件的封装,然后让组件外部能真正面向接口编程
解耦 :通过简单工厂,实现了客户端和具体实现类的解耦。

缺点:

可能增加客户端的复杂度。

工厂模式其实可以划分为:简单工厂模式、工厂方法模式、抽象工厂模式等。

1.简单工厂模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂模式使一个类的实例化延迟到其子类。一般用在具体产品很少扩展的情况下,不用经常修改,且不修改代码的话是不能实现扩展的。

例子:去商店卖手机 一个是苹果厂商提供的手机 一个是小米厂商提供的手机。

#简单工厂模式#定义一个接口 手机类商品 等电子产品interface Mobile{    #手机    public function mobile();    #充电器    public function charger();}#苹果手机厂商class Iphone_Mobile implements Mobile {    public function __construct()    {        echo '苹果旗舰店:';    }    public function mobile(){        echo '手机;';    }    public function charger(){        echo '充电器;';    }}#小米手机厂商class XiaoMI_Mobile implements Mobile {    public function __construct()    {        echo '小米旗舰店:';    }    public function mobile(){        echo '手机;';    }    public function charger(){        echo '充电器;';    }}# 商店class Shopping{    public static function create($class){        switch ($class)        {            case 'Iphone_Mobile':                return new Iphone_Mobile();#选择苹果厂商的商品                break;            case 'XiaoMI_Mobile':                return new XiaoMI_Mobile();#选择小米厂商的商品            default: echo '不好意思,我这里没有 '.$class.' 这个手机卖!';        }    }}#商店 下单买苹果手机$Iphone = Shopping::create('Iphone_Mobile');#苹果旗舰手机店:$Iphone->mobile();#买苹果手机:;$Iphone->charger();#买苹果充电器:;#商店 下单买小米手机$XiaoMI = Shopping::create('XiaoMI_Mobile');#小米旗舰店:$XiaoMI->mobile();#买小米手机:;$XiaoMI->charger();#买小米充电器:;#商店 下单买华为手机$HUAWEI = Shopping::create('HUAWEI_Mobile');#不好意思,我这里没有 HUAWEI_Mobile 这个手机卖!
2.工厂方法模式

例子:去店铺买手机。发现只有苹果的柜台和小米的柜台。而且柜台只有手机和充电器买。

通过定义了一个抽象出来的核心工厂类,并同时定义创建产品对象的接口,而创建具体实例的工作延迟到工厂子类中去完成

#工厂模式方法#定义一个接口 手机类商品 等电子产品interface Mobile{    #手机    public function mobile();    #充电器    public function charger();}#苹果手机厂商class Iphone_Mobile implements Mobile {    public function __construct()    {        echo '苹果手机:';    }    public function mobile(){        echo '手机;';    }    public function charger(){        echo '充电器;';    }}#小米手机厂商class XiaoMI_Mobile implements Mobile {    public function __construct()    {        echo '小米手机:';    }    public function mobile(){        echo '手机;';    }    public function charger(){        echo '充电器;';    }}#区别#定义一个抽象类#淘宝abstract class Taobao{abstract static function shop();# 开店 }# 苹果手机的厂家在淘宝开店class Iphone function extends Taobao{public static function shop(){return new Iphone_Mobile();#卖的是自己的苹果手机} }# 小米手机的厂家在淘宝开店class XiaoMI function extends Taobao{public static function shop(){return new XiaoMI_Mobile();#卖的是自己的小米手机} } $one = Iphone::shop();#去苹果手机店里面$one->mobile();//手机$one->charger();//充电器$two = XiaoMI::shop();#去小米手机店里面$two->mobile();//手机$two->charger();//充电器
3.抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口。

例子:去淘宝买电子产品 只有两个电脑和手机两个种类的产品。 而且电脑产品只有:电脑和鼠标卖,手机产品只有:手机和充电器买。

#抽象工厂 #定义一个手机类电子产品的接口interface Mobile{#手机    public function mobile(); #充电器    public function charger();} # 苹果厂商class IPhone implements Mobile{    public function mobile()    {        echo "购买苹果手机";    }     public function charger()    {        echo "购买苹果充电器";    }} #定义一个电脑类电子产品的接口interface Computer{#电脑    public function computer(); #鼠标    public function mouse();} #小米厂商class XiaomiComputer implements Computer{    public function computer()    {        echo "购买小米电脑";    }     public function mouse()    {        echo "购买小米鼠标";    }} #定义一个抽象类的 店铺 里面提供手机产品和电脑产品abstract class Shop{#手机产品    abstract public static function createMobile(); #电脑产品    abstract public static function createComputer();} #淘宝class Taobao extends Shop{#手机产品    public static function createMobile()    {        return new IPhone();#只有苹果的手机产品买    } #电脑产品    public static function createComputer()    {        return new XiaomiComputer();#只有小米的电脑产品买    }} #用户去淘宝选手机$one = Taobao::createMobile();#发现只有苹果的手机买$one->mobile();#买了一个苹果手机$one->charger();#买了一个苹果充电器#用户去淘宝选电脑$two = Taobao::createComputer();#发现只小米的电脑买$two->computer();#购买小米电脑$two->mouse()#购买小米鼠标

3.策略模式

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

代码示例:

#通过需要不同的日期信息来调用不同的类实现功能。 #策略模式:        #定义一个接口  日期转换        interface Time        {            public function timeString();        }        # 当前的年份        class Year implements Time{            public function timeString(){                   echo date('Y',time()).'年';            }        }        # 当前的月份        class Month implements Time{            public function timeString(){                echo date('m',time()).'月';            }        }        # 当前的日期        class Day implements Time{            public function timeString(){                echo date('Y-m-d',time());            }        }        class Times {            private $class;            #根据所需的日期 来选择调用哪个类的方法            public function timess(Time $class){                 $this->class = $class;                 return $this->class->timeString();            }        }        $Year = new Times();        #查看当前的年份        $Year->timess(new Year());#2022年        #查看当前的月份        $Year->timess(new Month());#07月        #查看当前的日期        $Year->timess(new Day());#2022-07-20        

4.适配器模式

将一个类的接口转成我们希望的另外一个接口,使得原本接口不兼容不能在一起工作的类可以在一起工作。

优点:灵活性和扩展性都非常好,符合开闭原则。
缺点:过多地使用适配器,会让系统非常零乱,不易整体进行把握。

代码示例:

#例如:封装一个缓存类,它支持  redis 和 memcache,只需切换使用时只需修改相关配置就能实现切换了,而不需要修改大量的代码。#减少代码间的耦合,可以方便增减需要实现的类。# 适配器模式        #定义一个缓存类        interface Cache        {            public function connect();            public function set($key,$value,$time=0);            public function get($key);            public function del($key);            public function close();        }# 使用 redis 做为缓存        class Rediss implements Cache        {            private $redis;            public function __construct()            {                $this->connect();            }            public function connect()            {                $this->redis = new Redis();                return $this->redis->connect('127.0.0.1','6379');            }            public function set($key,$value,$time=0)            {                if($time==0){                    return $this->redis->set($key,$value);                }else{                    return $this->redis->setex($key,$time,$value);                }            }            public function get($key)            {                return $this->redis->get($key);            }            public function del($key)            {                return $this->redis->delete($key);            }            public function close()            {                return $this->redis->close();            }        }        #使用 memcache 做为缓存    class Memcaches implements Cache    {        private $memcache;        public function __construct()        {            $this->connect();        }        public function connect()        {            $this->memcache = new Memcache();            return $this->memcache->connect('127.0.0.1','11211');        }        public function set($key,$value,$time=0)        {            return $this->memcache->set($key,$value,false,$time);        }        public function get($key)        {            return $this->memcache->get($key);        }        public function del($key)        {            return $this->memcache->delete($key);        }        public function close()        {            return $this->memcache->close();        }    }        #调用if($cache_config == 'redis'){# 使用 redis $cache = new Rediss();  }else{# 使用 memcache    $cache = new Memcaches();}$cache->set('key','value');        $cache->get('key'));        $cache->del('key');        $cache->close();    
5.注册模式

注册树模式通过将对象示例注册到一颗全局的对象树上, 需要的时候从对象树上采摘的模式设计方法。

代码示例:

 #注册模式    class ReGISter    {        #定义一个私有的变量        private static $objects;        # 注册类        public static function set($key,$class)        {           if(!isset(self::$objects[$key])){               self::$objects[$key] = $class;           }           return true;        }        #获取类的对象        public static function get($key){            if(!isset(self::$objects[$key])){                return false;            }            return self::$objects[$key];        }        #取消注册类        public static function unset_class($key){            if(!isset(self::$objects[$key])){                return false;            }            unset(self::$objects[$key]);            return true;        }        #查看所有的类        public static function all(){            return self::$objects;        }    }    # 定义一个类        #苹果手机类    class Apple{            public function __construct(){                echo '苹果手机:';            }            public function open(){                echo '开机';            }            public function close(){                echo '关机';            }    }        #华为手机类    class HuaWei{        public function __construct(){            echo '华为手机:';        }        public function open(){            echo '开机';        }        public function close(){            echo '关机';        }    }        #注册类        Register::set('apple',new Apple());        Register::set('huawei',new HuaWei());#获取类       echo Register::get('apple')->close();#苹果手机:关机       echo Register::get('huawei')->close();#华为手机:关机       #查看所有注册类        var_dump(Register::all());        
6.观察者模式

观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项目中经常使用的模式定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

优点:降低了类对象之间的耦合度。
缺点:观察者较多时,可能会花费一定的开销来发消息,但这个消息可能仅一个观察者消费。

代码示例:

 #观察者模式  #把购买商品这个接口 当做被观察的对象  #把通知商户 , 通知用户,记录日志 当做观察者        #例子 购买商品成功 需要通知商户 通知用户 记录日志等操作            #定义一个通知的接口            interface Send{                public function sendMsg();            }            #给商户发消息 观察者            class Shop implements Send{                public function sendMsg(){                   echo '
 用户下单成功 
'
; } } #给用户发消息 观察者 class User implements Send{ public function sendMsg(){ echo '
 购买商品成功 
'
; } } #给日志发消息 观察者 class Loggs implements Send{ public function sendMsg(){ echo '
 xx用户在xx商户购买xx商品成功 
'
; } } #定义一个接口 interface obeject{ public function addObeject($key); } # 被观察的对象 class Order implements obeject{ private $obeject; #绑定通知 public function addObeject($key){ $this->obeject[]=$key; } #购买逻辑 public function addOrder(){ #写下单逻辑 #下单成功通知 foreach ($this->obeject as $value){ $value->sendMsg(); } } } $order = new Order(); $order->addObeject(new Loggs());#
 xx用户在xx商户购买xx商品成功 
$order->addObeject(new Shop());#
 购买商品成功 
$order->addOrder();

来源地址:https://blog.csdn.net/kafeibujianai/article/details/125865697

--结束END--

本文标题: PHP 设计模式之最全面,最简单的讲解

本文链接: https://lsjlt.com/news/417167.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • PHP 设计模式之最全面,最简单的讲解
    1.单例模式 单例模式是指只创建一个资源(对象、数据库链接等),防止外部实例+判断是否有返回或创建后返回对象。 三个要点: 1.需要一个保存类的唯一实例的静态成员变量2.构造函数和克隆函数必须声...
    99+
    2023-09-25
    php 设计模式 单例模式
  • Java设计模式之GOF23全面讲解
    一、什么是设计模式 设计模式(Design pattern) 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码...
    99+
    2024-04-02
  • Python 中最简最好的设计模式
    大势所趋,Python 已然成风C语言诞生于1972年,确随着 Unix 的诞生才深深植根于各大操作系统;C++诞生于1983年,确因微软的可视化桌面操作系统才得以广泛传播;Java 诞生于1995年,确因互联网的迅速崛起才变得家喻户晓;P...
    99+
    2023-01-31
    最好的 模式 Python
  • Java设计模式之单件模式深入讲解
    目录定义Java单件模式经典单件模式的实现多线程单件模式的实现急切创建实例双重检查加锁Python单件模式模块实现new关键字实现装饰器实现函数装饰器类装饰器定义 单件模式确保一个类...
    99+
    2024-04-02
  • Golang设计模式之单例模式详细讲解
    目录单例模式概念示例单例模式 单例是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 单例拥有与全局变量相同的优缺点。 尽管它们非常有用, 但...
    99+
    2023-01-11
    Go单例模式 Go设计模式
  • java设计模式之简单工厂模式详解
    简单工厂模式:由一个工厂对象决定创建出哪一种类的实例。抽象类public abstract class People { public abstract void doSth();}...
    99+
    2023-05-31
    java 设计模式 简单工厂
  • PHP 设计模式单元测试最佳实践
    php 设计模式单元测试最佳实践:隔离依赖项: 使用依赖注入或 mock 对象,避免与外部组件的耦合。测试边界条件: 考虑异常、错误处理和边缘用例,确保设计模式在各种情况下都能正确工作。...
    99+
    2024-05-07
    php 设计模式
  • Java设计模式之单例模式简介
    目录一、饿汉式(静态常量)二、饿汉式(静态代码块)三、懒汉式(线程不安全)四、懒汉式(线程安全,同步方法)五、懒汉式(线程不安全,同步代码块)六、双重检查( DCL )七、静态内部类...
    99+
    2024-04-02
  • C#设计模式之简单工厂模式
    设计模式分类: 创建型模式。结构型模式。行为模式。 23种设计模式,如何记。面向对象的系统中有很多对象,创建型模式解决的问题就是如何创建对象,何时创建对象,它努力的让代码不要太多的关...
    99+
    2024-04-02
  • Java超详细讲解设计模式之一的单例模式
    目录单例模式1.单例模式的结构2.单例模式的实现2.1饿汉式2.2懒汉式3.单例模式的破坏3.1序列化和反序列化3.2反射单例模式 单例模式顾名思义就是单一的实例,涉及到一个单一的类...
    99+
    2024-04-02
  • Golang设计模式之组合模式讲解
    目录组合模式概念示例组合模式 组合是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。 对于绝大多数需要生成树状结构的问题来说, 组合都是非...
    99+
    2023-01-14
    Go组合模式 Go组合模式
  • 深入理解Java设计模式之简单工厂模式
    目录一、什么是简单工厂模式二、简单工厂模式的结构三、简单工厂模式的应用场景四、简单工厂模式和工厂方法模式区别五、简单工厂模式和策略模式的异同六、简单工厂模式的优缺点七、简单工厂模式的...
    99+
    2024-04-02
  • Java 超详细讲解设计模式之原型模式讲解
    目录传统方式原型模式基本介绍原型模式在spring框架中源码分析深入讨论-浅讨论和深拷贝原型模式的注意事项和细节传统方式 克隆羊问题 现在有一只羊 tom,姓名为: tom,年龄为:...
    99+
    2024-04-02
  • PHP设计模式:最佳实践探究
    设计模式在 php 中提供可重复的代码解决方案,提高代码的可维护性、可扩展性和可复用性。常见的模式包括:单例模式:确保只创建一个类的实例。观察者模式:允许一个对象通知多个对象其状态更改。...
    99+
    2024-05-13
    php 设计模式 高可扩展性
  • Java 设计模式以虹猫蓝兔的故事讲解简单工厂模式
    目录专栏介绍本期介绍什么是简单工厂模式优点缺点应用场景简单工厂的实现专栏介绍 本系列专栏会以虹猫蓝兔七侠传的故事为例来给大家详细分析所有模式,希望能给大家带来帮助! 本期介绍 模式:...
    99+
    2024-04-02
  • C++单例设计模式详细讲解
    目录特殊类设计只能在堆上创建对象的类请设计一个类只能在栈上创建对象请设计一个类不能被拷贝请设计一个类不能被继承请设计一个类只能创建一个对象(单例模式)懒汉模式和饿汉模式的对比特殊类设...
    99+
    2024-04-02
  • PHP设计模式中观察者模式讲解
    目录简介适用场景优点缺点补充代码(自定义实现)代码(基于SPL实现)简介 观察者模式是行为型模式的一种,定义了对象间一对多的关系。当对象的状态发生变化时候,依赖于它的对象会得到通知。...
    99+
    2022-11-13
    PHP观察者模式 PHP设计模式
  • PHP 设计模式解惑:从工厂到单例,全面剖析
    php 设计模式用于解决常见问题,提供灵活性、可扩展性和可维护性。它们包括:工厂模式:通过工厂类创建对象,简化对象的创建过程。建造者模式:分步建造复杂对象,允许在不影响表示的情况下独立改...
    99+
    2024-05-09
    php 设计模式
  • python之解析最简单的xml
    1、person.xm文件如下 2、用xml.etree.ElementTree解析person.xml的实现 3、效果如下 4、总结 python里面的list = []相当于java里面的list,然后...
    99+
    2023-01-31
    最简单 python xml
  • JAVA设计模式之单例模式详解
    目录前言一、单例模式是什么?二、懒汉式单例三、饿汉式单例四、双重校验锁总结前言 在之前的文章里已经介绍了设计模式以及设计原则的概念,接下来我们从单例模式入手深入学习几种常用的JAVA...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作