【设计模式】外观模式(Facade Pattern)

在这里插入图片描述

 

🔥 核心

外观模式为一组繁杂的接口提供了一个简洁的高层接口。

内部子系统的复杂性被隐藏,从外观看来简单易用。

 

🙁 问题场景

你在暑假里放飞自我,空调20度,零食一大堆,熬夜看比赛。

果不其然,你发烧了。你来到医院,却没想到烦心的事儿才刚刚开始。

因为医院是一个「复杂的系统」,因而采用的是“分而治之”的思想,将看病的过程分成了许多个「子系统」——挂号、候诊、门诊、化验、划价、取药、缴费…

顶着高烧,你在医院走廊里来回穿梭,在各个部门间反复横跳,在许多医生间不断周旋…

 

🙂 解决方案

真的是太麻烦了!你心里暗暗发出怒吼。

如果医院可以设置一个「接待员」,病人就仅仅需要和接待员一人沟通,由接待员负责在这么多繁杂的部门间进行交涉——那样该有多方便、多省心!

这就是外观模式。接待员是这个繁杂医院系统的简洁的、统一的、高层的接口,即医院的「外观」。

 

🌈 有趣的例子

电脑整机的开机过程(startup())和关机过程(shutdown())是十分复杂的。

但在实际生活中,我们并不需要了解电脑内部的系统结构,只需要按下电脑暴露出的 开机键关机键 即可。

在这里插入图片描述

 电脑组件(接口)
interface ComputerPart {
    void startup();
    void shutdown();
}

 处理器
class Cpu implements ComputerPart {
    public void startup() { System.out.println("CPU已启动 ^_^"); }
    public void shutdown() { System.out.println("CPU已关闭 >_<"); }
}
 显卡
class Rtx implements ComputerPart {
    public void startup() { System.out.println("显卡已启动 ^_^"); }
    public void shutdown() { System.out.println("显卡已关闭 >_<"); }
}

 内存
class Ddr implements ComputerPart {
    public void startup() { System.out.println("内存已启动 ^_^"); }
    public void shutdown() { System.out.println("内存已关闭 >_<"); }
}

 硬盘
class Ssd implements ComputerPart {
    public void startup() { System.out.println("硬盘已启动 ^_^"); }
    public void shutdown() { System.out.println("硬盘已关闭 >_<"); }
}


 电脑外观
class ComputerFacade {

    private Cpu cpu;
    private Rtx rtx;
    private Ddr ddr;
    private Ssd ssd;

    public ComputerFacade() {
        this.cpu = new Cpu();
        this.rtx = new Rtx();
        this.ddr = new Ddr();
        this.ssd = new Ssd();
    }

    public void startup() {
        System.out.println("电脑开始启动.........");
        cpu.startup();
        rtx.startup();;
        ddr.startup();
        ssd.startup();
        System.out.println("电脑启动完成!!!!!!!!!");
    }

    public void shutdown() {
        System.out.println("电脑开始关闭.........");
        cpu.shutdown();
        rtx.shutdown();
        ddr.shutdown();
        ssd.shutdown();
        System.out.println("电脑关闭完成!!!!!!!!!");
    }
}
public class FacadePatternDemo {
    public static void main(String[] args) {

        // 创建一个电脑外观
        ComputerFacade computerFacade = new ComputerFacade();

        // 开启电脑整机
        computerFacade.startup();
        // 关闭电脑整机
        computerFacade.shutdown();
    }
}
电脑开始启动.........
CPU已启动 ^_^
显卡已启动 ^_^
内存已启动 ^_^
硬盘已启动 ^_^
电脑启动完成!!!!!!!!!

电脑开始关闭.........
CPU已关闭 >_<
显卡已关闭 >_<
内存已关闭 >_<
硬盘已关闭 >_<
电脑关闭完成!!!!!!!!!

 

☘️ 使用场景

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

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

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

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

让我们回到视频转换框架的例子。该框架可以拆分为两个层次:音频相关和视频相关。你可以为每个层次创建一个外观,然后要求各层的类必须通过这些外观进行交互。这种方式看上去与中介者模式非常相似。

 

🧊 实现方式

(1)考虑能否在现有子系统的基础上提供一个更简单的接口。如果该接口能让客户端代码独立于众多子系统类,那么你的方向就是正确的。

(2)在一个新的外观类中声明并实现该接口。外观应将客户端代码的调用重定向到子系统中的相应对象处。如果客户端代码没有对子系统进行初始化,也没有对其后续生命周期进行管理,那么外观必须完成此类工作。

(3)如果要充分发挥这一模式的优势,你必须确保所有客户端代码仅通过外观来与子系统进行交互。此后客户端代码将不会受到任何由子系统代码修改而造成的影响,比如子系统升级后,你只需修改外观中的代码即可。

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

 

🎲 优缺点

  ➕ 你可以让自己的代码独立于复杂子系统。

  ➕ 提高了灵活性、安全性

  ➖ 外观可能成为与程序中所有类都耦合的上帝对象。

  ➖ 不符合开闭原则,增加新的子系统可能需要修改外观类或客户端的源代码。

 

🌸 补充

 我们无时无刻不在不经意间使用着外观模式。

 把众多接口整合在一起作为一个高层统一接口,是一个简单而优雅的做法。

 

🔗 参考网站

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值