- 什么是外观模式
- 外观模式的结构
- 外观模式的代码示例
- 子系统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子系统2fileLines = 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(); } }
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加密完成"); } }外观模式的优缺点 外观模式优点
- 它对客户端屏蔽了子系统组件,减少了客户端需要处理的子对象数目,并使子系统使用起来更加容易,通过引入外观模式,客户端代码将变的很简单,与之关联的对象也很少。
- 它实现了子系统和客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
- 一个子系统的修改对其他子系统无影响,而且子系统内部变化也不会影响到外观对象。
- 不能很好的限制客户端直接使用子系统类,如果客户端对访问子系统类做太多的限制就减少了可变性和灵活性。
- 如果设计不当,增加新的子系统可能需要修改外观内的元外卖,违背了开闭原则。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)