设计模式系列之「门面模式」

《三国演义》中有曰:刘备、诸葛亮趁曹操赤壁之战失利,大肆扩充地盘,先后占领荆州大部地区,引起东吴孙权的警惕。为了限制刘备势力的发展,鲁肃奉命向刘备讨还荆州,但遭到拒绝。东吴大都督周瑜向孙权献计:趁刘备的甘夫人病故,用孙权的妹妹孙仁为诱饵,将刘备“赚到南徐,妻子不能勾得,幽囚在狱中”。 但是,这个诡计被诸葛亮一眼识破。他将计就计,让刘备“择日便去就亲”,并派赵云前去保护,并给了赵云三个锦囊,教赵云“依次而行”。结果,使东吴“赔了夫人又折兵”。此为诸葛亮的锦囊三妙计。

一、三妙计

妙计一:见乔国老,并把刘备娶亲的事情搞得东吴人尽皆知。

妙计二:用谎言(曹操打荆州)骗泡在温柔乡里的刘备回去。

妙计三:让孙夫人摆平东吴的追兵,她是孙权妹妹,东吴将领惧她三分。

二、妙计的两种实施方案

1.把三个锦囊直接交给刘备,让刘备根据情况打开锦囊。

2.把锦囊交给赵云,赵云按照诸葛亮的嘱咐,依次按照情况使用锦囊。

三、刘备用妙计

①妙计的接口

public interface Strategy {
    //妙计内容
    public void carryOut();
}

②妙计一

public class StrategyOne implements Strategy {

    @Override
    public void carryOut() {
        System.out.println("见乔国老,并把刘备娶亲的事情搞得东吴人尽皆知。");
    }
}

③妙计二

public class StrategyTwo implements Strategy {

    @Override
    public void carryOut() {
        System.out.println("用谎言(曹操打荆州)骗泡在温柔乡里的刘备回去。");
    }
}

④妙计三

public class StrategyThree implements Strategy {

    @Override
    public void carryOut() {
        System.out.println("让孙夫人摆平东吴的追兵。");
    }
}

⑤刘备使用妙计

public class Client {
    public static void main(String[] args) {
        //刘备一行人到达南徐的时候,打开第一个锦囊
        Strategy strategyOne=new StrategyOne();
        strategyOne.carryOut();
        //周瑜和孙权通过计谋使刘备沉迷在温柔乡无法自拔
        Strategy strategyTwo=new StrategyTwo();
        strategyTwo.carryOut();
        //周瑜看计谋不行,出兵拦杀刘备
        Strategy strategyThree=new StrategyThree();
        strategyThree.carryOut();
    }
}

输出的结果为:

//刘备一行人到达南徐的时候,打开第一个锦囊
见乔国老,并把刘备娶亲的事情搞得东吴人尽皆知。

//周瑜和孙权通过计谋使刘备沉迷在温柔乡无法自拔
用谎言(曹操打荆州)骗泡在温柔乡里的刘备回去。

//周瑜看计谋不行,出兵拦杀刘备
让孙夫人摆平东吴的追兵。

忽略其他正常因素(诸葛亮不可能把锦囊交给刘备实施),代码角度分析这种方案带来的问题

  • 锦囊使用是有前提的,要根据每个阶段来使用对应的锦囊,在编写代码中要清楚它们的顺序,一旦出错就会造成刘备死翘翘。这在面向对象的编程中是极度地不适合,它根本就没有完成一个类所具有的单一职责。

  • 外界访问直接深入到子系统内部,相互之间是一种强耦合关系,这样的强依赖是系统设计所不能接受的。

  • 子系统的内部方法直接暴露给外部调用,安全性低。

  • 当锦囊数越来越多的时候,那么Client就需要调用更多锦囊类来实现,这就会增加Client的实现难度,维护更加困难。

四、赵云协助用妙计(门面模式)

诸葛亮能够想到应对之策,当然也会考虑到让谁和如何实施这三个锦囊才能够让刘备顺利化险为夷。综合上面刘备亲自实施锦囊妙计带来的问题,安排赵云保管锦囊并在适当的时机协助实施才是上上之策。

1.UML实现

增加了一个ZhaoYunFacadee类,负责对锦囊实施过程进行封装,然后高层模块只要和它有交互就成。

2.增加的代码模块

①赵云充当门面

public class ZhaoYunFacade {
    //妙计一
    private Strategy strategyOne=new StrategyOne();
    //妙计二
    private Strategy strategyTwo=new StrategyTwo();
    //妙计三
    private Strategy strategyThree=new StrategyThree();

    //三妙计统一让赵云协助实施
    public void carryOut(){
        //刘备一行人到达南徐的时候,打开第一个锦囊
        strategyOne.carryOut();
        //周瑜和孙权通过计谋使刘备沉迷在温柔乡无法自拔
        strategyTwo.carryOut();
        //周瑜看计谋不行,出兵拦杀刘备
        strategyThree.carryOut();
    }
}

刘备在遇到困难的时候,只要让赵云根据诸葛亮的锦囊进行处理,这多简单,Client减少了很多工作。

②Client

public class Client {
    public static void main(String[] args) {
        //刘备遇到困难,只要通过赵云按照锦囊实施,就可化险为夷
        ZhaoYunFacade zhaoYunFacade=new ZhaoYunFacade();
    zhaoYunFacade.carryOut();;
    }   
}

输出的结果为:

//刘备一行人到达南徐的时候,打开第一个锦囊
见乔国老,并把刘备娶亲的事情搞得东吴人尽皆知。

//周瑜和孙权通过计谋使刘备沉迷在温柔乡无法自拔
用谎言(曹操打荆州)骗泡在温柔乡里的刘备回去。

//周瑜看计谋不行,出兵拦杀刘备
让孙夫人摆平东吴的追兵。

运行结果是相同的。场景类简化了很多,只要与ZhaoYunFacade交互就成了,其他的什么都不用管,什么时候使用锦囊、怎么用都不用管,只要调用ZhaoYunFacade提供的方法,就可以得到想要的妙计,这种方式不仅简单,而且扩展性还非常好,同时不改变子系统对外暴露的接口、方法,只改变内部的处理逻辑,其他兄弟模块的调用产生了不同的结果。

3.两种方案的程序结构图

  • 没有采用门面模式
  • 采用门面模式

总的来说,门面对象是外界访问子系统内部的唯一通道,不管子系统内部是多么杂乱无章。

五、门面模式的介绍

1.门面模式的定义

门面模式(Facade Pattern)也叫做外观模式。要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。

2.中介模式的角色介绍

  • Facade门面角色
    客户端可以调用这个角色的方法。此角色知晓子系统的所有功能和责任。一般情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就说该角色没有实际的业务逻辑,只是一个委托类。

  • subsystem子系统角色
    可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。子系统并不知道门面的存在。对于子系统而言,门面仅仅是另外一个客户端而已。

3.门面模式的使用场景

  • 为一个复杂的模块或子系统提供一个供外界访问的接口。

  • 为降低个人代码质量对整体项目的影响风险,只能在指定的子系统中开发,然后再提供门面接口进行访问操作。

  • 子系统相对独立——外界对子系统的访问只要黑箱操作即可。

六、门面模式优缺点

1.优点

减少系统的相互依赖。上面也提到不使用门面模式,外界访问直接深入到子系统内部,相互之间是一种强耦合关系这样的强依赖是系统设计所不能接受的,门面模式的出现就很好地解决了该问题,所有的依赖都是对门面对象的依赖,与子系统无关。

提高了灵活性。依赖减少了,灵活性自然提高了。不管子系统内部如何变化,只要不影响到门面对象,就没有什么问题了。

提高安全性。访问子系统的哪些业务就开通哪些逻辑,不需要把子系统的内部方法直接暴露给外部调用。

2.缺点

门面模式最大的缺点就是不符合开闭原则,对修改关闭,对扩展开放。系统投产后发现问题唯一能做的一件事就是修改门面角色的代码,这个风险相当大。

七、简单对比门面模式和中介模式的区别

1.从定义上,门面模式为复杂的子系统提供一个统一的访问界面,它定义的是一个高层接口,该接口使得子系统更加容易使用,避免外部模块深入到子系统内部而产生与子系统内部细节耦合的问题。中介者模式使用一个中介对象来封装一系列同事对象的交互行为,它使各对象之间不再显式地引用,从而使其耦合松散,建立一个可扩展的应用架构。

2.从功能上,门面模式只是增加了一个门面,它对子系统来说没有增加任何的功能,子系统若脱离门面模式是完全可以独立运行的。而中介者模式则增加了业务功能,它把各个同事类中的原有耦合关系移植到了中介者,同事类不可能脱离中介者而独立存在。

3.从关系上,对门面模式来说,子系统不知道有门面存在,而对中介者来说,每个同事类都知道中介者存在,因为要依靠中介者调和同事之间的关系,它们对中介者非常了解。

4.从封装程度上,门面模式是一种简单的封装,所有的请求处理都委托给子系统完成,而中介者模式则需要有一个中心,由中心协调同事类完成,并且中心本身也完成部分业务,它属于更进一步的业务功能封装。

八、总结

门面模式是一个很好的封装方法,一个子系统比较复杂时,比如算法或者业务比较复杂,就可以封装出一个或多个门面出来,项目的结构简单,而且扩展性非常好。还有,对于一个较大项目,为了避免人员带来的风险,也可以使用门面模式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 第一回 宴桃园豪杰三结义 斩黄巾英雄首立功 汉末十常侍为奸,朝政日非,人心思乱. 张角兄弟起事.百姓拥护,官军望风...
    JACKNPC阅读 36,810评论 2 12
  • 首先声明:我真的不是一个标题党。这个标题和今天要讲的常胜将军赵云赵子龙绝对是有关的,且听我慢慢八卦。。。。。...
    天外非仙阅读 1,918评论 5 12
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,820评论 1 15
  • 文/十月云 (一) 2004年春,一天早上刚上班,S医院导诊护士在大厅看到一对年轻夫妇带着一个4、5岁大的男孩,正...
    十月云阅读 1,457评论 12 48
  • 《成长心连心》引用体验式学习方法使学生、家长、老师体验到全面的教育发展,不单能够激发学生的内在潜力,同时亦可创...
    潘饶平阅读 161评论 0 0