定義:
門面模式為了系統提供一個統一的頂端介面,供外部客戶使用。也是提供一個更高的層次的介面,使得子系統更容易使用。
定義:
門面模式為了系統提供一個統一的頂端介面,供外部客戶使用。也是提供一個更高的層次的介面,使得子系統更容易使用。
形式:
定義一個(或多個)具備所需介面的新類(門面類)
新類門戶使用原來的系統
客戶使用門面類物件與原系統打交道
使用:
1、客戶只需要使用某個複雜系統的子集,或者需要以一種特殊的方式與系統交互時,使用門面模式。
2、當需要跟蹤原系統的使用情況時 ,使用門面模面模式。因為所有對系統的訪問都經過FACADE,所很可以容易的監視系統的使用 。
3、 希望封裝和隱藏原系統時。
4、編寫新類的成本小於所有人使用和維護原系統使用所需的成本時
代碼解析:
①定義介面
/*
*<b>類描述:</b >定義介面:寫信的過程<br>
* <b>郵件:</b> yiyu1@163.com <br>
* @author wonter
*/
public interface GuoCheng {
//信的內容
public void XinContext(String context);
//信封地址,收信人等
public void Envelope(String address);
//將信放入信封
public void Into();
//郵遞
public void sendLetter();
}
②定義實現類,去繼承①介面。
/**
*<b>類描述:</b >實現類 LetterImp<br>
* <b>郵件:</b> yiyu1@163.com <br>
* @author wonter
*/
public class LetterImp implements GuoCheng {
//寫信
public void XinContext(String context) {
System.out.println("信的內容"+context);
}
//寫信封
public void Envelope(String address) {
System.out.println("收件人地址及姓名"+address );
}
//將信放入信封
public void Into() {
System.out.println("將信放入信封");
}
//塞到郵箱中,郵遞
public void sendLetter() {
System.out.println("郵遞信");
}
③【不推薦】這時候,你可以直接在main()方法中寫信了。
/**
*<b>類描述:</b >定義 main() 寫信<br>
* <b>郵件:</b> yiyu1@163.com <br>
* @author wonter
*/
public class ZhouJielun {
public static void main(String[] args) {
//創建一個處理信件的過程
GuoCheng guocheng = new LetterImp();
//寫信
guocheng.XinContext("你好,方文山,你寫的歌詞我弄丟了。");
//寫信封
guocheng.Envelope("273100,山東,曲阜,方文山");
//將信放入信封
guocheng.Into();
//塞到郵箱中,郵遞
guocheng.sendLetter();
}
}
【推薦】④怎麼樣才能更完美,更適合商業項目
③與高內聚的要求相差甚遠
為了讓調用者更方便的調用, 就對Sub System 進行了封裝,增加了一個門面,ZhouJielun 調用時,
直接調用門面的方法就可以了,不用瞭解具體的實現方法以及相關的業務順序,
/**
*<b>類描述:</b >我們來看程式的改變,GuoCheng 介面和實現類都沒有改變,只是增加了一個Moden 類<br>
* <b>郵件:</b> yiyu1@163.com <br>
* @author wonter
*/
public class Moden {
private GuoCheng guocheng = new LetterImp();
//寫信,封裝,投遞,一體化了
public void sendLetter(String context,String address){
//幫你寫信
guocheng.XinContext(context);
//寫好信封
guocheng.Envelope(address);
//把信放到信封中
guocheng.Into();
guocheng.sendLetter();
}
}
/**
*<b>類描述:</b >OK 開始 寫信
* ZhouJielun的操作簡單了很多,提供這種模式後,系統的擴展性也有了很大的提高。<br>
* <b>郵件:</b> yiyu1@163.com <br>
* @author wonter
*/
public class ZhouJielun {
public static void main(String[] args) {
//郵局,有這項服務
Moden moden = new Mod();
//你只要把信的內容和收信人位址給他,他會幫你完成一系列的工作;
String address = "273100,山東,曲阜,方文山";
String context = "你好,方文山,你寫的歌詞我弄丟了。";
moden.sendLetter(context, address);
}
}
⑤突然一個非常時期(比如中美大戰),寄往 洛杉磯 的郵件都必須進行安全檢查。怎麼辦呢?
/**
*<b>類描述:</b >
*只是增加了一個 rPolice 變數的聲明以及一個方法的調用,那這個寫信的過程就變成了這樣:先
*寫信,然後寫信封,然後員警開始檢查,然後才把信放到信封,然後發送出去。
*<br>
* <b>郵件:</b> yiyu1@163.com <br>
* @author wonter
*/
public class Moden {
private GuoCheng guocheng = new LetterImp();
//按需要定義Police
private Police letterPolice = new Police();
//寫信,封裝,投遞,一體化了
public void sendLetter(String context,String address){
//幫你寫信
guocheng.writeContext(context);
//寫好信封
guocheng.fillEnvelope(address);
//員警要檢查信件了
letterPolice.checkLetter(guocheng);
//把信放到信封中
guocheng.into();
//郵遞信件
guocheng.sendLetter();
}
}
好處:
門面模式是一個很好的封裝方法,一個子系統比較複雜,比如演算法或者業務比較複雜,
就可以封裝出一個或多個門面出來,專案的結構簡單,而且擴展性非常好。還有,在一個較大項目
中的時候,為了避免人員帶來的風險,也可以使用這個模式。
缺點:
1) 當你要為了一個複雜子系統提供一個簡單介面時。在上面已經描述了原因。
2) 由於抽象類別的實現部分與客戶程式之間存在著很大的依賴性。引入 facade 將這個子系統與客戶以及其他的子系統分離,
可以提高子系統的獨立性和可攜性(上面也提到了)。
3) 當你需要構建一個層次結構的子系統時,使用 facade 模式定義子系統中每層的入口點。如果子系統之間是相互依賴的,
你可以讓它們僅通過 facade 進行通訊,從而簡化了它們之間的依賴關係。