zoukankan      html  css  js  c++  java
  • php---依赖倒转(反转控制)原则

    一、简介

      依赖注入和控制反转说的实际上是同一个东西,它们是一种设计模式,这种设计模式用来减少程序间的耦合

      优点:使用依赖注入,最重要的一点好处就是有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活

      依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高。而依赖倒置原则的思想是,上层不应该依赖下层,应依赖接口。意为上层代码定义接口,下层代码实现该接口,从而使得下层依赖于上层接口,降低耦合度,提高系统弹性

    二、问题

      具有紧耦合关系的代码,往往迁一发而动全身。例如:

    <?php
    // dog 类
    class dog {
        public function eat(){
            echo '骨头';
        }
        public function speak(){
            echo '旺旺';
        }
    }
    //cat 类
    class cat {
        public function eat(){
            echo '鱼';
        }
        public function speak(){
            echo '喵喵';
        }
    }
    
    // BeastTraining 类
    class BeastTraining{
        private $animal;
        public function __construct($animal){
            if ($animal == 'dog'){
                $this->animal = new dog();
            } else {
                $this->animal = new cat();
            }
        }
        public function eat(){
            $this->animal->eat();
        }
        public function speak(){
            $this->animal->speak();
        }
    }
    
    $animal = new BeastTraining('dog');
    $animal->eat();

        上面的 BeastTraining 类与 dog 类 和 cat 类存在着紧耦合的关系,一旦dog类和cat 需要修改了eat方法,那么 BeastTraining 类也就要做相应的调整。或者又添加一个与cat 类相似的类,那此时有该怎么办呢?

    三、解决方案

      以上的问题在于高层的代码(BeastTraining)依赖于底层的代码(dog 类或cat类),不利于代码的复用。如何减少对底层代码的依赖?解决方案:

    <?php
    interface animal{                    # 定义好接口
        public function eat();
        public function speak();
    }
    
    // dog 类
    class dog implements animal {             # 实现接口类的 所有方法
        public function eat(){
            echo '骨头';
        }
        public function speak(){
            echo '旺旺';
        }
    }
    //cat 类
    class cat implements animal{              # 实现接口的所有方法
        public function eat(){
            echo '鱼';
        }
        public function speak(){
            echo '喵喵';
        }
    }
    
    // BeastTraining 类
    class BeastTraining{
        private $animal;
        public function __construct(animal $animal){      # 传输实现接口的类
            $this->animal = $animal;
        }
        public function eat(){
            $this->animal->eat();
        }
        public function speak(){
            $this->animal->speak();
        }
    }
    
    
    $animal = new BeastTraining(new cat());
    $animal->eat();

     或者

    <?php
    abstract class animal{
        protected $status = 0;
        public function get_status()
        {
            echo $this->status;
        }
        abstract public function eat();
        abstract public function speak();
    }
    
    // dog 类
    class dog extends animal {
        public $status=1;
        public function eat(){
            echo '骨头';
        }
        public function speak(){
            echo '旺旺';
        }
    }
    //cat 类
    class cat extends animal{
        public $status=1;
        public function eat(){
            echo '鱼';
        }
        public function speak(){
            echo '喵喵';
        }
    }
    
    // BeastTraining 类
    class BeastTraining{
        private $animal;
        public function __construct(animal $animal){
            $this->animal = $animal;
        }
        public function eat(){
            $this->animal->eat();
        }
        public function speak(){
            $this->animal->speak();
        }
        public function get_status(){
            $this->animal->get_status();    
        }
    }
    
    $animal = new BeastTraining(new cat());
    $animal->eat();
    $animal->get_status();

      上面两个代码案例其实是一样的,都解决了高层代码(BeastTrainnig 类)对底层代码(dog ,cat类)的依赖。通过对接口的定义。使底层代码符合接口规范,而高层代码又无需了解底层代码的实现过程。实现了高层代码与底层代码的解耦。

    四、图解

      

    五、总结

      1、高层模块不应该依赖于底层模块,两个都应该依赖于抽象

      2、抽象不应该依赖于细节,细节应该依赖于抽象

    不足之处,请多多指教。

  • 相关阅读:
    PHP教程:PHPUnit学习笔记(三)测试方法进阶
    PHP教程:PHPUnit学习笔记(二)PHPUnit基本用法
    PHP教程:PHPUnit学习笔记(一)PHPUnit介绍及安装
    phpunit框架安装
    防注入(url)
    ssh 密钥详解
    JS判断登陆端是PC还是手机
    字节换算器
    gif 图片制作和拆解
    让你的网站秒开 为IIS启用“内容过期”
  • 原文地址:https://www.cnblogs.com/xiaobaiskill/p/8649310.html
Copyright © 2011-2022 走看看