我的博客原文:
接口隔離原則java
設計模式六大原則之四:接口隔離原則。設計模式
姓名 :接口隔離原則ide
英文名 :Interface Segregation Principle測試
價值觀 :寧缺毋濫設計
我的介紹 :code
也用一個故事來說這 2 句乾巴巴的定義。接口
一小夥子跑到大城市的工廠打工,工做了一年半載,愈來愈以爲沒勁,天天干那麼多活,又領那麼一點工資,和他老爸抱怨這段時間的困擾,老爸想着,家裏有個小做坊,本身也一年不如一年了,要不就讓兒子回老家管理這小做坊。小夥子熬不過這個年,就跑回老家跟着老爸打理小做坊。ip
(來自Google Image)ci
小做坊主要是作布娃娃的,如上圖,工做在於打扮包裝布娃娃,工序有給布娃娃扎辮子、穿衣服、包裝入箱、打標籤。整個完整的流程都是一我的作的。有不少個工人天天都在作這個事情。開發
老爸向小夥子訴苦,感受招工挺多人的,生產力仍是提不上去。小夥子記着老爸的話,在工廠裏面觀察了幾天,他發現每一個工人都要作這 4 個打扮包裝布娃娃的工序,有些工人扎辮子很快但穿衣服很慢,有些工人扎辮子很慢但穿衣服快,他用了筆記本記下來:李大姨扎辮子快,王大媽穿衣服快,就這樣把每一個人有效率的工做都記錄下來。
一天晚上吃飯,小夥子跟老爸說了本身觀察到的現象,也把本子拿給老爸看,跟老爸商量:可不能夠作個嘗試,不要每一個人負責打扮包裝布娃娃全步驟,而是按工序分開,每一個人只負責一個工序,每一個工人只幹一件事,更容易熟能生巧。老爸聽着以爲有道理。
次日早上,就到小做坊裏,召集了全部工人,按小夥子的筆記上面的名單分工,你們都作好各自負責的內容,像流水線同樣,作好了就放到下個工序的地方,讓下個工序的人去作。到了下班,小夥子清點了今天工做的成果,包裝完成的娃娃比前一天多了 50% 。晚上小夥子跟老爸喝着百威吃起大肉慶祝一番。
這個故事你看了可能想罵爹罵娘,跟上面的定義有啥毛關係?故事只是把你們帶入這個場景,咱們在工做中,着手開發以前不都得先理清好需求背景,這就是要講接口隔離原則的背景,經過代碼來給你們講解一下如何用好接口隔離原則。
先看代碼
interface Work { void hairBraiding(); void getDressed(); void packingIntoTheBox(); void makeTag(); } class WangMather implements Work{ @Override public void hairBraiding() { System.out.println("王大媽給布娃娃扎辮子"); } @Override public void getDressed() { System.out.println("王大媽給布娃娃穿衣服"); } @Override public void packingIntoTheBox() { System.out.println("王大媽把布娃娃裝入箱子"); } @Override public void makeTag() { System.out.println("王大媽給箱子打標籤"); } } class LiAunt implements Work { @Override public void hairBraiding() { System.out.println("李大姨給布娃娃扎辮子"); } @Override public void getDressed() { System.out.println("李大姨給布娃娃穿衣服"); } @Override public void packingIntoTheBox() { System.out.println("李大姨把布娃娃裝入箱子"); } @Override public void makeTag() { System.out.println("李大姨給箱子打標籤"); } } // 測試代碼 WangMather wangMather = new WangMather(); wangMather.hairBraiding(); wangMather.getDressed(); wangMather.packingIntoTheBox(); wangMather.makeTag(); LiAunt liAunt = new LiAunt(); liAunt.hairBraiding(); liAunt.getDressed(); liAunt.packingIntoTheBox(); liAunt.makeTag();
在父親管理下的小做坊,是你們各自完成好一個布娃娃,工做互不交接,在這種運營模式下,咱們把全部工做都合併在一個接口 Work 是沒有問題的。有人可能要問,不是說接口隔離麼?這裏面 Work 接口的 4 個方法均可以分離開,它們都是各自的工做內容。稍等一下,咱們如今是基於老父親運營的模式下實現,若是小做坊一直都是這種模式運營,這段代碼有問題麼?其實沒問題的,咱們根據當時的業務考慮,在這種狀況下,把 Work 抽成 4 個接口不是不能夠,只是不現實,每一個工人都去實現如出一轍的 4 個接口在老父親運營模式下是不切實際。
接下來介紹兒子的運營模式。兒子提倡的是每一個工人職責分明,只負責一個事情,在這種狀況下,若是仍是用老父親的 Work 接口會有什麼問題呢?上面咱們說了,李大姨扎辮子快,王大媽穿衣服快,因此李大姨被分配去給布娃娃扎辮子,王大媽被分配去給布娃娃穿衣服。咱們沿用老父親的 Work 接口實現,代碼以下
class WangMather2 implements Work{ @Override public void hairBraiding() { } @Override public void getDressed() { System.out.println("王大媽給布娃娃穿衣服"); } @Override public void packingIntoTheBox() { } @Override public void makeTag() { } } class LiAunt2 implements Work { @Override public void hairBraiding() { System.out.println("李大姨給布娃娃扎辮子"); } @Override public void getDressed() { } @Override public void packingIntoTheBox() { } @Override public void makeTag() { } }
看出問題來了麼?李大姨僅僅參與扎辮子工做,王大媽參與了穿衣服工做,可是卻都要依舊實現其餘 3 個多餘的接口。因此在兒子的運營模式下,老父親的 Work 接口須要從新分配,以工序的角度分配,而不是以完成一個布娃娃的角度分配。總共有 4 個工序:扎辮子、穿衣服、包裝入箱、打標籤,咱們須要定義 4 個接口,讓員工去實現各自負責的工序接口。代碼以下
interface Hair { void hairBraiding(); } interface Dress { void getDressed(); } interface Box { void packingIntoTheBox(); } interface Tag { void makeTag(); } /** * 李大姨給布娃娃扎辮子快 */ class LiAunt3 implements Hair { @Override public void hairBraiding() { System.out.println("李大姨給布娃娃扎辮子"); } } /** * 王大媽給布娃娃穿衣服快 */ class WangMather3 implements Dress{ @Override public void getDressed() { System.out.println("王大媽給布娃娃穿衣服"); } } /** * 陳大叔包裝快 */ class ChenUncle implements Box { @Override public void packingIntoTheBox() { System.out.println("陳大叔給布娃娃裝箱"); } } /** * 黃大姐貼標籤快 */ class HuangSister implements Tag { @Override public void makeTag() { System.out.println("黃大姐給箱子打標籤"); } } // 測試代碼 LiAunt3 liAunt3 = new LiAunt3(); WangMather3 wangMather3 = new WangMather3(); ChenUncle chenUncle = new ChenUncle(); HuangSister huangSister = new HuangSister(); liAunt3.hairBraiding(); wangMather3.getDressed(); chenUncle.packingIntoTheBox(); huangSister.makeTag();
這段代碼看起來就很清晰了,在兒子的運營模式下,你們都是隻作一道工序,這樣子實現就很是合理。看了這個過程,你理解了接口隔離原則了麼?再看一看上面的定義:客戶端不該該依賴它不須要的接口。閉上眼睛,靜默 3 秒,感覺一下。
咱們也能夠回憶一下在工做中編寫的代碼,是否是有遵照接口隔離原則?在特定的場景下,若是不少類實現了同一個接口,而且都只實現了接口的極少部分方法,這時候頗有可能就是接口隔離性很差,就要去分析能不能把方法拆分到不一樣的接口。
接口隔離原則最最最重要一點就是要根據實際狀況,具體業務具體分析,不能犯了上面說到的錯誤:在老父親的運營模式下,按兒子的工序劃分接口去實現,那樣子會得不償失。
參考資料:《大話設計模式》、《Java設計模式》、《設計模式之禪》、《研磨設計模式》、《Head First 設計模式》
但願文章對您有所幫助,設計模式系列會持續更新,感興趣的同窗能夠關注公衆號,第一時間獲取文章推送閱讀,也能夠一塊兒交流,交個朋友。