【设计模式-7】门面模式(外观模式)的代码实现和应用场景

 门面模式,最简单的结构性设计模式,将多个不同的子系统逻辑封装起来,对外提供统一的调用接口。门面模式又叫做外观模式,可能是我们接触最多的模式,在开发中,可能不经意间就用到了门面模式。

1. 概述

门面模式 的官方定义是:客户端和多个子系统的通信会通过一个统一的外观角色进行,这个角色为子系统中的一组接口提供了一个一致的入口,它是一种结构性的设计模式

在这里插入图片描述
 根据单一职责的描述,在软件中会将一个系统划分成为若干个子系统,这有利于降低整个系统的复杂性。但多个系统之间存在同步或者异步的交互关系,拓扑结构极为复杂,为了解决这种情况,一个常见的设计方式便是引入一个外观的角色,使得外部客户端与子系统之间的相互依赖关系达到最小。

 门面模式是迪米特法则的最佳体现,引入一个新的外观角色可以降低系统的复杂度,同时也能降低客户类和子系统的耦合度。举个开发中常见的门面模式,controller层对多个数据表进行保存,会调用到多个表对应的service层,但是我们一般会在service层封装一个专用外观类来实现对多个表保存的逻辑,controller层只需要与这个外观类交互就可以。

 在门面模式中,通常存在两个角色:

  • 外观角色:与客户端交互的类,封装了子系统的交互逻辑,对外提供统一的访问入口。
  • 子系统:子系统是一个广义的概念,可以是一个类、一个功能模块或者是一个完整的子系统。子系统能够实现具体的功能。

2. 代码实现

 我们来看一个代码实现,需求是要求实现读取本地文件,加密后从新存储的功能。这个需求可以拆分成3个模块来实现,1.文件读取 → 2.内容加密 → 3.写入磁盘。如下是代码实现:

  • 1. 子系统
// 1.文件阅读
public class FileReader {
    // 文件读取
    public String read(String path) {
        StringBuffer stringBuffer = new StringBuffer();
        // 读取本地文件
        try (FileInputStream fileInputStream = new FileInputStream(path)) {
            // 获取流信息并且转为字符串返回
            int data;
            while ((data = fileInputStream.read()) != -1) {
                stringBuffer.append((char)data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuffer.toString();
    }
}

// 2.字符串加密
public class EncryptOperate {
    // AES算法加密
    public String encrypt(String content) {
        //随机生成密钥
        byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
        //构建
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        //加密为16进制表示
        String encryptHex = aes.encryptHex(content);
        return encryptHex;
    }
}

// 3.保存文件到本地
public class FileWriter {
    // 写入文件
    public void write(String encrypt, String path) {
        // 写入本地
        try (FileOutputStream outputStream = new FileOutputStream(path)) {
            outputStream.write(encrypt.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 2. 门面类
// 门面类
public class Facade {

    private FileReader fileReader;
    private EncryptOperate encryptOperate;
    private FileWriter fileWriter;

    Facade() {
        this.fileReader = new FileReader();
        this.encryptOperate = new EncryptOperate();
        this.fileWriter = new FileWriter();
    }
    // 文件操作
    public void operate(String path) {
        String content = fileReader.read(path);
        String encrypt = encryptOperate.encrypt(content);
        fileWriter.write(encrypt, "/user/xxx/file/设计模式.txt");
    }
}
  • 3. 客户端
// 客户端
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.operate("/user/xxx/file/设计模式.txt");
    }
}

3. UML类图

 根据上述代码实现,我们来画一下这个Demo的类图。
在这里插入图片描述

4. 抽象门面角色的引入

 在实际开发中,如果遇到多种门面类的实现场景,可以增加一个抽象的门面角色,让客户端与抽象的门面类交互。这样在遇到新的门面实现类时,不用修改原来的代码,增加一个实现就可以,也符合开闭原则。

5. 总结

 门面模式优点如下:

  • 门面模式对客户端屏蔽了子系统的复杂拓扑关系,使得客户端的调用逻辑简单直接,理解和改动的成本降低。
  • 子系统和客户端之间松耦合,当需要增加新的门面实现逻辑时,可以新增一整套子系统的逻辑实现,符合开闭原则。

 门面模式的应用场景:

  • slf4j门面模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值