外观模式-提供统一入口

在办理流量套餐的时候,我们可以去官网查查询套餐,找出符合我们需求的套餐,然后进行办理。官网是充斥着各种各样的套餐,如果我们一个个去查看这些套餐,耗费的时间很多。而且在办理套餐的时候,步骤也比较多。而且假如有一天官网的规则或者界面改变的话,我们也不得不适应这些改变。

有个省事的办法:直接打电话给客服:"帮我办理最优惠的套餐"。这就是本文要讲的"外观模式"。

1 外观模式概述

又称为门面模式,客户端与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。(子系统可以是一个类、一个功能模块、系统的一个组成部分或者一个完整系统。)

外观角色将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观角色打交道,而不需要与子系统内部的很多对象打交道。

图 外观模式示意图

图 外观模式结构图

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

SubSystem,子系统角色。每个子系统可以不是一个单独的类,而是一个类的集合。每个子系统可以被客户端直接调用或者被外观角色调用。对于子系统而言,外观角色仅仅是另一个客户端而已。

复制代码
public class MenuService {

    public void search() {
        System.out.println("查询套餐");
    }

    public void detail() {
        System.out.println("套餐详情");
    }

    public void makeOrder() {
        System.out.println("办理套餐");
    }

}


public class Facade {

    private final MenuService menuService;

    private static class ClassHolder {
        private static final Facade instance = new Facade(new MenuService());
    }

    public static Facade getInstance() {
        return ClassHolder.instance;
    }

    private Facade(MenuService menuService) {
        this.menuService = menuService;
    }

    public void makeOrder() {
        menuService.search();
        menuService.detail();
        menuService.makeOrder();
    }
}

public class Client {

    public static void main(String[] args) {
        Facade instance = Facade.getInstance();
        instance.makeOrder();
//        运行结果:
//        查询套餐
//        套餐详情
//        办理套餐
    }

}

1.1 抽象外观类

在标准的外观模式结构图中,如果需要增加、删除或更换与外观类交互的子系统,必须修改外观类或客户端源代码,这违背了开闭原则。

通过引入抽象外观类来对系统进行改进。客户端可以针对抽象外观类进行编程,对于新的业务需求,不需要修改原有外观类,而对应增加一个新的外观类。

图 抽象外观模式结构图

1.2 补充说明

1)在很多情况下,为了节约资源,系统中只需要一个外观实例,可以通过单例模式来设计外观类。

2)一个系统中可以设计多个外观类,每个外观类都复杂和一些特定的子系统交互,向客户端提供相应的业务功能。

3)试图通过外观类为子系统增加新行为的做法是错误的。

2 优缺点

优点:

  1. 对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目并使得子系统使用起来更容易。
  2. 子系统与客户端之间松耦合,子系统变化不会影响到它的客户端,只需要调整外观类即可。

缺点:

  1. 不能很好地限制客户端直接使用子系统,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性。
  2. 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。

3 适用场景

  1. 要为访问一些列复杂的子系统提供一个简单入口时;
  2. 客户端程序与多个子系统之间存在很大的依赖性。
  3. 在层次结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。
相关推荐
Web极客码5 小时前
抵御隐蔽的慢速连接攻击:我用 Claude 编写 nftables 规则,精准压制 HTTP Slo
服务器·copilot
桌面运维家5 小时前
云桌面一个点位多少钱:IDV 云桌面按终端数还是并发数算预算
运维·虚拟化·云桌面
飞飞传输5 小时前
政府信创改造,怎样搭建安全可控的信创文件传输系统?
大数据·运维·安全
fanxiaohui121385 小时前
2026年长效耐用磁吸充电宝推荐|南孚传应解锁安心出游
服务器·人工智能·手机·电池·南孚传应
IT邦德5 小时前
BIC-QA如何重新定义数据库知识服务
运维·数据库
我命由我123456 小时前
Mac 操作系统 - 一些使用记录
运维·windows·学习·系统安全·运维开发·mac·学习方法
Gauss松鼠会6 小时前
GaussDB 系统表与系统视图详解(内网运维版)
运维·服务器·网络·数据库·gaussdb·经验总结
BJ_Bonree6 小时前
Bonree ONE·Sage AI「故障诊断助手」实测:从告警到根因,只要一句话
大数据·运维·人工智能·可观测性
小小de风呀7 小时前
de风——【从零开始学习Linux】(五):gcc编译器的基本使用
linux·运维·服务器
数智工坊7 小时前
RustDesk 自建服务器教程
运维·服务器