史無前例的設計模式-接口隔離原則

一、概念

接口隔離原則: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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章