飞道的博客

史无前例的设计模式-接口隔离原则

303人阅读  评论(0)

一、概念

接口隔离原则:Interface Segregation Principle,简称ISP。客户端(接口调用者)不应该被迫依赖他不需要的接口。

二、如何理解“接口”

如何理解接口隔离原则中的接口二字?

分为三个方面

  • 一个类里的一组API接口
  • 单个API接口
  • OOP中的interface的概念

三、“接口”解释

1、一个类里的一组API接口

1.1、案例

用户系统提供了一些接口(比如注册、登录、查询用户信息等非敏感操作给其他系统使用)。

1.2、代码

public interface UserService {
  boolean register(String cellphone, String password);
  boolean login(String cellphone, String password);
  UserInfo getUserInfoById(long id);
  UserInfo getUserInfoByCellphone(String cellphone);
}

public class UserServiceImpl implements UserService {
  // ...
}

但是新的管理系统需要我们提供根据手机号删除用户的接口,这时候就很危险了,因为删除操作是很敏感的行为。如果在上面的UserService里添加deleteUserByCellphone接口的话就违背了接口隔离原则,因为其他业务系统都在依赖这个UserService,这也就意味着其他业务系统都有了deleteUserByCellphone这个接口的权限,很危险。所以按照接口隔离原则需要将这个敏感接口单独放到一个其他Service里,比如RestrictedUserService#deleteUserByCellphone来供新管理系统使用。最终完整代码如下


public interface UserService {
  boolean register(String cellphone, String password);
  boolean login(String cellphone, String password);
  UserInfo getUserInfoById(long id);
  UserInfo getUserInfoByCellphone(String cellphone);
}

public interface RestrictedUserService {
  boolean deleteUserByCellphone(String cellphone);
  boolean deleteUserById(long id);
}

public class UserServiceImpl implements UserService, RestrictedUserService {
  // ...省略实现代码...
}

为什么是UserServiceImpl实现了两个接口,而不是单独的RestrictedUserServiceImpl去实现RestrictedUserService?
因为我这里是RPC接口,直接对外暴露Service层就行。Service里仅有一个接口。

2、单个API接口

2.1、案例

也就是把接口理解成单个方法,也就是说方法的设计功能要单一,不要将多个不同的功能逻辑放到一个方法中实现,这里我们的单一职责原则也是如此,所有原则大方向都一样,只是某些点不同。所以不要纠结。
比如看下面一个统计的代码

2.2、代码

public class Statistics {
  private Long max;
  private Long min;
  private Long average;
  private Long sum;
  private Long percentile99;
  private Long percentile999;
  //...省略constructor/getter/setter等方法...
}

public Statistics count(Collection<Long> dataSet) {
  Statistics statistics = new Statistics();
  statistics.setMax(...);
  statistics.setMin(...);
  statistics.setAverage(...);
  //...等等
  return statistics;
}

2.3、分析

上面的count函数表面看功能不够单一,违背了单一职责原则、接口(因为这里的接口说的就是方法,)隔离原则,因为它这个count干了N件事情,按照接口隔离原则来看应该把它拆分成如下几个粒度更小的方法

public Long max(Collection<Long> dataSet) { //... }
public Long min(Collection<Long> dataSet) { //... } 
public Long average(Colletion<Long> dataSet) { //... }
// ...省略其他统计函数...

这个是需要看业务场景的,如果你只要统计max和min,那么拆分粒度更小的越好,越不会违背接口隔离原则。因为如果不拆分直接用count的话,需要多查几次其他函数,比如average,这些都是无用功,浪费性能不说,其他函数出了问题还会影响主流程。但是如果业务场景就是需要统计全部的话,那么count这个方法也没毛病,不会违背接口隔离原则。所有的设计原则、设计模式都是为了解决问题而生,所以没有绝对,取决于业务场景。

3、OOP中的interface的概念

面向接口编程,interface隔离,单一功能。不要把全部方法都放到一个interface里,根据业务适当拆分多个interface。


转载:https://blog.csdn.net/ctwctw/article/details/105929771
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场