面向对象设计原则实践:之五.迪米特原则,接口隔离原则

六、迪米特(第三者交互)原则

1. 定义

每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

2. 分析

1) 迪米特法则就是指一个软件实体应当尽可能少的与其他实体发生相互作用。

这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,

这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

2) 狭义的迪米特法则:

可以降低类之间的耦合,但是会在系统中增加大量的小方法并散落在系统的各个角落,

它可以使一个系统的局部设计简化,因为每一个局部都不会和远距离的对象有直接的关联,

但是也会造成系统的不同模块之间的通信效率降低,使得系统的不同模块之间不容易协调。

3) 广义的迪米特法则:

指对对象之间的信息流量、流向以及信息的影响的控制,主要是对信息隐藏的控制。

信息的隐藏可以使各个子系统之间脱耦,从而允许它们独立地被开发、优化、使用和修改,同时可以促进软件的复用,

由于每一个模块都不依赖于其他模块而存在,因此每一个模块都可以独立地在其他的地方使用。

一个系统的规模越大,信息的隐藏就越重要,而信息隐藏的重要性也就越明显。

4) 迪米特法则的主要用途在于控制信息的过载。

a. 在类的划分上,应当尽量创建松耦合的类,

类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及

b. 在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限

c. 在类的设计上,只要有可能,一个类型应当设计成不变类 

d. 在对其他类的引用上,一个对象对其他对象的引用应当降到最低。 

3. 实例

某系统界面类(如Form1、Form2等类)与数据访问类(如DAO1、DAO2等类)之间的调用关系较为复杂。

如图所示:

第三者交互原则-图-1

第三者交互原则-图-2

图(一)和图(二)分析:

因为这样就可以降低类的耦合性,是类中功能更加单一,相当于【外观模式】。

4. 总结

一个软件实体应当尽可能少的与其他实体发生相互作用

七、接口隔离原则(ISP--Interface Segregation Principle)

1. 定义

a) 客户端不应该依赖那些它不需要的接口。

b).  一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。 

使用多个专门的接口比使用单一的总接口要好。 

一个类对另外一个类的依赖性应当是建立在最小的接口上的。 

一个接口代表一个角色,不应当将不同的角色都交给一个接口。

没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。 

不应该强迫客户依赖于它们不用的方法。

接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,

再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,

那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。 

2.分析

a). 接口隔离原则是指使用多个专门的接口,而不使用单一的总接口。

每一个接口应该承担一种相对独立的角色,不多不少,不干不该干的事,该干的事都要干。

b). 使用接口隔离原则拆分接口时,首先必须满足单一职责原则,

将一组相关的操作定义在一个接口中,且在满足高内聚的前提下,接口中的方法越少越好。

c). 可以在进行系统设计时采用定制服务的方式,

即为不同的客户端提供宽窄不同的接口,只提供用户需要的行为,而隐藏用户不需要的行为

3.实例

下图展示了一个拥有多个客户类的系统,在系统中定义了一个巨大的接口(胖接口)AbstractService来服务所有的客户类。

如图所示:

接口隔离原则-图-1

接口隔离原则-图-2

图(一)和图(二)分析:

因为这样做既满足了接口隔离原则,又满足了单一原则,何乐而不为呢,

但是也带来了很多的不便,类增多了。

4. 举例说明

参考下图的设计,在这个设计里,取款、存款、转帐都使用一个通用界面接口,

也就是说,每一个类都被强迫依赖了另两个类的接口方法,那么每个类有可能因为另外两个类的方法(跟自己无关)而被影响。

拿取款来说,它根本不关心“存款操作”和“转帐操作”,可是它却要受到这两个方法的变化的影响。 

那么我们该如何解决这个问题呢?

参考下图的设计,为每个类都单独设计专门的操作接口,

使得它们只依赖于它们关系的方法,这样就不会互相影了!

5. 总结

类应该完全依赖相应的专门的接口

实现方法: 

a) 使用委托分离接口 

b) 使用多重继承分离接口 

猜你喜欢

转载自blog.csdn.net/fireroll/article/details/82107417