官术网_书友最值得收藏!

  • 設計模式之禪
  • 秦小波
  • 2034字
  • 2019-01-02 03:55:49

4.2 美女何其多,觀點各不同

我們舉例來說明接口隔離原則到底對我們提出了什么要求。現在男生對小姑娘的稱呼,使用頻率最高的應該是“美女”了吧,你在大街上叫一聲:“嗨,美女!”估計10個有8個回頭,其中包括那位著名的如花。美女的標準各不相同,首先就需要定義一下什么是美女:首先要面貌好看,其次是身材要窈窕,然后要有氣質,當然了,這三者各人的排列順序不一樣,總之要成為一名美女就必須具備:面貌、身材和氣質,我們用類圖體現一下星探(當然,你也可以把自己想象成星探)找美女的過程,如圖4-1所示。

圖4-1 星探尋找美女的類圖

定義了一個IPettyGirl接口,聲明所有的美女都應該有goodLooking、niceFigure和great-Temperament,然后又定義了一個抽象類AbstractSearcher,其作用就是搜索美女并顯示其信息,只要美女都按照這個規范定義,Searcher(星探)就輕松多了,美女類的實現如代碼清單4-1所示。

代碼清單4-1 美女類

public interface IPettyGirl {
     //要有姣好的面孔
     public void goodLooking();
     //要有好身材
     public void niceFigure();
     //要有氣質
     public void greatTemperament();
}

美女的標準定義完畢,具體的美女實現類如代碼清單4-2所示。

代碼清單4-2 美女實現類

public class PettyGirl implements IPettyGirl {
     private String name;
     //美女都有名字
     public PettyGirl(String _name){
             this.name=_name;
     }
     //臉蛋漂亮
     public void goodLooking() {
             System.out.println(this.name+"---臉蛋很漂亮!");
     }
     //氣質要好
     public void greatTemperament() {
             System.out.println(this.name+"---氣質非常好!");
     }
     //身材要好
     public void niceFigure() {
             System.out.println(this.name+"---身材非常棒!");
     }
}

通過三個方法,把對美女的要求都定義出來了,按照這個標準,如花姑娘被排除在美女標準之外了。有美女,就有搜索美女的星探,其具體實現如代碼清單4-3所示。

代碼清單4-3 星探抽象類源代碼

public abstract class AbstractSearcher {
     protected IPettyGirl pettyGirl;
     public AbstractSearcher(IPettyGirl _pettyGirl){
             this.pettyGirl=_pettyGirl;
     }
     //搜索美女,列出美女信息
     public abstract void show();
}

星探的實現類就比較簡單了,其源代碼如代碼清單4-4所示。

代碼清單4-4 星探類

public class Searcher extends AbstractSearcher{
     public Searcher(IPettyGirl _pettyGirl){
             super(_pettyGirl);
     }
     //展示美女的信息
     public void show(){
             System.out.println("--------美女的信息如下:---------------");
             //展示面容
             super.pettyGirl.goodLooking();
             //展示身材
             super.pettyGirl.niceFigure();
             //展示氣質
             super.pettyGirl.greatTemperament();
     }
}

場景中的兩個角色美女和星探都已經出現了,需要寫一個場景類來串聯起各個角色,場景類的實現如代碼清單4-5所示。

代碼清單4-5 場景類

public class Client {
     //搜索并展示美女信息
     public static void main(String[] args) {
             //定義一個美女
             IPettyGirl yanYan=new PettyGirl("嫣嫣");
             AbstractSearcher searcher=new Searcher(yanYan);
             searcher.show();
     }
}

星探搜索美女的運行結果如下所示:

--------美女的信息如下:---------------
嫣嫣---臉蛋很漂亮!
嫣嫣---身材非常棒!
嫣嫣---氣質非常好!

星探尋找美女的程序開發完畢了,運行結果也正確。我們回頭來想想這個程序有沒有問題,思考一下IPettyGirl這個接口,這個接口是否做到了最優化設計?答案是沒有,還可以對接口進行優化。

我們的審美觀點都在改變,美女的定義也在變化。唐朝的楊貴妃如果活在現在這個年代非羞愧而死不可,為什么?胖呀!但是胖并不影響她入選中國四大美女,說明當時的審美觀與現在是有差異的。當然,隨著時代的發展我們的審美觀也在變化,當你發現有一個女孩,臉蛋不怎么樣,身材也一般般,但是氣質非常好,我相信大部分人都會把這樣的女孩叫美女,審美素質提升了,就產生了氣質型美女,但是我們的接口卻定義了美女必須是三者都具備,按照這個標準,氣質型美女就不能算美女,那怎么辦?可能你要說了,我重新擴展一個美女類,只實現greatTemperament方法,其他兩個方法置空,什么都不寫,不就可以了嗎?聰明,但是行不通!為什么呢?星探AbstractSearcher依賴的是IPettyGirl接口,它有三個方法,你只實現了兩個方法,星探的方法是不是要修改?我們上面的程序打印出來的信息少了兩條,還讓星探怎么去辨別是不是美女呢?

分析到這里,我們發現接口IPettyGirl的設計是有缺陷的,過于龐大了,容納了一些可變的因素,根據接口隔離原則,星探AbstractSearcher應該依賴于具有部分特質的女孩子,而我們卻把這些特質都封裝了起來,放到了一個接口中,封裝過度了!問題找到了,我們重新設計一下類圖,修改后的類圖如圖4-2所示。

把原IPettyGirl接口拆分為兩個接口,一種是外形美的美女IGoodBodyGirl,這類美女的特點就是臉蛋和身材極棒,超一流,但是沒有審美素質,比如隨地吐痰,文化程度比較低;另外一種是氣質美的美女IGreatTemperamentGirl,談吐和修養都非常高。我們把一個比較臃腫的接口拆分成了兩個專門的接口,靈活性提高了,可維護性也增加了,不管以后是要外形美的美女還是氣質美的美女都可以輕松地通過PettyGirl定義。兩種類型的美女定義如代碼清單4-6所示。

圖4-2 修改后的星探尋找美女類圖

代碼清單4-6 兩種類型的美女定義

public interface IGoodBodyGirl {
     //要有姣好的面孔
     public void goodLooking();
     //要有好身材
     public void niceFigure();
}
public interface IGreatTemperamentGirl {
     //要有氣質
     public void greatTemperament();
}

按照臉蛋、身材、氣質都具備才算美女,實現類實現兩個接口,如代碼清單4-7所示。

代碼清單4-7 最標準的美女

public class PettyGirl implements IGoodBodyGirl,IGreatTemperamentGirl {
     private String name;
     //美女都有名字
     public PettyGirl(String _name){
             this.name=_name;
     }
     //臉蛋漂亮
     public void goodLooking() {
             System.out.println(this.name+"---臉蛋很漂亮!");
     }
     //氣質要好
     public void greatTemperament() {
             System.out.println(this.name+"---氣質非常好!");
     }
     //身材要好
     public void niceFigure() {
             System.out.println(this.name+"---身材非常棒!");
     }
}

通過這樣的重構以后,不管以后是要氣質美女還是要外形美女,都可以保持接口的穩定。當然,你可能要說了,以后可能審美觀點再發生改變,只有臉蛋好看就是美女,那這個IGoodBody接口還是要修改的呀,確實是,但是設計是有限度的,不能無限地考慮未來的變更情況,否則就會陷入設計的泥潭中而不能自拔。

以上把一個臃腫的接口變更為兩個獨立的接口所依賴的原則就是接口隔離原則,讓星探AbstractSearcher依賴兩個專用的接口比依賴一個綜合的接口要靈活。接口是我們設計時對外提供的契約,通過分散定義多個接口,可以預防未來變更的擴散,提高系統的靈活性和可維護性。

主站蜘蛛池模板: 齐河县| 同仁县| 徐闻县| 宝兴县| 积石山| 通州区| 武安市| 清苑县| 塘沽区| 永清县| 财经| 青龙| 永仁县| 伊宁县| 榆林市| 雷州市| 忻州市| 安多县| 炎陵县| 平阳县| 南通市| 渭源县| 绵阳市| 邹城市| 福州市| 连山| 宜君县| 广宁县| 安达市| 鹤山市| 沈阳市| 乐山市| 新竹市| 开封市| 和田市| 平顶山市| 呼图壁县| 泰宁县| 治多县| 沈阳市| 青阳县|