一、概念
接口隔离原则: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