设计模式之外观模式

外观模式

外观模式的概念

外观模式(Facade),也叫“过程模式“。外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。

生活实例

比如说食堂的盘装套饭,一个盘子四个坑,一个装米饭,另外三个搭配不同的菜式。

解决的问题

假如有如下模块中的5个基础功能,对外封装成接口:

(图来源于漫画:设计模式之 “外观模式”

如果有一个需求,需要先调用接口1再调用接口2最后调用接口5。

后面又有需求,需要按照顺序先调用接口4,再调用接口2,最后调用接口5。

 

发现很麻烦,因为需求在不断变更,那么调用的内容也会变更。

解决方法如下:

(图来源于漫画:设计模式之 “外观模式”

将需要的接口组合成一个大的接口,大接口中包含子功能接口。

UML图

外观模式包含如下两个角色:

      (1) Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。

      (2) SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。

注意:子类中没有Facade的任何信息,即没有对Facade对象的引用。

示例

调用关系是:客户端类Client调用外观类Facade,外观类组合子系统类SubSystemA、SubSystemB.......

首先是子系统类SubSystemA、SubSystemB等。

public class SubSystemA {
    public void methodA() {
        System.out.println("调用SubSystemA类的methodA()方法!");
    }
}

接着是外观类Facade,对子系统接口的组合。

public class Facade {
    private SubSystemA ssa=new SubSystemA();
    private SubSystemB ssb=new SubSystemB();
    private SubSystemC ssc=new SubSystemC();
    private SubSystemD ssd=new SubSystemD();
    private SubSystemE sse=new SubSystemE();

    public void comboMethodA(){
        // 封装一个子接口
        ssa.methodA();
        ssd.methodD();
        sse.methodE();
    }

    public void comboMethodB(){
        // 再封装一个子接口
        ssb.methodB();
        sse.methodE();
        ssc.methodC();
    }
}

最后是客户端类Client,调用外观类的组合接口方法。

public class Client {
    public static void main(String[] args) {
        // 不需要知道子系统有几个接口,只需要外观类的组合接口即可。
        // 实例化外观类Facade
        Facade facade = new Facade();
        // 通过外观模式,调用组合接口A
        facade.comboMethodA();
        // 通过外观模式,调用组合接口B
        facade.comboMethodB();


        /* ------------------------下面是不使用外观模式,直接调用子系统类的代码----------------------- */
        // 相当于调用comboMethodA()
        SubSystemA ssa = new SubSystemA();
        ssa.methodA();
        SubSystemD ssd = new SubSystemD();
        ssd.methodD();
        SubSystemE sse = new SubSystemE();
        sse.methodE();
        // 相当于调用comboMethodB()
        SubSystemB ssb = new SubSystemB();
        ssb.methodB();
        sse.methodE();
        SubSystemC ssc = new SubSystemC();
        ssc.methodC();
    }
}

外观模式的总结

外观模式的优点:

  • 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。(因为Client只需要调用Facade类中的方法,不需要直接调用子系统类了)
  • 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
  • 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。

外观模式的缺点:

  • 不能很好地限制客户使用子系统类,很容易带来未知风险。
  • 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

外观模式的应用场景:

  • 在设计功能接口的初期,有意识的将不同的层分离开,比如在数据访问层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观类Facade,降低耦合。
  • 在开发阶段,子系统因为不断演化而变得越来越复杂,可以增加外观类Facade提供一个简单的接口,减少它们之间的依赖。
  • 在维护一个遗留的系统时,较难以维护,但又包含重要功能,新的需求必须要依赖它,可以为新系统开发一个外观类Facade,提供接口,通过新系统与Facade对象、Facade对象与遗留系统代码完成新系统与旧系统的交互工作。

总结:外观模式就是子系统的组合使用

参考链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值