JAVA设计模式 - 外观模式

JAVA设计模式 - 外观模式,第1张

JAVA设计模式 - 外观模式

章节目录
  • 什么是外观模式
  • 外观模式的结构
  • 外观模式的代码示例
    • 子系统1
    • 子系统2
    • 子系统3
    • 子系统4
    • 外观类1
    • 外观类2
    • 抽象外观类
    • 客户端
  • 外观模式的优缺点
    • 外观模式优点
    • 外观模式缺点

  本文参考自书籍《JAVA设计模式》

什么是外观模式

  外观模式是一种使用频率非常高的结构性设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互。为复杂的子系统提供一个统一的入口,使子系统和客户端之间耦合度降低。

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

外观模式的结构

外观模式的代码示例 子系统1
package facade;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;



public class FileReader {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileReader.class);

    
    public String read(String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            List fileLines = Files.readAllLines(Paths.get(fileName));
            for (String fileLine : fileLines) {
                stringBuilder.append(fileLine).append("n");
            }
        } catch (FileNotFoundException exception) {
            LOGGER.error("文件不存在");
        } catch (IOException exception) {
            LOGGER.error("解析文件失败", exception);
        }
        LOGGER.info("读取文件,获取明文:{}", stringBuilder);
        return stringBuilder.toString();
    }
}

子系统2
package facade;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;


public class FileWriter {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileWriter.class);

    
    public void writeFile(String fileName, String lines) throws IOException {
        LOGGER.info("写入文件:{} {}", fileName, lines);
        if (!Files.exists(Paths.get(fileName))) {
            Files.createFile(Paths.get(fileName));
        }
        Files.write(Paths.get(fileName), lines.getBytes(StandardCharsets.UTF_8));
    }
}

子系统3
package facade;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;


public class Md5EncryptionUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(Md5EncryptionUtil.class);

    private static final String KEY_MD5 = "MD5";

    public String encrypt(String baseString) throws Exception {
        byte[] digest = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
            digest = md5.digest(baseString.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException e) {
            LOGGER.error("未找到该加密算法", e);
        }
        return Optional.ofNullable(digest)
                .map(param -> new BigInteger(1, param).toString(16))
                .orElseThrow(() -> new Exception("加密失败"));
    }
}

子系统4
package facade;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;


public class ShaEncryptionUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ShaEncryptionUtil.class);

    private static final String KEY_SHA = "SHA";

    
    public String encryptSha(String data) throws NoSuchAlgorithmException {
        MessageDigest instance = MessageDigest.getInstance(KEY_SHA);
        instance.update(data.getBytes(StandardCharsets.UTF_8));
        return Arrays.toString(instance.digest());
    }
}

外观类1
package facade;


public class Md5EncryptFacade extends AbstractEncryptFacade {

    private static final String SPLIT = "\.";

    
    private final Md5EncryptionUtil md5EncryptionUtil;

    
    private final FileWriter fileWriter;

    
    private final FileReader fileReader;

    public Md5EncryptFacade() {
        fileWriter = new FileWriter();
        fileReader = new FileReader();
        md5EncryptionUtil = new Md5EncryptionUtil();
    }

    
    @Override
    public void fileEncrypt(String fileName) throws Exception {
        String content = fileReader.read(fileName);
        String encrypt = md5EncryptionUtil.encrypt(content);
        fileWriter.writeFile(convertToResultFileName(fileName), encrypt);
    }

    private String convertToResultFileName(String fileName) {
        String[] split = fileName.split(SPLIT);
        split[0] += "-result";
        return String.join(".", split);
    }
}

外观类2
package facade;


public class ShaEncryptFacade extends AbstractEncryptFacade {

    private static final String SPLIT = "\.";

    
    private final ShaEncryptionUtil shaEncryptionUtil;

    
    private final FileWriter fileWriter;

    
    private final FileReader fileReader;

    public ShaEncryptFacade() {
        fileWriter = new FileWriter();
        fileReader = new FileReader();
        shaEncryptionUtil = new ShaEncryptionUtil();
    }

    
    @Override
    public void fileEncrypt(String fileName) throws Exception {
        String content = fileReader.read(fileName);
        String encrypt = shaEncryptionUtil.encryptSha(content);
        fileWriter.writeFile(convertToResultFileName(fileName), encrypt);
    }

    private String convertToResultFileName(String fileName) {
        String[] split = fileName.split(SPLIT);
        split[0] += "-result";
        return String.join(".", split);
    }
}

抽象外观类
package facade;


public abstract class AbstractEncryptFacade {

    
    public abstract void fileEncrypt(String fileName) throws Exception;
}

客户端
package facade;


public class Client {

    public static void main(String[] args) throws Exception {
        AbstractEncryptFacade md5Facade = new Md5EncryptFacade();
        md5Facade.fileEncrypt("D:\documents\person\designPattern\md5Test.txt");
        System.out.println("MD5加密完成");

        AbstractEncryptFacade shaFacade = new ShaEncryptFacade();
        shaFacade.fileEncrypt("D:\documents\person\designPattern\shaTest.txt");
        System.out.println("SHA加密完成");
    }
}

外观模式的优缺点 外观模式优点
  1. 它对客户端屏蔽了子系统组件,减少了客户端需要处理的子对象数目,并使子系统使用起来更加容易,通过引入外观模式,客户端代码将变的很简单,与之关联的对象也很少。
  2. 它实现了子系统和客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
  3. 一个子系统的修改对其他子系统无影响,而且子系统内部变化也不会影响到外观对象。
外观模式缺点
  1. 不能很好的限制客户端直接使用子系统类,如果客户端对访问子系统类做太多的限制就减少了可变性和灵活性。
  2. 如果设计不当,增加新的子系统可能需要修改外观内的元外卖,违背了开闭原则。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5683000.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存