• 第十三章·外观模式


    一、外观模式的概述

    在外观模式中,一个子系统的外部与其内部的通信通过一个统一的外观类进行,外观类将客户类与子系统的内部复杂性分隔开,是的客户类只需要与外观角色打交道,而不需要与子系统内部的很多对象打交道。

    外观模式的定义如下:
    外观模式:为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口这一子系统更加容易使用。

    二、外观模式的结构与实现

    2.1 外观模式的结构

    有两个角色:
    1,Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或多个)子系统的功能和责任;

    2,SubSystem(子系统角色):在软件系统中可以有一个或多个子系统角色,每一个子系统是一个类的集合,它实现子系统的功能;子系统可以被客户端直接调用,也可以被外观角色调用。

    2.2 外观模式的实现

    //子系统的代码案例

    /**
     * 模拟操作系统
     */
    public class OperatingSystem {
    
        /**
         * 模拟操作系统的载入
         */
        public void load(){
            System.out.println("开始载入操作系统...");
        }
    
    }
    
    /**
     * 模拟内存类
     */
    public class Memory {
    
        /**
         * 模拟内存的自检方法
         */
        public void check(){
            System.out.println("开始对内存进行自检...");
        }
    
    }
    
    /**
     * 模拟磁盘类
     */
    public class HardDisk {
    
        /**
         * 模拟磁盘的读取
         */
        public void read(){
            System.out.println("开启读取磁盘...");
        }
    
    }
    
    /**
     * 模拟CPU类
     */
    public class CPU {
    
        /**
         * 模拟CPU的运行
         */
        public void run(){
            System.out.println(1/0);
            System.out.println("开始运行CPU...");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    //外观角色的代码案例

    /**
     * 电脑主机
     * 外观类
     */
    public class Mainframe {
    
        private CPU cpu;
        private HardDisk hardDisk;
        private Memory memory;
        private OperatingSystem operatingSystem;
    
        public Mainframe() {
            cpu = new CPU();
            hardDisk = new HardDisk();
            memory = new Memory();
            operatingSystem = new OperatingSystem();
        }
    
        public void on() {
            try {
                hardDisk.read();
                operatingSystem.load();
                memory.check();
                cpu.run();
            } catch (Exception e) {
                throw new RuntimeException("电脑启动失败!");
            }
            System.out.printf("电脑启动成功!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    //客户端

    public class Client {
    
        public static void main(String[] args) {
    
            /**
             * 案例需求描述:
             * 在电脑主机Mainframe中只需要按下主机的开机按钮on(),即可调用其他硬件设备和软件的启动方法,
             * 如内存Memory的自检check()方法,CPU的运行run(),硬盘HardDisk的读取read(),操作系统OperatingSystem的载入load()等,
             * 如果某一个过程发生错误则电脑启动失败。
             * 试用外观模式模拟该过程。
             *
             */
    
            Mainframe mainframe = new Mainframe();
            mainframe.on();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    三、外观模式的优缺点和适用环境

    3.1 外观模式的优点

    1. 对客户端屏蔽了子系统组件,减少了客户端所需要处理的对象数目,并使得子系统使用起来更加容易;

    3.2 外观模式的缺点

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

    3.3 外观模式的适用环境

    1. 要为访问一系列复杂的子系统提供一个简单入口;
    2. 客户端程序与多个子系统之间存在很大的依赖性;
    3. 在层次化机构中可以使用外观模式定义系统每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

    【参考文献】:
    本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。

    【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git

  • 相关阅读:
    [SpringBoot系列]SpringBoot如何整合SSMP
    给字符串添加加粗标签(AC自动机+Python)
    vue源码分析-从new Vue开始
    动态数组底层是如何实现的
    基于模糊BP神经网络轨迹跟踪(Matlab代码实现)
    常用正则表达式(不定时更新)
    说一下 session 的工作原理?
    Netty从入门到实战
    生物安全柜检测与验证标准指南及验证设备选型建议
    计算机msvcp120.dll丢失?msvcp120.dll丢失5种简单的解决方法分享
  • 原文地址:https://blog.csdn.net/weixin_44143114/article/details/126514383