天外有天,人外有人。
分类: C/C++
2013-09-29 23:05:16
一个类的职责单一从而实现高内聚低耦合。相反,如果一个类实现了多个功能,功能间耦合度高,将来修改其中一个职责可能会影响其他的职责。同样也适用于函数的设计。
难点:很难把握职责划分的粒度。
All member variables should be private; global variable should be avoided; using run time type identification(RTTI) is dangerous.
软件应该对扩展开放,对修改关闭。对现有代码的修改可能会影响到对改动代码的一连串依赖,从而引起一系列的潜在问题,所以需要对修改关闭。对扩展开放不需要修改现有实现,不会影响到既有功能,通过扩展实现代码重用。
实现关闭方法:
1. 尽可能使用private封装成员变量;
2. 用使用全局变量。即使用的话可通知ApplicationContext这样的类来封装。
3. 禁止使用RTTI。如:dynamic_cast.
4. 不会修改的函数或参数使用const, const_iterator等。
实现开放方法:
1. 引入接口类。不直接使用具体类指针。
1988年由MIT的Barbara Liskov提出。
子类尽量不重写父类的方法,也不重载父类的方法,这样在所有使用父类的地方都可透明地使用子类,其功能不会发生改变。即:子类可扩展父类的功能,但不能更改父类原来的功能。
方法:
1. 子类可实现自己特有的方法。
2. 子类实现父类的接口。
3. 子类不能hide父类已实现的方法。
4. 使用抽象基类,由子类实现其接口。
Client应该不依赖于其不需要的接口。
方法:将多功能接口拆解,各类使用其依赖的于功能单一的接口。
臃肿的接口设计:
采用接口依赖原则refactor后的设计:
高层模块不应该依赖低层模块,都应该依赖于抽象,抽象不能依赖于细节,细节需依赖于抽象。
实现方法,类不依赖于其他具体类,只依赖该具体类的抽象基类,这样其他类似的具体类的加入不需要修改现有类的实现。
实现(居然跟Struts+Spring+Hibernate的依赖注入(DI, Dependence Injection)一样):
1. set_XXX(IProduct product)方法实现
2. constructor(IProduct product)构造函数实现
3. func(IProduct product)接口方法实现
实例:User是高层模块,实现业务逻辑。
依赖具体类的一个设计,加入新的ProductB需要修改User的实现,对修改不关闭。
依赖具体接口,加入新的ProductB不需要修改User的实现,实现对扩展开放:
又叫最少知道原则(Least Knowledge Principle), 一个类尽可能少地与其他类交互,尽可能少地知道其他类。
实现方法:
采用中介来减少类之间相互知晓。Mediator和Fa?ade模式是LOD的具体应用。