接口隔离模式
在講接口隔離原則之前,我們先明確一下我們的主角,什么是接口,接口分為兩種:
一種是實(shí)例接口 (Object Interface),在 Java 中聲明一個(gè)類,然后用 new 關(guān)鍵字產(chǎn)生的一個(gè)實(shí)例,它是對一個(gè)類型的事 物描述,這是一種接口,比如你定義個(gè) Person 這個(gè)類,然后使用 Person zhangSan = new Person()產(chǎn)生了 一個(gè)實(shí)例,這個(gè)實(shí)例要遵從的標(biāo)準(zhǔn)就是 Person 這個(gè)類,Person 類就是 zhangSan 的接口,看不懂?不要緊, 那是讓 Java 語言浸染的時(shí)間太長了。主角已經(jīng)出場了,那我們看它的原則是什么,它有兩種定義:
第一種定義: Clients should not be forced to depend upon interfaces that they don't use. 客戶端不應(yīng)該依賴它不需用的接口。
第二種定義:The dependency of one class to another one should depend on the smallest possible interface。類間的依賴關(guān)系應(yīng)該建立在最小的接口上。
一個(gè)新事物的定義一般都是比較難理解的,晦澀難懂是正常的,否則那會讓人家覺的你沒有水平,這 也是一些國際廠商在國內(nèi)忽悠的基礎(chǔ),不整些名詞怎么能讓你崇拜我呢?我們把這個(gè)定義剖析一下,先說 第一種定義客戶端不應(yīng)該依賴它不需要接口,那依賴什么?依賴它需要的接口,客戶端需要什么接口就提 供什么借口,把不需要的接口剔除掉,那就需要對接口進(jìn)行細(xì)化,保證其純潔性;再看第二個(gè)定義,類間 的依賴關(guān)系應(yīng)該建立在最小的接口上,它要求是最小的接口,也是要求接口細(xì)化,接口純潔,與第一個(gè)定 義如出一轍,只是一個(gè)事物的兩種不同描述。
我們可以把這兩個(gè)定義概括為一句話:建立單一接口,不要建立臃腫龐大的接口。再通俗的一點(diǎn)講: 接口盡量細(xì)化,同時(shí)接口中的方法盡量的少。看到這里大家有可能要疑惑了,這與單一職責(zé)原則不是相同 的嗎?錯(cuò),接口隔離原則與單一職責(zé)的定義的規(guī)則是不相同的,單一職責(zé)要求的是類和接口職責(zé)單一,注 重的是職責(zé),沒有要求接口的方法減少,例如一個(gè)職責(zé)可能包含 10 個(gè)方法,這 10 個(gè)方法都放在一個(gè)接口 中,并且提供給多個(gè)模塊訪問,各個(gè)模塊按照規(guī)定的權(quán)限來訪問,在系統(tǒng)外通過文檔約束不使用的方法不 要訪問,按照單一職責(zé)原則是允許的,按照接口隔離原則是不允許的,因?yàn)樗蟆氨M量使用多個(gè)專門的 接口”,專門的接口指什么?就是指提供給多個(gè)模塊的接口,提供給幾個(gè)模塊就應(yīng)該有幾個(gè)接口,而不是建 立一個(gè)龐大的臃腫的接口,所有的模塊可以來訪問。
未遵循接口隔離原則的設(shè)計(jì):
?
遵循接口隔離原則的設(shè)計(jì):
根據(jù)接口隔離原則拆分接口時(shí),必須首先滿足單一職責(zé)原則。
?
我們來舉個(gè)例子來說明接口隔離原則到底對我們提出了什么要求。現(xiàn)在男生對小姑娘的稱呼使用頻率 最高的應(yīng)該是“美女”了吧,我們今天來定義一下什么是美女:首先要面貌好看,其次是身材要窈窕,然 后要有氣質(zhì),當(dāng)然了,這三者各人的排列順序不一樣,總之要成為一名美女就必須具備:面貌、身材和氣質(zhì),我們用類圖類體現(xiàn)一下星探(當(dāng)然,你也可以把你自己想想成星探)找美女的過程,看類圖:
?
定義了一個(gè) IPettyGirl 接口,聲明所有的美女都應(yīng)該有 goodLooking、niceFigure 和 greatTemperament,然后又定義了一個(gè)抽象類 AbstractSearcher,其作用就是搜索美女然后展示信息,只 要美女都是按照這個(gè)規(guī)范定義,Searcher(星探)就輕松的多了,我們先來看美女的定義:
public interface IPettyGirl { //要有姣好的面孔 public void goodLooking(); //要有好身材 public void niceFigure(); //要有氣質(zhì) public void greatTemperament(); }然后我們看美女的實(shí)現(xiàn)類:
public class PettyGirl implements IPettyGirl { private String name; //美女都有名字 public PettyGirl(String _name){this. name=_name;} //臉蛋漂亮 public void goodLooking() {System. out.println(this. name + "---臉蛋很漂亮!");} //氣質(zhì)要好 public void greatTemperament() {System. out.println(this. name + "---氣質(zhì)非常好!");} //身材要好 public void niceFigure() {System. out.println(this. name + "---身材非常棒!");} }然后我們來看 AbstractSearcher 類,這個(gè)類一般就是指星探這個(gè)行業(yè)了,源代碼如下:
public abstract class AbstractSearcher { protected IPettyGirl pettyGirl; public AbstractSearcher(IPettyGirl _pettyGirl){this.pettyGirl = _pettyGirl;} //搜索美女,列出美女信息 public abstract void show(); }場景中的兩個(gè)角色美女和星探都已經(jīng)完成了,我們再來寫個(gè)場景類,展示一下我們的這個(gè)過程:
public class Client { //搜索并展示美女信息 public static void main(String[] args) {//定義一個(gè)美女IPettyGirl yanYan = new PettyGirl(" 嫣嫣");AbstractSearcher searcher = new Searcher(yanYan);searcher.show();} }星探查找到美女,打印出美女的信息,源碼如下:
public class Searcher extends AbstractSearcher{ public Searcher(IPettyGirl _pettyGirl){super(_pettyGirl);} //展示美女的信息 public void show(){System. out.println("--------美女的信息如下: ---------------");//展示面容super. pettyGirl.goodLooking();//展示身材 super. pettyGirl.niceFigure();//展示氣質(zhì)super. pettyGirl.greatTemperament();} }運(yùn)行結(jié)果如下:
--------美女的信息如下:---------------
嫣嫣---臉蛋很漂亮!
嫣嫣---身材非常棒!
嫣嫣---氣質(zhì)非常好!
采用接口隔離原則:重新修改一下類圖:
把原 IPettyGirl 接口拆分為兩個(gè)接口,一種是外形美的美女 IGoodBodyGirl,這類美女的特點(diǎn)就是臉 蛋和身材極棒,超一流,但是沒有審美素質(zhì),比如隨地吐痰,出口就是 KAO,CAO 之類的,文化程度比較低; 另外一種是氣質(zhì)美的美女 IGreatTemperamentGirl,談吐和修養(yǎng)都非常高。我們從一個(gè)比較臃腫的接口拆分 成了兩個(gè)專門的接口,靈活性提高了,可維護(hù)性也增加了,不管以后是要外形美的美女還是氣質(zhì)美的美女 都可以輕松的通過 PettyGirl 定義。我們先看兩種類型的美女接口:
public interface IGoodBodyGirl { //要有姣好的面孔 public void goodLooking(); //要有好身材 public void niceFigure(); } public interface IGreatTemperamentGirl { //要有氣質(zhì) public void greatTemperament(); }實(shí)現(xiàn)類沒有改變,只是實(shí)現(xiàn)類兩個(gè)接口,源碼如下:
private String name; //美女都有名字 public PettyGirl(String _name){this. name=_name;} //臉蛋漂亮 public void goodLooking() {System. out.println(this. name + "---臉蛋很漂亮!");} //氣質(zhì)要好 public void greatTemperament() {System. out.println(this. name + "---氣質(zhì)非常好!");} //身材要好 public void niceFigure() {System. out.println(this. name + "---身材非常棒!");} }總結(jié):
通過這樣的改造以后,不管以后是要?dú)赓|(zhì)美女還是要外形美女,都可以保持接口的穩(wěn)定。當(dāng)然你可能 要說了,以后可能審美觀點(diǎn)再發(fā)生改變,只有臉蛋好看就是美女,那這個(gè) IGoodBody 接口還是要修改的呀, 確實(shí)是,但是設(shè)計(jì)時(shí)有限度的,不能無限的考慮未來的變更情況,否則就會陷入設(shè)計(jì)的泥潭中而不能自拔。 以上把一個(gè)臃腫的接口變更為兩個(gè)獨(dú)立的接口依賴的原則就是接口隔離原則,讓 AbstractSearcher 依 賴兩個(gè)專用的接口比依賴一個(gè)綜合的接口要靈活。接口是我們設(shè)計(jì)時(shí)對外提供的契約,通過分散定義多個(gè) 接口,可以預(yù)防未來變更的擴(kuò)散,提高系統(tǒng)的靈活性和可維護(hù)性。
?
轉(zhuǎn)載于:https://www.cnblogs.com/jiansen/p/7343927.html
總結(jié)
- 上一篇: hadoop大数据分析与挖掘实战(读书笔
- 下一篇: [原创] 为什么模除的时候一般建议选择素