实现接口隔离原则主要需要实现两个要求:
- 客户端不应该依赖不需要的接口
- 类间的依赖应该建立在最小的接口上
接口不应该是臃肿的,接口应该细化。这和单一职责有一定区别,单一职责要求类或者接口具有单一的职责,而接口隔离要求接口的实现的方法尽可能的少。
例如提供了PersonInfoService 如下所示. 对于PersonInfoService 来说,有的业务仅仅只需要判断Person的性别即可,并不需要完整的PersonInfoService ,这时候仅仅需要提供PersonSexService即可,这样就做到了简单的服务拆分。
public interface PersonInfoService {String getPersonName(int personId);int getPersonAge(int personId);boolean isMan(int personId);}// 可以拆分为public interface PersonInfoService extends PersonSexSerivice {String getPersonName(int personId);int getPersonAge(int personId);}public interface PersonSexSerivice{boolean isMan(int personId);}
同样的,假如你需要判断一个人的性别,针对第二个要求: 类间的依赖应该建立在最小的接口上,所以仅需要注入PersonSexService即可。
// 仅需要获取用户性别,最小依赖 PersonSexServicePersonSexService sexService = new PersonInfoServiceImpl();boolean isMan1 = sexService.isMan(1);// 需要获取其他信息,需要依赖 PersonInfoServicePersonInfoService infoService = new PersonInfoServiceImpl();boolean isMan2 = infoService.isMan(1);int personAge = infoService.getPersonAge(1);String personName = infoService.getPersonName(1);
4.1 星探搜索代码
假设我们需要实现星探搜索美女的一个软件,评判一个人是否是美女通常需要有一些条件: 好看的外观条件,良好的文化修养 以及 身材,依据此我们可以实现一个PrettyGirl的服务。
public interface IPrettyGirl {void goodLooking();void nickFigure();void hasCulture();}
那么依据此我们可以实现简单的类图如下:
上面的类图可以非常方便的展示出,类之间的关系,但是随着时代的发展,文化修养可能产出文化美女,但是我们的代码设计却还是以这三个条件作为判断依据,显然不是合适的,所以我们需要将文件修养单独实现该接口。在AbstractSearch的接口中分别实现这些判断逻辑,类图结构如下:
这样以后需要文化性美女也可以很好地减少修改,有读者可能提出: 如果后面只需要好看的美女呢,是不是还要单独分离一个新的接口,确实如此,但是在有限的开发设计中,不能无限考虑未来变更的情况,否则会陷入设计的泥潭中而不能自拔。
4.2 最佳实践
- 尽量保证接口最小化,即首先保证单一职责,然后保证接口隔离,不能出现臃肿接口(FatInterface)
- 一个接口通常只维护一个服务或者模块
- 接口需要高内聚,所谓的高内聚指的是 public 方法尽少的对外暴露,代码逻辑在类内部实现,对外承诺的服务越少,接口越安全
- 定制化服务,同高内聚类似,对外暴露的接口尽可能的少,如果有不同的服务实现,尽量拆分服务
- 切勿盲从,每个项目对于接口隔离的控制粒度都不一致,这需要我们不断的学习掌握
彻底贯彻接口隔离的方法是每个接口均有一个方法,但这样显然不合理,因此掌握每个接口的隔离粒度,就需要开发这不断地摸索掌握
