软件设计原则之接口隔离原则、合成复用原则、迪米特原则

系列文章目录

软件设计原则之单一职责原则、开闭原则
软件设计原则之里氏替换原则、依赖倒置原则
软件设计原则之接口隔离原则、合成复用原则、迪米特原则



一、接口隔离原则

什么是接口隔离原则(What)

接口隔离原则,ISP,Interface Segregation Principle
定义:用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口。
这里的“接口”有两种不同的含义:

  • 一个类型所具有的方法特征的集合,仅仅是一种逻辑上的抽象。
    此时,接口的划分将直接带来类型的划分。可以把接口理解成角色,一个接口只能代表一个角色,每个角色都有它特定的一个接口,此时,这个原则可以叫作“角色隔离原则”。
  • 某种语言具体的“接口”定义
    此时,该原则表达的意思是指接口仅仅提供客户端需要的行为,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。在面向对象编程语言中,实现一个接口就需要实现该接口中定义的所有方法,因此大的总接口使用起来不一定很方便。为了使接口的职责单一,需要将大接口中的方法根据其职责不同分别放在不同的小接口中,以确保每个接口使用起来都较为方便,并各承担某一单一角色。接口应该尽量细化,同时接口中的方法应该尽量少,每个接口中只包含一个客户端(如子模块或业务逻辑类)所需的方法即可,这种机制也称为“定制服务”,即为不同的客户端提供宽窄不同的接口。

为什么使用接口隔离原则(Why)

我们可以反过来问,如果不遵循接口隔离原则,会怎样。如果接口承担了太多职责,会导致以下后果:

  • 导致该接口的实现类很庞大,在不同的实现类中都不得不实现接口中定义的所有方法,灵活性较差,如果出现大量的空方法,将导致系统中产生大量的无用代码,影响代码质量;
  • 由于客户端针对大接口编程,将在一定程度上破坏程序的封装性,客户端看到了不应该看到的方法,没有为客户端定制接口。

因此需要将该接口按照接口隔离原则和单一职责原则进行重构,将其中的一些方法封装在不同的小接口中,确保每个接口使用起来都较为方便,并各承担某一单一角色,每个接口中只包含一个客户端(如模块或类)所需的方法即可。
接口隔离原则符合我们常说的高内聚低耦合的设计思想,使的类具有很好的可读性、可扩展性和可维护性。

如何使用接口隔离原则(How)

  • 建立单一接口,不要建立庞大臃肿的接口。当一个接口太大时,需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。
  • 注意控制接口的粒度。接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。

「接口隔离原则」与「单一职责原则」
个人的理解,可以把「单一职责原则」比作指导思想,而「接口隔离原则」就是这个思想的一种具体实践。


二、合成复用原则

什么是合成复用原则(What)

合成复用原则,CRP,Composite Reuse Principle
又叫组合/聚合复用原则,CARP,Composition/Aggregate Reuse Principle
定义:尽量使用对象组合,而不是继承来达到复用的目的。
「合成复用原则」就是在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用功能的目的。简言之:复用时要尽量使用组合/聚合关系(关联关系),少用继承。
「合成复用原则」同「里氏替换原则」相辅相成的,两者都是「开闭原则」的具体实现规范。


为什么使用合成复用原则(Why)

通常类的复用分为“继承复用”和“合成复用”两种。“继承复用”虽然有简单和易实现的优点,但它也存在以下缺点:

  • 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。
  • 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护。
  • 它限制了复用的灵活性。从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化。
  • 继承方式过度使用,会导致类的数量快速增长,会增加系统构建和维护的难度以及系统的复杂度。

采用“合成复用”时,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,它有以下优点:

  • 它维持了类的封装性。因为成员对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。
  • 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成员对象的唯一方法是通过成员对象的接口。
  • 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成员对象类型相同的对象。
  • 功能的扩展不会导致类数量的增加

使用「合成复用原则」可以使系统更加灵活,降低类与类之间的藕合度一个类的变化对其他类造成的影响相对较少。

如何使用合成复用原则(How)

合成复用原则,就是把上图改造为下图的过程 :
在这里插入图片描述
在这里插入图片描述


三、迪米特原则

什么是迪米特原则(What)

迪米特原则,LOD,Law of Demeter
也叫「最少知道原则」,The Least Knowledge Principle
定义:一个对象应该对其他对象保持最少的了解,使得系统功能模块相对独立,这样当一个模块修改时,影响的模块就会越少,扩展起来更加容易。又叫「最少知道原则」。

为什么使用迪米特原则(Why)

可以降低系统的耦合度,一个对象的改变不会给太多其他对象带来影响。

如何使用迪米特原则(How)

只和朋友交流,不和陌生人说话

在迪米特法则中,对于一个对象,其“朋友”包括以下几类:
(1)当前对象本身以及当前对象所创建的对象
(2)当前对象的成员对象,如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友
(3)以参数形式传入到当前对象方法中的对象
任何一个对象,如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。


第三者通信法
如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用;如果其中一个对象需要调用另一个对象的方法,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度。


参考书籍

[1] 设计模式的艺术 作者:刘伟

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值