设计模式(十)外观

一、定义

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

二、描述

包含以下两个角色: 1、Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统中去,传递给相应的子系统对象处理。
2、SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另一个客户端而已。

三、例子

X公司想要开发一个可应用于多个软件的文件加密模块,该模块可以对文件中的数据进行加密并将加密后的数据存储在一个新文件中,具体的流程包括3个部分,分别是读取源文件、加密、保存加密之后的文件。其中,读取文件和保存文件使用流来实现,加密操作通过求模运算实现。这3个操作相对独立,为了实现代码地独立重用,让设计更加符合单一职责原则,这3个操作的业务代码封装在3个不同的类中。 FileReader、CipherMachie、FileWriter:文件读取类、数据加密类、文件保存类,充当子系统类

C# 复制代码
public class FileReader
{
    public string Read(string fileNameSrc)
    {
        Console.WriteLine("读取文件,获取明文:");
        FileStream fs = null;
        StringBuilder sb = new StringBuilder();
        try
        {
            fs = new FileStream(fileNameSrc, FileMode.Open);
            int data;
            while ((data = fs.ReadByte()) != -1)
            {
                sb.Append((char)data);
            }
            fs.Close();
            Console.WriteLine(sb.ToString());
        }
        catch (FileNotFoundException e)
        {
            Console.WriteLine("文件不存在");
        }
        catch (IOException e)
        {
            Console.WriteLine("文件操作错误");
        }
        return sb.ToString();
    }
}

public class CipherMachine
{
    public string Encrypt(string plainText)
    {
        Console.WriteLine("数据加密,将明文转换为密文:");
        string es = "";
        char[] chars = plainText.ToCharArray();
        foreach (char ch in chars)
        {
            string c = (ch % 7).ToString();
            es += c;
        }
        Console.WriteLine(es);
        return es;
    }
}

public class FileWriter
{
    public void Write(string encryptedStr, string fileNameDes)
    {
        Console.WriteLine("保存密文,写入文件");
        FileStream fs = null;
        StringBuilder sb = new StringBuilder();
        try
        {
            fs = new FileStream(fileNameDes, FileMode.Create);
            byte[] str = Encoding.Default.GetBytes(encryptedStr);
            fs.Write(str, 0, str.Length);
            fs.Flush();
            fs.Close();
        }
        catch (FileNotFoundException e)
        {
            Console.WriteLine("文件不存在");
        }
        catch (IOException e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine("文件操作错误");
        }
    }
}

EncrytFacade:外观类

C# 复制代码
public class EncryptFacade
{
    private FileReader reader;
    private CipherMachine cipher;
    private FileWriter writer;

    public EncryptFacade()
    {
        reader = new FileReader();
        cipher = new CipherMachine();
        writer = new FileWriter();
    }

    public void FileEncrypt(string fileNameSrc, string fileNameDes)
    {
        string plainStr = reader.Read(fileNameSrc);
        string encryptedStr = cipher.Encrypt(plainStr);
        writer.Write(encryptedStr, fileNameDes);
    }
}

Program:客户端测试类

C# 复制代码
EncryptFacade facade = new EncryptFacade();
facade.FileEncrypt("src.txt", "des.txt");
Console.ReadLine();

四、总结

1、优点

(1)它对客户端屏蔽了子系统组件,减少了客户端需要处理的对象数目,并且使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
(2)它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
(3)一个子系统的修改对于其他子系统没有任何影响,而且子系统的内部变化也不会影响到外观对象。

2、缺点

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

相关推荐
长按助力退休1 分钟前
设计模式实战,这 5 个最常用
设计模式
Carl_奕然2 小时前
【智能体】Agent的四种设计模式之:Multi-Agent Collaboration
设计模式
Lost of 程序猿2 小时前
建造者模式实战:告别“十参数构造函数“的数据导出任务
后端·设计模式·c#·asp.net
SL_staff3 小时前
合规性折旧:当知识资产因主权缺位在审计中‘功能性清零’
java·设计模式·开源
Zane19947 小时前
工厂方法一定比简单工厂高级?三种工厂模式到底该怎么选
设计模式
Hespethorn7 小时前
设计模式是语言缺陷的补丁 —— 从工厂、单例、策略三个模式说起
设计模式
Lost of 程序猿7 小时前
命令模式实战:把“下单后的动作“打包成可执行的任务
后端·设计模式·c#·asp.net·命令模式
一只旭宝8 小时前
【C++复习】四种类型转换 + 常见设计模式 + Redis/MySQL(后端面试复习完整版)
c++·redis·笔记·mysql·设计模式
YYYing.9 小时前
【设计模式系列 (四) 】建造者模式
c++·后端·设计模式·建造者模式·c/c++
Zane19941 天前
同一段单例代码,为什么在高并发下偶尔会创建出两个实例?聊聊哪种单例实现才是真的安全
设计模式