类的设计趋向于:Use Case Diagram --> (derived) --> Detail
/* Software entities should be open for extension, but closed for modification */
反面例子:Dependency: 作为参数,作为局部变量,调用静态方法。
改进方式:增加抽象类或者接口,以及set方法。
[replace A with B 用B来代替A]
[substitute A for B 用A来代替B (或者A substitute for B)]
Derived Class 需严格成为 Base Class 的子类型。
首先针对基类编程,在具体实现或程序运行时再确定具体子类。 <-- 实现开闭原则的重要基础
除去set方法,也可采用读取配置文件来选择类的调用。<-- 实现开闭原则的重要手段
接口杜绝臃肿,以免空方法实现。
若 需使用一个类的方法,可以通过 继承 或者 聚合/组合。优先后者,降低耦合。
实例:DAO的实现
既然 getConnection() 可能会变化,那么其所在的类 不便成为基类(Base Class),
然后 采用 构造函数注入、setter方法注入 和 接口注入。从而注入不同的数据库。
Reference: http://www.360doc.com/content/11/0630/16/1265417_130603253.shtml
控制反转是一种将 组件依赖关系 的 创建和管理 置于程序外部的技术。
由容器控制程序之间的关系,而不是由代码直接控制。
由于控制权由代码转向了容器,所以称为反转。
Dependency Injection:两个对象之间的依赖关系在程序运行时由外部容器动态的注入依赖行为方式称为依赖注入 (DI) 。 DI 是 IOC 的一种形式。
依赖注入的三种实现类型:接口注入、 Setter注入和构造器注入。
接口注入
public class ClassA { private InterfaceB clzB; public void doSomething()
{ Ojbect obj = Class.forName(Config.BImplementation).newInstance(); clzB = (InterfaceB)obj; clzB.doIt() } …… }
set注入
public class ClassA { private InterfaceB clzB; public void setClzB(InterfaceB clzB) { this. clzB = clzB; } …… }
构造器注入
public class DIByConstructor { private final DataSource dataSource; public DIByConstructor(DataSource ds)
{ this.dataSource = ds; } …… }
???
/* 一个软件实体应当尽可能少地与其他实体发生相互作用 */
添加中间类来降低界面组件之间的耦合度.