设计模式的一些小整理

?设计模式

设计模式概述

    设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
    模式的经典定义:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的解决方案,无需再重复相同的工作。即模式是在特定环境中解决问题的一种方案 
    现在有两派,有的人建议使用设计模式,有的人不建议使用设计模式!

解决代码的耦合度
耦合度越低越好
高内聚低耦合(对内要高内聚,对外要低耦合)
设计模式不分语言。php是世界上最优美的语言

1 单例模式

这个类只能创建一个对象

php的应用主要在于数据库的应用,一个应用会出现大量的数据库操作,使用单例模式,可以避免大量的操作消耗的资源

步骤:

  1. 构造函数需要标记为private
  2. 保存类实例的静态成员变量
  3. 获取实例的公共的静态方法

    class Dog
    {
    //设置一个静态的成员属性来保存单例对象
    static private $instance;
    //将构造函数私有化
    private function getInstance()
    {
    if(self::$instance){
    self::$instances = new self();
    }
    return self::$instance;
    }

    }
    //调用的时候就调用这个函数
    $dog1 = Dog::getInstance();
    $dog2 = Dog::getInstance();
    if ($dog1 === $dog2) {
    echo '这是同一条狗
    ';
    } else {
    echo '这不是同一条狗
    ';
    }

2 简单工厂、标准工厂

    接口中定义一些方法
    实现接口的类实现这些方法
    工厂类:用以实例化对象
    优点:为系统结构提供了灵活的动态扩展机制。方便维护
    步骤
        1、根据类调用一个静态方法,传递一个你想要创造什么样对象的额参数
            就可以获得这个类
        2、有一个接口
        3、各个类型实现这些接口

/***************简单工厂模式***********************/
        interface Skill
        {
            function family();
            function buy();
        }

        class Human implements Skill
        {
            function family()
            {
                echo '人族在辛辛苦苦的伐木累<br />';
            }
            function buy()
            {
                echo '人族买了一个国王祭坛<br />';
            }
        }
        class JingLing implements Skill
        {
            function family()
            {
                echo '精灵族在绕树转圈,吸取大树的日月精华<br />';
            }
            function buy()
            {
                echo '精灵族买了一个战争古树<br />';
            }
        }

        class Animal implements Skill
        {
            function family()
            {
                echo '兽族在卯足了劲与树对干<br />';
            }
            function buy()
            {
                echo '兽族买了一个灵族祭坛<br />';
            }
        }
        class NoDie implements Skill
        {
            function family()
            {
                echo '不死族在大口大口的吃树<br />';
            }
            function buy()
            {
                echo '不死族买了一个墓地<br />';
            }
        }
        #根据你给的类型switch出你要new的对象
        class Factory
        {
            static function makeHero($type)
            {
                switch ($type) {
                    case 'humans':
                        return new human();
                        break;
                    case 'jingling':
                        return new JingLing();
                        break;
                    case 'animal':
                        return new Animal();
                        break;
                    case 'nodie':
                        return new NoDie();
                        break;
                }

            }
        }
        #调用的时候是调用工厂里面的静态函数 
        $human = Factory::makeHero('animal');
        echo $human->family();

3 工厂模式

工厂方法模式核心是工厂类不再负责所有对象的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,它仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节

    1:首先给工厂一个接口标准   
    2:然后各种类型去继承这些接口
    3:然后又一个工厂接口,静态的方法
    4:各个工厂自己去实现自己的接口来创造手机
    5:最终想要什么类型的,就用该类型自己的工厂去调用静态函数去实现

interface Tell
{
    function call();
    function recieve();
}
class xiaoMi implements Tell
{
  function call()
   {
     echo '我在用小米手机打电话'.'<br/>';
   }
  function recieve()
  {
    echo '我在用小米手机接电话'.'<br/>';
  }
}
class meiZu implements Tell
{
  function call()
   {
     echo '我在用meiZu手机打电话'.'<br/>';
   }
  function recieve()
  {
    echo '我在用meiZu手机接电话'.'<br/>';
  }
}
/***********************************************/
interface Factory
{
  static function makePhone();
}
class xiaomiFactory implements Factory
{
    function makePhone()
      {
        return new xiaoMi();
      }
}
class meizuFactory implements Factory
{
    function makePhone()
      {
        return new meiZu();
      }
}
/******************************************/
$phone = meizuFactory::makePhone();
echo $phone->recieve();

4 观察者模式

涉及到两个类:

        @-@一个是被观察者
            1、添加观察者
            2、删除观察者
            3、发送通知
        @-@一个是观察者
            1、做出反应即可
在php中:用户注册(收到邮件,收到短信,或者收到其他信息)
    它是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;
    观察者模式提供了避免组件之间紧密耦合的另一种方法。
   

官方接口

            SplSubject
                attach  添加观察者
                detach  删除观察者
                notify  通知
            SplOberser
                update  做出响应

/**************被观察者*****************************/
class SuperBoy
    {
        #我可以有自己的观察者,放在数组里
        public $observers = [];
        #添加观察者的时候会传进来一个人是对象,然后把这个人放在数组里
        function addObserver($observer)
        {
            $this->observers[] = $observer;
        }
        #删除观察者的时候也是找到传入的这个人的键删掉
        function deleteObserver($observer)
        {
            $key = array_search($observer,$this->observers);
            unset($this->observers[$key]);
        }
        // 有通知观察者的做法,也就是让观察者做出反应
        function notice()
        {
            foreach ($this->observers as $observer) 
            {
                // 让这些对象分别去调用做出反应的方法
                foreach ($this->observers as $observer) {
                    $observer->findYou();
                }
            }
        }
        function kf()
        {
            $this->notice();
        }

    }
    // 观察者只需要做出反应即可
    class Girl
    {
        function findYou()
        {
            echo '老娘就知道你在外面不老实,我哪里不如她<br />';
        }
    }
/************************************************/
    $hututu = new Girl();
    $huchunchun = new Girl();
    $lihui = new Girl();

    $obj = new SuperBoy();

    $obj->addObserver($hututu);
    $obj->addObserver($huchunchun);
    $obj->addObserver($lihui);
    $obj->kf();

5 适配器模式

生活中就有很多适配器 电源适配器 就是里面的变压器 220v

    可将一个类的接口转换成客户希望的另外一个接口,使得原本不兼容的接口能够一起工作。通俗的理解就是将不同接口适配成统一的接口
    1:当一个类实现外面的接口的时候,会通过传递一个对象,调用这个对象的方法
    2:在接口函数里面调用对象的方法

interface SuperMan
{
  function cook();
  function writePhp();
}
class Mans
{
    function cook()
    {
        echo __CLASS__ . '<br/>';
        echo "我会做宫保鸡丁";
    }
}
/***************这里是核心******************/
class CodeMonkey implements SuperMan
    {
        public $Man;
        function __construct($Man)
        {
            $this->Man = $Man;
        }
        function cook ()
        {
            $this->Man->cook();
        }
        function writePhp()
        {
            echo '我不仅会写php代码,我还会java、oc、c++、c#、c、go、js<br />';
        }
    }

    $xiaohuihui = new Mans();
    $xiang = new CodeMonkey($xiaohuihui);
    $xiang->cook();
    $xiang->writePhp();

6 策略模式

    (1)多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
    (2)需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
    (3)对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
    (4)客户端必须知道所有的策略类,并自行决定使用哪一个策略类,策略模式只适用于客户端知道所有的算法或行为的情况。
    (5)策略模式造成很多的策略类,每个具体策略类都会产生一个新类。
    优点:
        1、策略模式提供了管理相关的算法族的办法
        2、算法封闭在独立的Strategy类中使得你可以独立于其Context改变它
        3、使用策略模式可以避免使用多重条件转移语句

7 门面模式

    优点
        1、它对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便
        2、实现了子系统与客户之间的松耦合关系
        3、如果应用需要,它并不限制它们使用子系统类。因此可以在系统易用性与能用性之间加以选择
    适用场景
        1、为一些复杂的子系统提供一组接口
        2、提高子系统的独立性
        3、在层次化结构中,可以使用门面模式定义系统的每一层的接口

interface JiPai
{
  function want();
  function cook();
}
class XXJipai
{
    function naoyou()
    {
        echo '脑油味鸡排<br />';
    }
    function biti()
    {
        echo '鼻涕味鸡排<br />';
    }
}
class People implements JiPai
 {
        public $XXJipai;
        function __construct()
        {
            $this->XXJipai = new XXJipai(); 
        }
        function want()
        {
            $this->XXJipai->naoyou();
        }
        function cook()
        {
            $this->XXJipai->biti();
        }
 }

$test = new People();
$test->want();
$test->cook();

门面模式就是给你两个方法当门:这两个方法里面有你要执行的操作,于是你只需要调用这个门方法就可以了

门方法里面的函数是用对象调用的,对象是里面的成员属性

8 DI依赖注入

(Ioc反转控制)(Dependency Injection)

    说白了就是传递一个参数进来,只不过这个参数是强制类型
    这样就不好了,所有的全部固定了。

interface Roller
{
    function roll();
}

class MiQiLin implements Roller
{
    function roll()
    {
        echo '米其林轮胎在滚动<br />';
    }
}

class BeiNaiLi implements Roller
{
    function roll()
    {
        echo '倍耐力轮胎在滚动<br />';
    }
}
/*********************************************/
interface Runner
{
    function run();
}
class HongGuang implements Runner
{
    private $tai;
    function __construct(Roller $tai)
    {
        $this->tai = $tai;
    }
    function run()
    {
        $this->tai->roll();
        echo '神车五菱宏光在高速公路上和宝马飙车<br />';
    }
}
class BMW implements Runner
{
    private $tai;
    function __construct(Roller $tai)
    {
        $this->tai = $tai;
    }
    function run()
    {
        $this->tai->roll();
        echo '宝马在高速公路上飙车<br />';
    }
}
/*****************************************/
class Xiang
{
    private $car;
    function __construct(Runner $car)
    {
        $this->car = $car;
    }
    function travel()
    {
        $this->car->run();
        echo '我带着别人的媳妇私奔了<br />';
    }
}
//$tai = new MiQiLin();
//$tai = new BeiNaiLi();
//$car = new BMW($tai);
//$car = new HongGuang($tai);
$xiang = new Xiang(new BMW(new MiQiLin()));
$xiang->travel();

9 容器

容器:在我们的依赖注入里面需要注入大量的对象实例,然后呢,总不能全部实例化好吧,所以呢,这个时候,我们需要一个容器把这些实例放到里面,需要用的时候取出来

class Container
{
    static public $things = [];
    //往容器里面放东西
    static public function bind($name, Closure $method)     //限定类型为匿名函数
    {   
        if(!isset(self::$things[$name]))
        {
            self::$things[$name] = $method; //这里绑定匿名函数是不执行的亲
        }
    }
    //在容器里面取出来用
    static public function make($name)
    {
        if(isset(self::$things[$name]))
        {
            $func = self::$things[$name];
            $func();
        }
    }
}
Container::bind('jinLong', function(){
    echo '你看我是两条金龙鱼<br>';
});
Container::bind('xiaojie', function(){
    echo '我要吃了哪条金龙鱼<br>';
});
Container::make('jinLong');
Container::make('xiaojie');

10 反射

主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义

通过反射机制访问对象的属性,方法,构造方法等

<?php
/**
 * 你看我是一个注释
 * @author 
 * @concat 3wfindme@gmail.com
 */
class XiaoJie
{
    public $name = 'xiaojiejie';

    /**
     * 这是一个方法的注释
     * @param $where string
     * @param $how string
     */
    public function zuo($where, $how)
    {
        echo '小杰想做于是乎他就做了。。。';
    }

    public function shui()
    {
        echo '小杰说做累了就呼呼睡觉<br>';
    }
}
// $reflection = new ReflectionClass('XiaoJie');
// $method = $reflection->getMethods();
// $doc = $reflection->getDocComment();
// var_dump($reflection->getMethod('zuo'));
// var_dump($doc);
// var_dump($method);
// var_dump($reflection);
$r = new ReflectionMethod(new XiaoJie(), 'zuo');
var_dump($r->getParameters());
var_dump($r->getDocComment());

转载于:https://www.cnblogs.com/backkomjiu/p/7134372.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值