zoukankan      html  css  js  c++  java
  • [设计模式]之依赖倒置

    摘要

    首先提及下面向对象的四个好处
    ①可维护
    ②可扩展
    ③可复用
    ④灵活性好
    可以把PC电脑理解成为一个大的软件系统,CPU、内存、硬盘、显卡等都可以理解为程序中封装好的类或者程序集,由于PC易插拔式,不管哪一个出问题,都可以在不影响别的部件的前提下进行修改或替换。
    这种关系在面向对象中叫强内聚、松耦合。
    在PC的世界里像CPU这种内聚力非常强的东东,只有AMD和Intel2大厂家,因为其核心的东西别人看不到,但它又独自成为产品,在电脑主板上插上就可以使用,这就是接口的最大好处,CPU只需要把接口定义好,而主板只需要预留与CPU针脚的插槽即可。
    强内聚:像CPU一样,别的厂商木有办法制造,因为看不见其内部。
    松耦合:像CPU的针脚与对应的主板插槽,坏了任何一个我们可以再换。
    PC内存不够只要插槽足够就可以添加,硬盘不够我们可以使用移动硬盘,但是扩展是有限的,软件系统设计的好则可以无限扩展。
    依赖倒转原则

    依赖倒转原则:
    A:高层模块不应该依赖底层模块。两个都应该依赖抽象。
    B:抽象不依赖细节,细节应该依赖抽象。
    模块间的依赖是通过抽象发生的,实现累之间不发生直接的关系,其依赖关系是通过接口或者抽象类发生的。
    接口和抽象类不依赖于实现类,实现类依赖于接口或者抽像类
    更加精简的定义就是“面向接口编程”--OOD的精髓之一。

        在项目开发中为了使常用代码可以重复使用,我们一般会把这些代码写成许许多多函数的程序库,比如访问数据的代码一般会封装成模块,每次建新项目就去调用这些函数。
    但是问题是,需要做新项目,发现业务逻辑的高层模块都是一样的,但客户用不同的数据库或存储信息方式,我们需要再次利用这些高层模块,但是高层模块与低层的访问数据库都绑定到一起了,没有办法复用这些高层模块,这就非常糟糕了。这就需要在设计时采用依赖倒转原则,不管是高层模块还是低层模块,都依赖于抽象,具体一点就是接口或抽象类,只要接口稳定那么任何一个更改都不用的担心其他受到影响,无论高层还是低层模块都可以很容易被复用,这才是最好的办法。

    下面通过一个例子来体现依赖倒转原则可以减少类之间的耦合性,提高系统的稳定性,减少并行开发引起的危险,提高代码的可读性和维护性。
    现在有车族越来越多,就通过张三开奔驰车来举例:首先我们可以通过2个类来描述2个对象如下图所示

    奔驰车可以提供一个方法run代表车辆运行
      public class Driver {
      //司机的主要职责就是驾驶汽车
      public void drive(Benz benz){
      benz.run();
      }
    }
    public class Benz {
        //汽车肯定会跑
        public void run(){  
        System.out.println("奔驰汽车开始运行...");  
        } 
    }
    Client场景展现张三开奔驰车
    public class Client {  
    public static void main(String[] args) {   
    Driver zhangSan = new Driver();  
    Benz benz = new Benz();  
    //张三开奔驰车  
    zhangSan.drive(benz);
    } }  
    目前为止张三开奔驰是没有问题的,假使业务需求变更让张三也会开宝马车,好咱们在建一个BMW的类然后在张三类里添加一方法,业务需求永无休止,难道就这样永无止境的改来改去
    所以依赖倒置原则闪亮登场,建立2个接口IDriver和ICar分别定义汽车和司机的各个职责,如下图所示

    public interface IDriver {
    //是司机就应该会驾驶汽车
    public void drive(ICar car);  
    }
    public interface ICar {
    //是汽车就应该能跑
    public void run();
    }
    public class Benz:ICar{  
    //汽车肯定会跑 
    public void run(){ 
    System.out.println("奔驰汽车开始运行...");
    }
    public class BMW:ICar{ 
    //宝马车当然也可以开动了 
    public void run(){
    System.out.println("宝马汽车开始运行...");
    }

    public class Client {   
    public static void main(String[] args) {  
    IDriver zhangSan = new Driver(); 
    ICar bmw = new BMW();
    //张三开奔驰车
    zhangSan.drive(bmw);
    }  
    }
    项目中实践几条规则

    1.每个类尽量有接口或者抽象类,或者抽象类和接口都具备。
    ——这是依赖倒置的基本要求,接口和抽象类都是抽象,有了抽象才能依赖倒置。
    2.变量的显示类型尽量是接口或者抽象类。
    3.任何类都不应从具体类派生。
    ——在项目初期写架子的时候适用此规则,这不是绝对的,很多项目维护扩展功能时可以不考虑去继承最高类。
    4.尽量不要覆写基类的方法
    ——如果基类是抽象类,而且这个方法已经实现了,子类尽量不要覆写,类间依赖是抽象的,覆写了抽象方法会对性能产生一定影响。
    5.结合里氏替换原则
    里氏代换原则:子类型必须能够替换掉它们的父类型。
    意思是说只有当子类可以替换掉父类,软件单位的功能不受影响,父类才能被真正复用,而子类也能够在父类的基础上扩展新的行为。
    我们可以得出一个通俗的规则:接口负责写public属性和方法,并且声明和其他对象的依赖关系,抽象类负责公共累构造的实现,实现类准确实现业务逻辑,同时适当的对父类进行细化。
    为什么叫依赖倒置:人们正常的思维要实现开奔驰车就得依赖奔驰车,要想使用笔记本就必须依赖笔记本,然而编程是对现实事物的抽象,抽象的结果就产生了接口和抽象类,进而产生了抽象间的依赖,代替了人们传统思维间事物的依赖,所以“倒置”就产生了。


  • 相关阅读:
    在 Linux 下搭建 Git 服务器***
    使用 SVN Hook 实现服务器端代码自动更新
    git服务器的建立
    Oracle 11gR2 RAC集群服务启动与关闭总结
    Cluster的日记体系
    DB time VS. DB CPU
    oracle 内存分配和调优 总结
    利用logminer恢复delete误删除操作的数据
    大话RAC介质恢复---联机日志损坏
    ORACLE联机日志文件丢失或损坏的处理方法(转)
  • 原文地址:https://www.cnblogs.com/hailiang2013/p/2846415.html
Copyright © 2011-2022 走看看