66设计模式基础概念(结构型模式):外观模式

概述

外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。

外观(Facade)模式又叫门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。

该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

结构

在这里插入图片描述

示例

下面是一些核心 Java 程序库中的外观示例:

  • javax.faces.context.FacesContext 在底层使用了 Life­Cycle、 View­Handler 和 Navigation­Handler 这几个类, 但绝大多数客户端不知道。
  • javax.faces.context.ExternalContext 在内部使用了 Servlet­Context、 Http­Session、 Http­Servlet­Request、 Http­Servlet­Response 和其他一些类。

识别方法: 外观可以通过使用简单接口, 但将绝大部分工作委派给其他类的类来识别。 通常情况下, 外观管理着其所使用的对象的完整生命周期

伪代码实现

外观 (Facade)

外观 (Facade) 提供了一种访问特定子系统功能的便捷方式, 其了解如何重定向客户端请求, 知晓如何操作一切活动部件。

interface Facade {
    public void method();
}

附加外观 (Additional Facade)

创建附加外观 (Additional Facade) 类可以避免多种不相关的功能污染单一外观, 使其变成又一个复杂结构。 客户端和其他外观都可使用附加外观。

//外观角色
class FacadeImpl1 implements Facede
{
    private SubSystem01 obj1=new SubSystem01();
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    public void method()
    {
        obj1.method1();
        obj2.method2();
        obj3.method3();
    }
}
//外观角色
class FacadeImpl1 implements Facede
{
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    private SubSystem04 obj4=new SubSystem04();
    public void method()
    {
        obj2.method2();
        obj3.method3();
        obj4.method4();
    }
}

复杂子系统 (Complex Subsystem)

复杂子系统 (Complex Subsystem) 由数十个不同对象构成。 如果要用这些对象完成有意义的工作, 你必须深入了解子系统的实现细节, 比如按照正确顺序初始化对象和为其提供正确格式的数据。

子系统类不会意识到外观的存在, 它们在系统内运作并且相互之间可直接进行交互。

//子系统角色
class SubSystem01
{
    public  void method1()
    {
        System.out.println("子系统01的method1()被调用!");
    }   
}
//子系统角色
class SubSystem02
{
    public  void method2()
    {
        System.out.println("子系统02的method2()被调用!");
    }   
}
//子系统角色
class SubSystem03
{
    public  void method3()
    {
        System.out.println("子系统03的method3()被调用!");
    }   
}
//子系统角色
class SubSystem04
{
    public  void method4()
    {
        System.out.println("子系统04的method4()被调用!");
    }   

客户端 (Client)

客户端 (Client) 使用外观代替对子系统对象的直接调用。

public class FacadePattern
{
    public static void main(String[] args)
    {
        Facade f=new FacadeImpl1();
        f.method();
        f=new FacadeImpl2();
        f.method();
    }
}

应用场景

如果你需要一个指向复杂子系统的直接接口, 且该接口的功能有限, 则可以使用外观模式。

子系统通常会随着时间的推进变得越来越复杂。 即便是应用了设计模式, 通常你也会创建更多的类。
尽管在多种情形中子系统可能是更灵活或易于复用的, 但其所需的配置和样板代码数量将会增长得更快。
为了解决这个问题, 外观将会提供指向子系统中最常用功能的快捷方式, 能够满足客户端的大部分需求。

如果需要将子系统组织为多层结构, 可以使用外观。

创建外观来定义子系统中各层次的入口。
你可以要求子系统仅使用外观来进行交互, 以减少子系统之间的耦合。

实现步骤

首先,考虑能否在现有子系统的基础上提供一个更简单的接口

如果该接口能让客户端代码独立于众多子系统类, 那么你的方向就是正确的。

其次,在一个新的外观类中声明并实现该接口

外观应将客户端代码的调用重定向到子系统中的相应对象处。
如果客户端代码没有对子系统进行初始化, 也没有对其后续生命周期进行管理, 那么外观必须完成此类工作。

之后,为了充分发挥这一模式的优势, 你必须确保所有客户端代码仅通过外观来与子系统进行交互

此后客户端代码将不会受到任何由子系统代码修改而造成的影响, 比如子系统升级后, 你只需修改外观中的代码即可。

最后,如果外观变得过于臃肿, 你可以考虑将其部分行为抽取为一个新的专用外观类

优缺点

优点:

  • 简化了调用过程,无需了解深入子系统,防止带来风险
  • 减少系统依赖、松散耦合
  • 更好的划分访问层次
  • 符合迪米特法则,即最少知道原则

缺点:

  • 增加子系统、扩展子系统行为容易引入风险
  • 不符合开闭原则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值