软件设计中的几点设计原则(下)

以下大部分内容摘抄自阎宏博士的《JAVA与模式》一书的第二部分,部分加入了本人的一些理解。

设计原则

上篇说道了“开闭原则”和“里氏替换原则”,下面继续:

3.依赖倒转原则(DependenceInversionPrinciple)

要依赖于抽象,不要依赖于具体。

或者说:要针对接口编程,而不要针对实现编程。

这条原则主要是判断具体类有变化的需求,所以依赖抽象可以让具体类去变化。

当然这里也有一个度的把握,当某些特殊类是相当稳定的、不会发生辩护的,则客户端也可以依赖于此具体类,而不必故意去发明一个抽象类型。

4.接口隔离原则(InterfaceSegregationPrinciple)

多个专门的接口比使用单一的接口要好,从客户端类的角度来讲,一个类对另一个类的依赖性应该建立在最小接口上的。

反过来说:过于臃肿的接口设计是对接口的污染(InterfaceContamination).

5.合成/聚合复用原则

要尽量使用合成/聚合,尽量不要使用继承。

首先区分下聚合和合成的关系:

a)聚合关系(Aggregation):关联的一种,是整体和个体之间的关系,无法通过语法分别,是逻辑判断得出的。

b)合成关系(Composition)也是关联的一种,但比聚合关系更强。具体有2点:一是要求整体对象负责部分对象的生命周期;二是要求不分对象不能共享(即合成关系不能被共享)

使用合成/聚合关系有如下优点:(缺点是有较多的对象需要管理)

a)隐藏了成分对象的细节

b)可以在运行时,改变成分对象。

c)这种复用支持包装,这里我(马背)的理解是对成分对象的方法进行调用时候,可以加入一些逻辑。

d)所需依赖较少,指类之间的依赖关系,因为没有继承无关的方法,所以无需依赖这些方法所依赖的二类

f)新对象存取成分对象的唯一方法是通过成分对象的接口。

老实说,这点我(马背)没有理解很好,估计是这样的意思:一是成分对象可以要求成抽象的接口,这样能够依赖于抽象而不是具体实现。

相对的,滥用继承关系有如下缺点:

a)将父类的内容细节暴露给子类

b)如果超类发生改变,子类也被强制改变

c)关系是静态的,运行时候能改变,缺乏灵活性。

这条原则的掌握需要我们明确分析对象之间是“has-A”还是"Is-A"的关系。

6.迪米特法则(LawofDemeter)或者叫做最少知识原则(LeastKnowledgePrinciple)

一个对象应该对其他对象有尽可能少的了解。可以从狭义和广义两个角度来理解。

狭义的迪米特法则:要求一个对象如果不必与其他对象直接通讯,最好能通过其他对象将调用转发(callforwarding),典型的模式:门面模式(Facade)和调停者模式(Mediator),这二者都通过中间对象降低了调用者和其他对象的耦合度。

广义的迪米特法则:主要体现在对象之间、包之间、模块之间,将本身的数据和实现隐藏起来

1)优先考虑将一个类设置为不变类

2)尽量降低一个类的访问权限

3)谨慎使用Serializable

4)降低成员的访问权限

5)限制局部变量的有效范围

相关推荐