zoukankan      html  css  js  c++  java
  • php设计模式

    1.控制反转(IOC)

     使用IOC的:

    优点:消除对象之间的耦合关系,提高代码的灵活性,从而加快开发速度,提升代码质量

    缺点:在真实框架中,由于会使用反射机制,会降低代码的运行速度,如果对速度很敏感,就不适合使用IOC了.

     以下是我整理的注释加强印象加深版代码,其中的bind其实就是工厂模式的一种体现

    <?php
    class Superman{
        function __construct($skill){
            //print_r($skill);
        }
    }
    class XPower{
        function __construct(){
            //echo __CLASS__.PHP_EOL;
        }
    }
    
    class Container
    {
        protected $binds;
     
        protected $instances;
     
        public function bind($abstract, $concrete)
        {
            if ($concrete instanceof Closure) {
                $this->binds[$abstract] = $concrete;
            } else {
                $this->instances[$abstract] = $concrete;
            }
        }
         //make方法其实是传入参数,调用已经绑定的闭包/方法,为什么使用call_user_func_array?因为参数个数未知,使用call_user_func_array会更灵活
        public function make($abstract, $parameters = [])
        {
            if (isset($this->instances[$abstract])) {
                return $this->instances[$abstract];
            }
     
            array_unshift($parameters, $this);//必须有一个container参数,因为很有可能在make时使用container
            return call_user_func_array($this->binds[$abstract], $parameters);
        }
    }
    
    // 创建一个容器(后面称作超级工厂)
    $container = new Container;
     
    // 向该 超级工厂 添加 超人 的生产脚本(告诉容器待会如何生产对象)
    $container->bind('superman', function($container, $moduleName) {
        return new Superman($container->make($moduleName));
    });
     
    // 向该 超级工厂 添加 超能力模组 的生产脚本(告诉容器待会如何生产对象)
    $container->bind('xpower', function($container) {
        return new XPower;
    });
     
    
     
    // ******************  华丽丽的分割线  **********************
    // 开始启动生产
    $superman_1 = $container->make('superman', ['xpower']);//生产对象,用的是刚刚绑定的方法

     2.单例模式

    在整个应用生命周期内,对某个类,只实例化一次,应用场景为:连接数据库,记录日志,使用单例模式可以避免不必要的资源消耗

    <?php
    class Singleton{
        private static $obj=null;
        private function __construct(){}
      private function __clone(){}
      
      
    
        static function getInstance(){
            if(!self::$obj){
                self::$obj=new self;
            }
            return self::$obj;
        }
    }
    $res=Singleton::getInstance();
    $res2=Singleton::getInstance();
    $res3=Singleton::getInstance();
    var_dump($res);
    var_dump($res2);
    var_dump($res3);

     3.工厂模式

    工厂模式用于生产对象,在最原始的代码中,如果一个对象obj1需要另一个对象obj2,通常是在obj1内部new一个obj2,但是这种硬性的编码很不灵活,比如因需求改变,要使用另一个和obj2功能类似的obj3,或者obj2修改了类名,这样会使代码改动很大

    使用工厂模式,可以让obj1只使用工厂Factory得到对象obj2,obj3,obj4...

    工厂模式解除了obj1与obj2的耦合关系,使代码便于修改.实现了低耦合.

    在上面例1中IOC容器的binds属性,其实就是工厂模式的体现.通过对ioc容器对象bind方法的调用,得到了许多小车间(new各种类的闭包函数),车间装载完毕,在使用make方法时就会根据参数使用相应车间..

    4.观察者模式

     将触发事件(发布者)与发生事件后需要执行的动作(订阅者需要做的动作)解耦

    目的:代码更灵活,大大提升可维护性

    <?php
    /**
     * Created by PhpStorm.
     * User: zhudong
     * Date: 16/8/11
     * Time: 下午4:02
     */
    class Newspaper implements SplSubject {
        private $name;
        private $observers;
        private $content;
        public function __construct($name){
            $this->$name = $name;
            $this->observers = new SplObjectStorage();
        }
        public function attach(SplObserver $observer){
            $this->observers->attach($observer);
        }
        public function detach(SplObserver $observer){
            $this->observers->detach($observer);
        }
        public function notify(){
            foreach ($this->observers as $observer) {
                $observer->update($this);
            }
        }
        public function getContent(){
            return $this->content."{$this->name}";
        }
        public function breakOutNews($content) {
            $this->content = $content;
            $this->notify();
        }
    }
    
    
    
    //不同的观察者,对新闻做出不同的反应,此处举例Reader和Reader2
    class Reader implements SplObserver {
        private $name;
        public function __construct($name){
            $this->name = $name;
        }
        public function update(SplSubject $subject) {
            echo $this->name.' received breakout news'.$subject->getContent().'and say 不错~~'.PHP_EOL;
        }
    }
    
    class Reader2 implements SplObserver {
        private $name;
        public function __construct($name){
            $this->name = $name;
        }
        public function update(SplSubject $subject) {
            echo $this->name.' received breakout news'.$subject->getContent().'and say 垃圾!'.PHP_EOL;
        }
    }
    
    
    
    $newspaper = new Newspaper('齐鲁晚报');
    $allen = new Reader("allen");
    $jimmy = new Reader("mike");
    $tom = new Reader2("tom");
    $jerry = new Reader2("jerry");
    $newspaper->attach($allen);
    $newspaper->attach($jimmy);
    $newspaper->attach($tom);
    $newspaper->attach($jerry);
    $newspaper->detach($jerry);
    
    $newspaper->breakOutNews('本报讯...');
            

     参考资料

    对依赖注入和控制反转的说明文

    laravel 学习笔记 —— 神奇的服务容器

    实际开发中哪些场景需要用到观察者模式?

    php常见三种设计模式

  • 相关阅读:
    kafka集群管理
    kafka server管理
    kafka 日志结构
    kafka消费者基本操作
    kafka 生产者基本操作
    kafka主题管理
    kafka基础知识
    centos7.0安装docker-18.06.1-ce不能启动问题
    spec 文件详解
    rpmbuild 源码打包clickhouse,附带打好的rpm包下载地址
  • 原文地址:https://www.cnblogs.com/ch459742906/p/8023532.html
Copyright © 2011-2022 走看看