• php解耦的三种境界


    我们有三个类,Db,FileSystem,Session;实际业务需求要组合操作这三个类.

    一.常规做法

    class Db
    {
        public function read($id)
        {
    
        }
    }
    
    class FileSystem
    {
        public function writeFile($file)
        {
    
        }
    }
    
    class Session
    {
        public function setSession($sessionName)
        {
    
        }
    }
    
    // 实际逻辑
    class Logic
    {
        protected $db;
        protected $file;
        protected $session;
    
        public function __construct()
        {
            $this->db = new Db();
            $this->file = new FileSystem();
            $this->session = new Session();
        }
    
        public function handle($id)
        {
            if ($name = $this->db->read($id)) {
                $this->file->writeFile(md5($name) . '.txt');
                $this->session->setSession($id);
            }
        }
    }
    
    $id = 11;
    $client = new Logic();
    $client->handle($id);
    

      

    缺点:
    Logic内部高度耦合了,Db,FileSystem,Session
    如果这三个类的初始化条件变化,则需要修改Logic的构造方法.

    二.参数依赖(类型提示,将新建关联类的放入调用处)

    修改Logic代码如下:

    class Logic
    {
        protected $db;
        protected $file;
        protected $session;
    
        public function __construct(Db $db, FileSystem $file, Session $session)
        {
            $this->db = $db;
            $this->file = $file;
            $this->session = $session;
        }
    
        public function handle($id)
        {
            if ($name = $this->db->read($id)) {
                $this->file->writeFile(md5($name) . '.txt');
                $this->session->setSession($id);
            }
        }
    }
    
    $id = 11;
    $db = new Db();
    $file = new FileSystem();
    $session = new Session();
    $client = new Logic($db, $file, $session);
    $client->handle($id);
    

      

    优点:
    实现了解耦

    缺点:
    业务变动,如果要更改Db类到MySql类或初始化条件变动,代码依然要改动.

    ps:大部分的设计模式使用了该解耦方法.

    三.容器

    1.希望DB类,Session类,FileSystem类“拿来即用”,不用每次繁琐的初始化,比如写$db=new DB(arg1,arg2);这类语句。
    2.希望DB等类型的对象是“全局”,在整个程序运行期间,随时可以调用。
    3.调用DB等类型的程序员不用知道这个类太多的细节,甚至可以用一个字符串的别名来创建这样一个对象。

    能够实现以上目标的就是IOC容器,可以把IOC容器简单的看成一个全局变量,并用关联数组把字符串和构造函数做绑定

    // 容器
    class Container
    {
        public $binds = array();
    
        public function bind($abstract, $concreate)
        {
            $this->binds[$abstract] = $concreate;
        }
    
        public function make($abstract, $params = [])
        {
            return call_user_func_array($this->binds[$abstract], $params);
        }
    }
    
    
    // 绑定或注册
    $container = new Container();
    $container->bind('db', function () {
        return new Db();
    });
    $container->bind('file', function () {
        return new FileSystem();
    });
    $container->bind('session', function () {
        return new Session();
    });
    
    
    
    // 实际逻辑,容器依赖
    class Logic
    {
        protected $db;
        protected $file;
        protected $session;
    
        public function __construct(Container $container)
        {
            $this->db = $container->make('db');
            $this->file = $container->make('file');
            $this->session = $container->make('session');
        }
    
        public function handle($id)
        {
            if ($name = $this->db->read($id)) {
                $this->file->writeFile(md5($name) . '.txt');
                $this->session->setSession($id);
            }
        }
    }
    
    $id = 11;
    $logic = new Logic($container);
    $logic->handle($id);
    

      

    本文参考自:https://www.cnblogs.com/sweng/p/6430374.html

  • 相关阅读:
    记一次ntp反射放大ddos攻击
    除了binlog2sql工具外,使用python脚本闪回数据(数据库误操作)
    vmware linux虚拟机忘记密码怎么办
    flask(二)
    flask(一)
    发布一个Django项目
    nginx的使用
    redis的下载及使用
    Linux虚拟机没有IP的解决办法
    Mariadb的安装与使用
  • 原文地址:https://www.cnblogs.com/itfenqing/p/7819500.html
Copyright © 2020-2023  润新知