PHP设计模式

文章目录
  1. 1. 单例模式
  2. 2. 观察者模式
  3. 3. 工厂模式
  • 适配器模式
    1. 1. 注册器模式(注册模式,注册树模式)
  • 参考自:https://www.cnblogs.com/DeanChopper/p/4830134.html

    单例模式

    单例模式指的是在整个应用中只有一个对象实例的设计模式。

    实现

    • 私有化一个属性用于存放唯一的一个实例
    • 私有化构造方法,私有化克隆方法,用来创建并只允许创建一个实例
    • 公有化静态方法,用于向系统提供这个实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class Singleton{
    //存放实例
    private static $_instance = null;

    //私有化构造方法
    private function __construct(){
    echo "单例模式的实例被构造了";
    }
    //私有化克隆方法
    private function __clone(){

    }

    //公有化获取实例方法
    public static function getInstance(){
    if (!(self::$_instance instanceof Singleton)){
    self::$_instance = new Singleton();
    }
    return self::$_instance;
    }
    }

    $singleton=Singleton::getInstance();

    构造函数私有化

    类中的方法修饰符没有限制,修饰符是在非类内部直接调用时生效,private 只能在类内部访问,实例化对象(new)的时候,会调用构造方法,但调用时发现构造方法修饰符为 private,不能在外部直接访问,所以报错,如果构造方法被私有化(private),就不能再使用 new 关键字,需要在类中写一个静态方法,因为静态方法调用不会走构造方法,再在静态方法中调用构造函数即可,此过程为“单例模式”的核心逻辑。

    观察者模式

    定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新 能够便利地创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定功能。

    实现

    首先,要有一个“主题”。只有有了一个主题,观察者才能搬着小板凳儿聚在一堆。其次,观察者还必须要有自己的操作。否则你聚在一堆儿没事做也没什么意义。

    从面向过程的角度来看,首先是观察者向主题注册,注册完之后,主题再通知观察者做出相应的操作,整个事情就完了。

    从面向对象的角度来看,主题提供注册和通知的接口,观察者提供自身操作的接口。(这些观察者拥有一个同一个接口。)观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。耦合度相当之低。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <?php
    // 主题接口
    interface Subject{
    public function register(Observer $observer);
    public function notify();
    }
    // 观察者接口
    interface Observer{
    public function watch();
    }
    // 主题
    class Action implements Subject{
    public $_observers=array();
    public function register(Observer $observer){
    $this->_observers[]=$observer;
    }

    public function notify(){
    foreach ($this->_observers as $observer) {
    $observer->watch();
    }

    }
    }

    // 观察者
    class Cat implements Observer{
    public function watch(){
    echo "Cat watches TV<hr/>";
    }
    }
    class Dog implements Observer{
    public function watch(){
    echo "Dog watches TV<hr/>";
    }
    }
    class People implements Observer{
    public function watch(){
    echo "People watches TV<hr/>";
    }
    }



    // 应用实例
    $action=new Action();
    $action->register(new Cat());
    $action->register(new People());
    $action->register(new Dog());
    $action->notify();
    工厂模式

    工厂模式是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。

    工厂模式分类:

    • 简单工厂模式:用来生产同一等级结构中的任意产品。对与增加新的产品,无能为力
    • 工厂模式:用来生产同一等级结构中的固定产品。(支持增加任意产品)
    • 抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

    无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <?php

    interface Transport{
    public function go();

    }

    class Bus implements Transport{
    public function go(){
    echo "bus每一站都要停";
    }
    }

    class Car implements Transport{
    public function go(){
    echo "car跑的飞快";
    }
    }

    class Bike implements Transport{
    public function go(){
    echo "bike比较慢";
    }
    }

    class transFactory{
    public static function factory($transport)
    {

    switch ($transport) {
    case 'bus':
    return new Bus();
    break;

    case 'car':
    return new Car();
    break;
    case 'bike':
    return new Bike();
    break;
    }
    }
    }

    $transport=transFactory::factory('car');
    $transport->go();

    适配器模式

    将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作。

    适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)–适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。

    适配器模式流程

    1. 客户通过目标接口调用适配器的方法对适配器发出请求
    2. 适配器使用被适配者接口把请求转换成被适配者一个或多个调用接口
    3. 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    <?php
    abstract class Toy
    {
    public abstract function openMouth();

    public abstract function closeMouth();
    }

    class Dog extends Toy
    {
    public function openMouth()
    {
    echo "Dog open Mouth\n";
    }

    public function closeMouth()
    {
    echo "Dog close Mouth\n";
    }
    }

    class Cat extends Toy
    {
    public function openMouth()
    {
    echo "Cat open Mouth\n";
    }

    public function closeMouth()
    {
    echo "Cat close Mouth\n";
    }
    }


    //目标角色:红枣遥控公司
    interface RedTarget
    {
    public function doMouthOpen();

    public function doMouthClose();
    }

    //目标角色:绿枣遥控公司及
    interface GreenTarget
    {
    public function operateMouth($type = 0);
    }


    //类适配器角色:红枣遥控公司
    class RedAdapter implements RedTarget
    {
    private $adaptee;

    function __construct(Toy $adaptee)
    {
    $this->adaptee = $adaptee;
    }

    //委派调用Adaptee的sampleMethod1方法
    public function doMouthOpen()
    {
    $this->adaptee->openMouth();
    }

    public function doMouthClose()
    {
    $this->adaptee->closeMouth();
    }
    }

    //类适配器角色:绿枣遥控公司
    class GreenAdapter implements GreenTarget
    {
    private $adaptee;

    function __construct(Toy $adaptee)
    {
    $this->adaptee = $adaptee;
    }

    //委派调用Adaptee:GreenTarget的operateMouth方法
    public function operateMouth($type = 0)
    {
    if ($type) {
    $this->adaptee->openMouth();
    } else {
    $this->adaptee->closeMouth();
    }
    }
    }



    class testDriver
    {
    public function run()
    {
    //实例化一只狗玩具
    $adaptee_dog = new Dog();
    echo "给狗套上红枣适配器\n";
    $adapter_red = new RedAdapter($adaptee_dog);
    //张嘴
    $adapter_red->doMouthOpen();
    //闭嘴
    $adapter_red->doMouthClose();
    echo "给狗套上绿枣适配器\n";
    $adapter_green = new GreenAdapter($adaptee_dog);
    //张嘴
    $adapter_green->operateMouth(1);
    //闭嘴
    $adapter_green->operateMouth(0);
    }
    }

    $test = new testDriver();
    $test->run();
    注册器模式(注册模式,注册树模式)

    已经创建好的这个对象,直接去取这个对象,这个就是注册器模式。

    实现
    首先我们需要一个作为注册树的类,这毋庸置疑。所有的对象“插入”到注册树上。这个注册树应该由一个静态变量来充当。而且这个注册树应该是一个二维数组。这个类应该有一个插入对象实例的方法(set()),当让相对应的就应该有一个撤销对象实例的方法(_unset())。当然最重要的是还需要有一个读取对象的方法(get())。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <?php
    class Register
    {
    static protected $objects;//全局树 array

    //设置
    static function set($alias,$object)
    {
    self::$objects[$alias] = $object;
    }
    //获得
    static function get($alias)
    {
    return self::$objects[$alias];
    }
    //注销
    static function _unset($alias)
    {
    unset(self::$objects[$alias]);
    }
    }

    Register::set('conf',array('dbhost'=>'127.0.0.1'));
    ?>