这系列博文将先讲述七大设计模式的原则,再详述23种java设计模式。
2)接口隔离原则(Interface-Segergation Principle)
定义:Many client specific interfaces are better than one general purpose interface(多个专用的接口优于一个通用接口)
这个定义是假设有一个具有多个功能的系统,多个客户端通过接口(API)调用访问。
若采用单一通用接口设计,结构如下
这样设计的问题在于,GrandInterface包含了所有客户端的接口,所有客户端都将不得不实现其他客户端的方法,仅是为了使其接口得以编译。而且,当某一个客户端特定接口更改时,需要付出巨大的努力来管理和更改其他所有的客户端。
比如有一个业务需要接受线上下单、电话下单、堂食下单、在线支付(针对在线客户)和货到付款。采用单一通用接口设计代为如下
public interface RestaurantInterface {
public void acceptOnlineOrder();
public void takeTelephoneOrder();
public void payOnline();
public void walkInCustomerOrder();
public void payInPerson();
}
针对线上下单的客户端实现为
public class OnlineClientImpl implements RestaurantInterface{
@Override
public void acceptOnlineOrder() {
//logic for placing online order
}
@Override
public void takeTelephoneOrder() {
//Not Applicable for Online Order
throw new UnsupportedOperationException();
}
@Override
public void payOnline() {
//logic for paying online
}
@Override
public void walkInCustomerOrder() {
//Not Applicable for Online Order
throw new UnsupportedOperationException();
}
@Override
public void payInPerson() {
//Not Applicable for Online Order
throw new UnsupportedOperationException();
}
}
电话下单、堂食下单与线上下单实现类似。
这样设计的问题在于
1、由于接口中包含了其他业务的接口,而线上下单的客户端不支持,因此不用实现,用 UnsupportedOperationException 处理
2、其他客户端也同样如此,若某个特定的接口更改,将需要更改所有的客户端,这会使得代码维护非常蛮烦
3、这也违背了单一职责原则
为了解决上述问题,我们采用接口隔离原则来重新设计上述接口。
接口隔离原则将一个臃肿的接口拆分为多个单独精简的接口,每个隔离的接口都只包含客户端所需要的特定方法,设计如下
当然,上述的精简接口并不意味着每一个客户端都需要一个特定接口,接口是否独立应该是根据功能类型而定,也就是根据单一职责原则来定。(单一职责原则是建立在接口隔离原则之上的,后者专门是对抽象的约束)
那么我们怎么利用接口隔离原则来解决上述问题呢?
1、将下单和付款分开两个接口,命名为PaymentInterface.java
和OrderInterface.java;
2、每种客户端使用各自种类的实现类,比如线上下单的客户端使用OnlinePaymentImpl和
OnlineOrderImpl,其他以此类推;
设计图如下
个人理解,接口隔离原则就是别把特定的方法加入到通用的接口中去,特定的方法可以写多一个接口,继承通用接口。
PS:java类是单继承,接口是可以多继承的。