2005年2月15日星期二

《ASD》:Principles

Agile Software Development是一本很棒的书,主要是因为作者是Robert C.Martin。当年我在ObjectMentor的网站上,读Robert C.Martin的文章时,就经常有背后的寒毛都竖起来的感觉。他对模式的理解和应用,常常让已经把GOF那本书读了四五次的我感到自己对模式还没有入门。
这本Agile Software Development我只看了一半,而且有一个多月没有看了。
所以我打算复习一下,然后把她看完。
今天复习的内容是Principles。
在我看来,Principles是软件设计的基础。和patterns不同,Principles不能直接解决任何问题。但是她是衡量设计好坏的标准,定下了设计的目标。
在复习之前,先回忆一下,能够想起的Principles有这么几个:
SRP,Simple Responsiple Principle,单一责任。即是,每个类应该只承担一个责任。衡量的方法是,在系统中,一个类只会随一种变化而改变。然而具体实现中,这是非常难以作到的,更实际的目标是针对接口。每个接口只承担一个责任,而继承了多个接口的类,就承担了多个责任。
OCP,Open Close Principle。即是对功能的扩展Open,对代码的修改Close。在不修改当前代码的前提下,只是添加新的代码,就可以扩充功能。实际上,没有绝对的Open,也没有绝对的Close。无论如何抽象接口,分离实现。代码中,总有一点是需要修改而无法close的。但是随着动态语言特性的引入,我想,设计中对OCP的支持将会被大大的增强。
替换原则,想不起来英语简写了。(三个字母的黑话太多了 ^_^)字面的意思是父类的应该能被子类替换。实际上,是指子类不应该扩展父类没有的接口。更深层的原因是,如果子类公开了父类没有的接口,那么在使用时,调用者将会判断正在使用什么子类,是否可以使用扩展接口。这就使得调用者依赖于具体的实现,造成了高耦合。那么如果子类一定要扩充接口怎么办呢?答案是继承多接口。
依赖倒置原则,想不起来英语简写了。(三个字母的黑话太多了 ^_^)相对而言,这个原则比较容易理解。即是,模块之间不应该有直接的依赖关系,而应该通过抽象的接口联结起来,彼此不关心对方的具体实现。这个principle虽然容易理解,然而在实施上却是颇为困难。
剩下的principles就想不起来了。现在去看书,一会儿来更新。

复习以后的更新内容:
1. SRP,没有什么可以说的了。
2. OCP,没有什么可以说的了。
3. 替换原则的简写是LSP。子类不仅不应该扩充接口,而且也不能消减接口。总之不能让客户者针对实现作出判断。然而,我现在想来,这与GP中的traits的用法似乎有点不合。关于这个问题,我要仔细想想。结论大概是,traits的用法是,实现者根据调用者的不同,提供不同的实现,但是仍然保持着接口的不变;对于调用者而言,不同的实现还是透明的。
4. 依赖倒置原则是DIP。更容易的理解是,所有的依赖方向都应该是由实现到抽象,并终结于抽象。具体一点的说,上层模块要定义自己需要调用的接口,并使用这个接口,所以依赖这个抽象。下层模块要实现上层模块定义的接口,所以依赖那个抽象。两层模块的实现都依赖于同一个接口。
5. 没有想起来的原则是接口隔离原则(ISP)。实际上是说,要避免胖接口,尽量使用瘦接口。核心思想是,不能强迫客户包含他们并不需要的接口。也就是说,不要单一的大接口,要有很多的小接口。实现可以使用多继承,也可以用包含的方式来实现这多个接口。

其实,以前就觉得,Robert C.Martin和其他大师相比,非常倾向于使用小接口和多继承。如今看来,他有一大堆的Priniciples来支持自己的这种设计。

没有评论: