zoukankan      html  css  js  c++  java
  • 融会贯通——深入了解面向对象设计原则“依赖倒转原则”

    一千个人眼里有一千个哈姆雷特,下面我尝试用深入浅出的语言贯穿到“控制反转”,“依赖注入”,“面向抽象编程”,以及“面向接口编程”这几个概念。

     

    传递参数,关联(组合&聚合)关系时,要尽量引用高层次的抽象类,使用基类和接口进行变量类型的声明,参数类型的声明,数据类型转换(也是向高层次的抽象类转),而不要用具体的子类。

    以上总结为“控制反转”,也叫“面向抽象编程”。

     

    真到了要使用具体子类的时候,采用“依赖注入”的方式:

    • 构造注入,通过构造函数传入具体类的对象
    • setter注入,通过setter方法传入具体类的对象
    • 接口注入,通过在接口中声明的业务方法,来传入具体类的对象作为方法的参数

      ——> 引申到“面向接口编程”的概念,接口的意思就是“如果你是***的话,你能干嘛?”,接口中定义的是能干嘛,具体怎么干不告诉你,等你是了(即实现该接口)自己去想具体怎么干。

    接口是抽象概念的一种,当你在面向抽象编程时,传递参数,关联关系,使用的是接口来声明变量类型,参数类型以及数据类型转换,而不是具体的类,这就是面向接口编程。

    所以,总结出这些概念的关系是,面向对象编程的中心思想是面向抽象编程,而面向接口编程是面向抽象编程的一种。

     

    那么问题又来了,如果面向接口编程只是面向抽象的一种,那么另一种是什么呢?

    另一种就是抽象基类,要注意区分这里的基类的概念,它包含abstract关键字的class,也包含普通父类(普通父类也是其众多子类的抽象化身),这里主要多说一下abstract class,它很容易与接口混淆,那么abstract class与接口的区别是什么?

    • abstract class可以包含有方法体的非抽象方法,可以包含任意作用域的成员数据。而接口一般不使用成员数据(即使有也是自动转为public static final类型),接口的所有方法都是没有方法体的抽象方法(接口内部不用abstract关键字)。
    • abstract class是对属性,行为的抽象,同时也可以有自己的具体方法。而接口只是对行为的抽象,接口更像是abstract class的特殊情况。
    • 这两种不同的抽象概念更好的支持了Java多态(一个基类可以有很多子类is-a,一个类可以实现很多接口like-a)。abstract class仍然是个类,必须是相同种族抽象出来的类,例如动物类,熊猫类,而接口只是对行为的抽象,不管谁实现他,也不管他们是否是一个种族,例如动物和汽车都可以跑,那他们都可以实现具有“跑”行为的接口,对于接口本身来讲,他并不关心你是动物还是汽车,他只管定义他的“跑”就行了。

     

    依赖倒转原则,总结一句话就是定义时用抽象类型(基类或者接口),运行时注入具体类型。

    开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段。

     

  • 相关阅读:
    DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践
    UVA10071 Back to High School Physics
    UVA10071 Back to High School Physics
    UVA10055 Hashmat the Brave Warrior
    UVA10055 Hashmat the Brave Warrior
    UVA458 The Decoder
    UVA458 The Decoder
    HDU2054 A == B ?
    HDU2054 A == B ?
    POJ3414 Pots
  • 原文地址:https://www.cnblogs.com/Evsward/p/DIP.html
Copyright © 2011-2022 走看看