1. 外觀模式
1.1 簡(jiǎn)介
??Facade模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過一個(gè)統(tǒng)一的Facade對(duì)象進(jìn)行瞬欧。Facade模式提供一個(gè)高層次的接口贷屎,使得子系統(tǒng)更易于使用。
??從客戶程序的角度來看艘虎,F(xiàn)acade模式不僅簡(jiǎn)化了整個(gè)組件系統(tǒng)的接口唉侄,同時(shí)對(duì)于組件內(nèi)部與外部客戶程序來說,從某種程度上也達(dá)到了一種“解耦”的效果——內(nèi)部子系統(tǒng)的任何變化不會(huì)影響到Fa?ade接口的變化野建。
??注意區(qū)分Fa?ade模式属划、Adapter模式、Bridge模式與Decorator模式候生。Fa?ade模式注重簡(jiǎn)化接口同眯,Adapter模式注重轉(zhuǎn)換接口,Bridge模式注重分離接口(抽象)與其實(shí)現(xiàn)陶舞,Decorator模式注重穩(wěn)定接口的前提下為對(duì)象擴(kuò)展功能嗽测。
Facade的兩種形式:
- 類內(nèi)實(shí)現(xiàn)額外非接口定義方法的隱藏
- 對(duì)一組接口方法封裝為一個(gè)提供對(duì)外服務(wù)
1.2 方法隱藏示例
對(duì)外接口FacadeService:
public interface FacadeService {
public void a();//這個(gè)方法是給外部調(diào)用的
}
實(shí)現(xiàn)類FacadeServiceImpl:
public class FacadeServiceImpl implements FacadeService {
public void a() {
System.out.println("這是給外部調(diào)用的");
}
public void b() {
System.out.println("這是給內(nèi)部調(diào)用的");
}
}
??a是給外部調(diào)用用的绪励,此時(shí)可以給外部調(diào)用肿孵。但是b是給內(nèi)部調(diào)用的,我們不希望給外部調(diào)用疏魏,此時(shí)可以怎么做呢停做??jī)煞N方式,一種是調(diào)整b方法的訪問權(quán)限為private大莫;另一種即Facade模式蛉腌。
** FacadeServiceImplForOut:**
public class FacadeServiceImplForOut implements FacadeService {
private FacadeService facadeService;
public FacadeServiceImplForOut(FacadeServiceImpl facadeService){
this.facadeService=facadeService;
}
public void a() {
facadeService.a();
}
}
調(diào)用:
public class FacadeServiceMain {
public static void main(String[] args) {
FacadeServiceImpl facadeService = new FacadeServiceImpl();
FacadeServiceImplForOut fout = new FacadeServiceImplForOut(facadeService);
fout.a();
}
}
??facade提供了一個(gè)供外部client調(diào)用的Facade層,由其組織調(diào)用真正的業(yè)務(wù)層,對(duì)于調(diào)用client來說烙丛,真正的業(yè)務(wù)層對(duì)他來說是透明的,這樣做的好處是讓調(diào)用層client和真正的業(yè)務(wù)層解耦,同時(shí)在Facade層也可以做更多的事情霹疫,比如上面的屏蔽client不該訪問到的方法等等舌界。
1.3 接口方法封裝示例
??我們把一個(gè)很文件的文件,放在了第二抽屜里忘蟹,而第二個(gè)抽屜的鑰匙放在了第一個(gè)抽屜里飒房,我們要想取出這個(gè)文件,需要打開第一個(gè)抽屜拿到鑰匙媚值,然后打開第二個(gè)抽屜取出文件狠毯。
抽屜1DrawerOne:
class DrawerOne {
public void open(){
System.out.println("第一個(gè)抽屜被打開了");
getKey();
}
public void getKey(){
System.out.println("得到第二個(gè)抽屜的鑰匙");
}
}
抽屜2 DrawerTwo:
class DrawerTwo{
public void open(){
System.out.println("第二個(gè)抽屜被打開了");
getFile();
}
public void getFile(){
System.out.println("得到這個(gè)重要文件");
}
}
調(diào)用示例:
public static void main(String []args){
DrawerOne darwerOne=new DrawerOne();
DrawerTwo darwerTwo=new DrawerTwo();
darwerOne.open();
darwerTwo.open();
}
** DrawerFacade:**
class DrawerFacade{
DrawerOne darwerOne=new DrawerOne();
DrawerTwo darwerTwo=new DrawerTwo();
public void open(){
darwerOne.open();
darwerTwo.open();
}
}
Facade調(diào)用示例:
public static void main(String []args){
DrawerFacade drawer=new DrawerFacade();
drawer.open();
}
1.4 使用場(chǎng)景
Facade模式主要適用于以下幾種情況:
- 不需要使用一個(gè)復(fù)雜系統(tǒng)的所有功能,而且可以創(chuàng)建一個(gè)新的類褥芒,包含訪問系統(tǒng)的所有規(guī)則嚼松。如果只需要使用系統(tǒng)的部分功能,那么你為新類所創(chuàng)建的API將比原系統(tǒng)的API簡(jiǎn)單的多锰扶。
- 希望封裝或者隱藏系統(tǒng)原系統(tǒng)惜颇。
- 希望使用原系統(tǒng)的功能,而且還希望增加一些新的功能少辣。
- 編寫新類的成本小于所有人學(xué)會(huì)使用或者未來維護(hù)原系統(tǒng)上所需的成本凌摄。