首页 > 代码库 > 对设计原则【依赖倒置】的一些理解

对设计原则【依赖倒置】的一些理解

作为一名oop程序员,设计原则是必须知道的知识:单一职责,开闭原则,依赖倒置,接口隔离,替换法则。

在看【Head First】一书时,突然对依赖倒置有了一些简单的理解。

  先看依赖倒置的定义:要依赖抽象,不要依赖具体类。

    其意思是具体类要依赖抽象,抽象不应该依赖具体类,更扩展一点就是说具体类也尽量不要依赖具体类。

 

  首先,何为具体类,我的理解,具体类应该就是某个具体的对象,是对现实中的实物或其他的一种反应,即就是类的实例,具体代码上就是通过new出来的对象。

比如Object obj  = new Object();这样便产生了一个具体对象。而若是直接在一个对象中new另一个对象,则这两个对象依赖在了一起,增加了这个类的耦合性。

  让我们先回到依赖倒置上!这个倒是有点像面向接口编程,但是这里更强调的“抽象”,这种抽象可以是一个接口,也可以是一个抽象类。这个原则说明了:不能让

“高层组件”依赖“低层组件”,而且两者都应该依赖于抽象。

  我来举一个例子。如果我们要开一家奶茶店,那我们首先想到的是什么呢,肯定是想到在什么地方开奶茶店,要多少员工,然后才是卖什么奶茶。

  没错,我们的思考方法一般都是从顶端 开始,然后往下才是具体类。但是要开奶茶店又要想怎么生产奶茶,这是一件很要命的事情。对于一个奶茶店主来说,并不

想理会奶茶这写具体类,否则奶茶店将全部依赖这些奶茶具体类。这时候就要倒置我们的思想,先从低端开始,从奶茶开始,抽象出一个奶茶抽象。

  这时候“奶茶店”就是“高层组件”,各种奶茶就是“低层组件”。由于奶茶店是如果买奶茶的具体类,则奶茶店对全部奶茶有了依赖,高层组件与低层有了依赖关系。

  这个模式告诉我们:我们应该依赖抽象类,而不应该具体类,无论是高层组件还是低层组件都应该如此。

  那么我们就想到定义一个奶茶的抽象类型,即为所有的奶茶提供一个抽象,而奶茶店则只需要面对这个抽象,而不用去管这个抽象的具体类是什么。即奶茶店只需

要专注于卖奶茶,收钱找钱什么的,而不用管具体奶茶是什么。这样奶茶店就依赖于奶茶的抽象,而不是依赖奶茶的具体类。

  

class TeaShop{    public void sell(){                   Tea tea = new SimpleTea();                      tea.produce();   }}

          这样虽然我们创建了一个抽象,但我们 仍在代码中,实际的创建的具体类(SimpleTea),所以,这样的抽象并不能实现低耦合。

  这时候,可以使用工厂模式来对代码进行进一步重构,来创建一个TeaFactory;为了使这个工厂更具有扩展型,我们来对工厂进行抽象。

public class abstract TeaFactory{       public Tea makeTea(String type){        createTea(type).produce();     }    public abstract Tea  createTea(String tea);}

  这时候我们在郑州开了个奶茶店,则创建一个郑州奶茶工厂。

public class ZZTeaFactory extends TeaFacory{   public Tea createTea(String tea){        if(tea.equles("simple")){             return new SimpleTea();      }else{               return new OtherTea();         } } } 

  这样就实现了一个奶茶的工厂模式。那么通过奶茶店进行点选奶茶的时候:

  

class TeaShop{    public void sell(){         TeaFactory factory = new ZZTeaFactory();          Tea tea = factory.makeTea("simple");              }}

  我们通过工厂模式将奶茶店与奶茶进行解耦,而且通过工厂模式也大大提高了程序的可扩展型,比如我们如果要在洛阳也开一家奶茶店的话,但是洛阳奶茶店所卖的

奶茶与郑州的奶茶并不一样,这时候我们只要实现一个洛阳的奶茶工厂,实现奶茶工厂的抽象即可,实现了开闭原则。通过这种将实例化延迟到子类中进行的方式。

  在次回到依赖倒置上,为什么使用工厂模式就实现了依赖倒置了呢?

  首先我们画一下类图:

    

             这时候高层组件(TeaShop)和低层组件(SimpleTea,OtherTea)都依赖于Tea抽象。想要遵循依赖倒置原则,工厂方法并非是唯一的方法,但却是

最有效的方法。

  

  如何避免违反依赖倒置原则:

    1.变量不可以持有具体类的引用。(持有类的引用即通过new出来的对象)

    2.不要让类派生自具体类。(如果派生自具体类,就产生了依赖,请派生自一个抽象)

    3.不要覆盖基类中已实现的方法。

 

  但是如果随时都要遵循这个原则,是不可能的,因为我们如果不new一个对象,那么我们是什么都写不成的。所以这个原则也有适用行。如果有一个不像是会改变

 的类,则具体类一点问题都没有的。而常改变的 类则可以使用一些技巧。

  永远不变的是变化本身,我们使用设计原则,设计模式,则是为了更好的应对变化,封装变化。

 

  参考资料:《Head First 设计模式》

对设计原则【依赖倒置】的一些理解