《三國(guó)演義》中有曰:劉備昧识、諸葛亮趁曹操赤壁之戰(zhàn)失利,大肆擴(kuò)充地盤盗扒,先后占領(lǐng)荊州大部地區(qū)滞诺,引起東吳孫權(quán)的警惕形导。為了限制劉備勢(shì)力的發(fā)展,魯肅奉命向劉備討還荊州习霹,但遭到拒絕朵耕。東吳大都督周瑜向?qū)O權(quán)獻(xiàn)計(jì):趁劉備的甘夫人病故,用孫權(quán)的妹妹孫仁為誘餌淋叶,將劉備“賺到南徐阎曹,妻子不能勾得,幽囚在獄中”煞檩。 但是处嫌,這個(gè)詭計(jì)被諸葛亮一眼識(shí)破。他將計(jì)就計(jì)斟湃,讓劉備“擇日便去就親”熏迹,并派趙云前去保護(hù),并給了趙云三個(gè)錦囊凝赛,教趙云“依次而行”注暗。結(jié)果,使東吳“賠了夫人又折兵”墓猎。此為諸葛亮的錦囊三妙計(jì)捆昏。
一、三妙計(jì)
妙計(jì)一:見(jiàn)喬國(guó)老毙沾,并把劉備娶親的事情搞得東吳人盡皆知骗卜。
妙計(jì)二:用謊言(曹操打荊州)騙泡在溫柔鄉(xiāng)里的劉備回去。
妙計(jì)三:讓孫夫人擺平東吳的追兵左胞,她是孫權(quán)妹妹寇仓,東吳將領(lǐng)懼她三分。
二烤宙、妙計(jì)的兩種實(shí)施方案
1.把三個(gè)錦囊直接交給劉備焚刺,讓劉備根據(jù)情況打開(kāi)錦囊。
2.把錦囊交給趙云门烂,趙云按照諸葛亮的囑咐乳愉,依次按照情況使用錦囊。
三屯远、劉備用妙計(jì)
①妙計(jì)的接口
public interface Strategy {
//妙計(jì)內(nèi)容
public void carryOut();
}
②妙計(jì)一
public class StrategyOne implements Strategy {
@Override
public void carryOut() {
System.out.println("見(jiàn)喬國(guó)老蔓姚,并把劉備娶親的事情搞得東吳人盡皆知。");
}
}
③妙計(jì)二
public class StrategyTwo implements Strategy {
@Override
public void carryOut() {
System.out.println("用謊言(曹操打荊州)騙泡在溫柔鄉(xiāng)里的劉備回去慨丐。");
}
}
④妙計(jì)三
public class StrategyThree implements Strategy {
@Override
public void carryOut() {
System.out.println("讓孫夫人擺平東吳的追兵坡脐。");
}
}
⑤劉備使用妙計(jì)
public class Client {
public static void main(String[] args) {
//劉備一行人到達(dá)南徐的時(shí)候,打開(kāi)第一個(gè)錦囊
Strategy strategyOne=new StrategyOne();
strategyOne.carryOut();
//周瑜和孫權(quán)通過(guò)計(jì)謀使劉備沉迷在溫柔鄉(xiāng)無(wú)法自拔
Strategy strategyTwo=new StrategyTwo();
strategyTwo.carryOut();
//周瑜看計(jì)謀不行房揭,出兵攔殺劉備
Strategy strategyThree=new StrategyThree();
strategyThree.carryOut();
}
}
輸出的結(jié)果為:
//劉備一行人到達(dá)南徐的時(shí)候备闲,打開(kāi)第一個(gè)錦囊
見(jiàn)喬國(guó)老晌端,并把劉備娶親的事情搞得東吳人盡皆知。
//周瑜和孫權(quán)通過(guò)計(jì)謀使劉備沉迷在溫柔鄉(xiāng)無(wú)法自拔
用謊言(曹操打荊州)騙泡在溫柔鄉(xiāng)里的劉備回去恬砂。
//周瑜看計(jì)謀不行咧纠,出兵攔殺劉備
讓孫夫人擺平東吳的追兵。
忽略其他正常因素(諸葛亮不可能把錦囊交給劉備實(shí)施)泻骤,代碼角度分析這種方案帶來(lái)的問(wèn)題
錦囊使用是有前提的漆羔,要根據(jù)每個(gè)階段來(lái)使用對(duì)應(yīng)的錦囊,在編寫代碼中要清楚它們的順序狱掂,一旦出錯(cuò)就會(huì)造成劉備死翹翹演痒。這在面向?qū)ο蟮木幊讨惺菢O度地不適合,它根本就沒(méi)有完成一個(gè)類所具有的單一職責(zé)趋惨。
外界訪問(wèn)直接深入到子系統(tǒng)內(nèi)部鸟顺,相互之間是一種強(qiáng)耦合關(guān)系,這樣的強(qiáng)依賴是系統(tǒng)設(shè)計(jì)所不能接受的器虾。
子系統(tǒng)的內(nèi)部方法直接暴露給外部調(diào)用讯嫂,安全性低。
當(dāng)錦囊數(shù)越來(lái)越多的時(shí)候曾撤,那么Client就需要調(diào)用更多錦囊類來(lái)實(shí)現(xiàn)端姚,這就會(huì)增加Client的實(shí)現(xiàn)難度晕粪,維護(hù)更加困難挤悉。
四、趙云協(xié)助用妙計(jì)(門面模式)
諸葛亮能夠想到應(yīng)對(duì)之策巫湘,當(dāng)然也會(huì)考慮到讓誰(shuí)和如何實(shí)施這三個(gè)錦囊才能夠讓劉備順利化險(xiǎn)為夷装悲。綜合上面劉備親自實(shí)施錦囊妙計(jì)帶來(lái)的問(wèn)題,安排趙云保管錦囊并在適當(dāng)?shù)臅r(shí)機(jī)協(xié)助實(shí)施才是上上之策尚氛。
1.UML實(shí)現(xiàn)
增加了一個(gè)ZhaoYunFacadee類诀诊,負(fù)責(zé)對(duì)錦囊實(shí)施過(guò)程進(jìn)行封裝,然后高層模塊只要和它有交互就成阅嘶。
2.增加的代碼模塊
①趙云充當(dāng)門面
public class ZhaoYunFacade {
//妙計(jì)一
private Strategy strategyOne=new StrategyOne();
//妙計(jì)二
private Strategy strategyTwo=new StrategyTwo();
//妙計(jì)三
private Strategy strategyThree=new StrategyThree();
//三妙計(jì)統(tǒng)一讓趙云協(xié)助實(shí)施
public void carryOut(){
//劉備一行人到達(dá)南徐的時(shí)候属瓣,打開(kāi)第一個(gè)錦囊
strategyOne.carryOut();
//周瑜和孫權(quán)通過(guò)計(jì)謀使劉備沉迷在溫柔鄉(xiāng)無(wú)法自拔
strategyTwo.carryOut();
//周瑜看計(jì)謀不行,出兵攔殺劉備
strategyThree.carryOut();
}
}
劉備在遇到困難的時(shí)候讯柔,只要讓趙云根據(jù)諸葛亮的錦囊進(jìn)行處理抡蛙,這多簡(jiǎn)單,Client減少了很多工作魂迄。
②Client
public class Client {
public static void main(String[] args) {
//劉備遇到困難粗截,只要通過(guò)趙云按照錦囊實(shí)施,就可化險(xiǎn)為夷
ZhaoYunFacade zhaoYunFacade=new ZhaoYunFacade();
zhaoYunFacade.carryOut();;
}
}
輸出的結(jié)果為:
//劉備一行人到達(dá)南徐的時(shí)候捣炬,打開(kāi)第一個(gè)錦囊
見(jiàn)喬國(guó)老熊昌,并把劉備娶親的事情搞得東吳人盡皆知绽榛。
//周瑜和孫權(quán)通過(guò)計(jì)謀使劉備沉迷在溫柔鄉(xiāng)無(wú)法自拔
用謊言(曹操打荊州)騙泡在溫柔鄉(xiāng)里的劉備回去。
//周瑜看計(jì)謀不行婿屹,出兵攔殺劉備
讓孫夫人擺平東吳的追兵灭美。
運(yùn)行結(jié)果是相同的。場(chǎng)景類簡(jiǎn)化了很多选泻,只要與ZhaoYunFacade交互就成了冲粤,其他的什么都不用管,什么時(shí)候使用錦囊页眯、怎么用都不用管梯捕,只要調(diào)用ZhaoYunFacade提供的方法,就可以得到想要的妙計(jì)窝撵,這種方式不僅簡(jiǎn)單傀顾,而且擴(kuò)展性還非常好,同時(shí)不改變子系統(tǒng)對(duì)外暴露的接口碌奉、方法短曾,只改變內(nèi)部的處理邏輯,其他兄弟模塊的調(diào)用產(chǎn)生了不同的結(jié)果赐劣。
3.兩種方案的程序結(jié)構(gòu)圖
- 沒(méi)有采用門面模式
- 采用門面模式
總的來(lái)說(shuō)嫉拐,門面對(duì)象是外界訪問(wèn)子系統(tǒng)內(nèi)部的唯一通道,不管子系統(tǒng)內(nèi)部是多么雜亂無(wú)章魁兼。
五婉徘、門面模式的介紹
1.門面模式的定義
門面模式(Facade Pattern)也叫做外觀模式。要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過(guò)一個(gè)統(tǒng)一的對(duì)象進(jìn)行咐汞。門面模式提供一個(gè)高層次的接口盖呼,使得子系統(tǒng)更易于使用。
2.中介模式的角色介紹
Facade門面角色
客戶端可以調(diào)用這個(gè)角色的方法化撕。此角色知曉子系統(tǒng)的所有功能和責(zé)任几晤。一般情況下,本角色會(huì)將所有從客戶端發(fā)來(lái)的請(qǐng)求委派到相應(yīng)的子系統(tǒng)去植阴,也就說(shuō)該角色沒(méi)有實(shí)際的業(yè)務(wù)邏輯蟹瘾,只是一個(gè)委托類。subsystem子系統(tǒng)角色
可以同時(shí)有一個(gè)或者多個(gè)子系統(tǒng)掠手。每一個(gè)子系統(tǒng)都不是一個(gè)單獨(dú)的類憾朴,而是一個(gè)類的集合。子系統(tǒng)并不知道門面的存在惨撇。對(duì)于子系統(tǒng)而言伊脓,門面僅僅是另外一個(gè)客戶端而已。
3.門面模式的使用場(chǎng)景
為一個(gè)復(fù)雜的模塊或子系統(tǒng)提供一個(gè)供外界訪問(wèn)的接口。
為降低個(gè)人代碼質(zhì)量對(duì)整體項(xiàng)目的影響風(fēng)險(xiǎn)报腔,只能在指定的子系統(tǒng)中開(kāi)發(fā)株搔,然后再提供門面接口進(jìn)行訪問(wèn)操作。
子系統(tǒng)相對(duì)獨(dú)立——外界對(duì)子系統(tǒng)的訪問(wèn)只要黑箱操作即可纯蛾。