外观模式(Facade Pattern)

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/407 访问。

外观模式属于结构型模式,它隐藏了系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。

为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。

角色:

1、外观角色(Facade)

外观模式的核心,它被客户角色调用,它熟悉子系统的各项功能,可以在内部根据需求预定几种功能的组合;

2、子系统角色(SubSystem)

实现了子系统的功能,它内部可以有系统内的相互交互,也可以由供外界调用的接口。

示例:

命名空间FacadePattern中包含外观类Facade,提供公开的Handle方法,Haikwan是海关类,可以通过Apply方法从后台取得一个加密的完税凭证JSON数据,Decrypt类为解密类,可以解密海关的JSON数据,TaxProof则是完税凭证类,可以将JSON反序列化成一个对象,FileStore则将完税凭证数据持久化到文件中。本案例尝试通过一个从海关获取数据、解密、反序列化、保存到文件的完整流程来向大家简明扼要的阐述外观模式的使用。

namespace FacadePattern
public class Haikwan {public string Apply(Uri uri) {Console.WriteLine($"Apply some data from {uri.ToString()}!");return Const.TEMPLET_HAIKWAN;}}

海关类Haikwan,包含一个Apply方法可以从海关的后台获取一个加密的JSON数据。

public class Decrypt {public string Decipher(string ciphertext) {Console.WriteLine("Deciphering ciphertext!");Console.WriteLine(Const.LINE_BREAK);Console.WriteLine(ciphertext);Console.WriteLine(Const.LINE_BREAK);return ciphertext;}}

解密类Decrypt,将加密的JSON数据用Decipher方法解密成原始JSON数据。

public class TaxProof {public string TaxNo { get; private set; }public decimal Money { get; private set; }public DateTime PaymentData { get; private set; }public void Deserialize(string plaintext) {Console.WriteLine("Creating TaxProof Instance from plaintext!");TaxNo = "287361039374492-A01";Money = 1986.1020m;PaymentData = new DateTime(2018, 07, 20);}}

TaxProof完税凭证类,将JSON数据反序列化成实体对象,以便使用类的面向对象语言的优势进行后续的处理。

本例中没有真正实现反序列化的动作,仅仅作为一个演示使用了Hard Code。在实际开发过程中,推荐使用Newtonsoft.Json来处理序列化和反序列化。

public class FileStore {public void Store(TaxProof taxProof) {Console.WriteLine("Saving taxProof instance to file!");Console.WriteLine($"TaxProof.TaxNo = {taxProof.TaxNo},");Console.WriteLine($"TaxProof.Money = {taxProof.Money},");Console.WriteLine($"TaxProof.PaymentData = {taxProof.PaymentData}!");Console.WriteLine(Const.LINE_BREAK);}}

FileStore文件保存类,将完税凭证数据持久化到文件中。

public class Facade {private Haikwan _haikwan = null;private Decrypt _decrypt = null;private TaxProof _taxProof = null;private FileStore _fileStore = null;public Facade() {_haikwan = new Haikwan();_decrypt = new Decrypt();_taxProof = new TaxProof();_fileStore = new FileStore();}public void Handle(Uri uri) {var ciphertext = _haikwan.Apply(uri);var plaintext = _decrypt.Decipher(ciphertext);_taxProof.Deserialize(plaintext);_fileStore.Store(_taxProof);}}

Facade外观类,这是外观模式的核心类,首先在内部维持对海关类Haikwan、解密类Decrypt、完税凭证类TaxProof、文件保存类FileStore的引用,并在构造函数中创建它们,公开的Handle方法处理一个完整的从海关获取数据到持久化文件的完整流程。

public class Const {public const string TEMPLET_HAIKWAN = "{\r\n" +"  \"Haikwan\": {\r\n" +"    \"TaxNo\": \"287361039374492-A01\",\r\n" +"    \"Money\": 1986.1020,\r\n" +"    \"PaymentData\": \"\\/Date(1532099596)\\/\"\r\n" +"  }\r\n" +"}";public const string LINE_BREAK ="-------------------------------------------------------------";public const string HAIKWAN_URI ="http://@copyright#www.customs.gov.cn";}

Const常量类,统一管理本案例中用到的字符串资源。实际开发过程中不应当出现此类,请参考2017年阿里发布的《阿里巴巴Java开发手册》,此规则对C#开发者来说也应当遵守。

public class Program {private static Facade _facade = null;public static void Main(string[] args) {_facade = new Facade();_facade.Handle(new Uri(Const.HAIKWAN_URI));Console.ReadKey();}}

调用方的代码,仅仅需要一行代码就完成了一个完整的流程。以下是这个案例的输出结果:

Apply some data from http://@copyright/#www.customs.gov.cn!
Deciphering ciphertext!
-------------------------------------------------------------
{"Haikwan": {"TaxNo": "287361039374492-A01","Money": 1986.1020,"PaymentData": "\/Date(1532099596)\/"}
}
-------------------------------------------------------------
Creating TaxProof Instance from plaintext!
Saving taxProof instance to file!
TaxProof.TaxNo = 287361039374492-A01,
TaxProof.Money = 1986.1020,
TaxProof.PaymentData = 2018-07-20 00:00:00!
-------------------------------------------------------------

优点:

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/407 访问。

1、实现了子系统与客户端之间的松耦合关系;
2、客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。

缺点:

1、不符合开闭原则,如果要修改某一个子系统的功能,通常外观类也要一起修改;
2、没有办法直接阻止外部不通过外观类访问子系统的功能,因为子系统类中的功能必须是公开的(根据需要决定是否使用internal访问级别可解决这个缺点,但外观类需要和子系统类在同一个程序集内)。

使用场景:

1、设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式;
2、开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口;
3、维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。

C#设计模式之10-外观模式相关推荐

  1. 【白话设计模式二】外观模式(Facade)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  2. 从王者荣耀看设计模式(十.外观模式)

    ##从王者荣耀看设计模式(外观模式) 一.简介 王者荣耀是由多人协同开发而成,每个人负责游戏的一个或多个子功能,一个完整的功能是由很多已开发的子功能组合成的.我们要玩游戏时,只需要打开王者荣耀APP, ...

  3. 设计模式之【外观模式-Facade】

    外观模式(Facade) 外观模式是为了解决类与类之家的依赖关系的 像spring一样,可以将类和类之间的关系配置到配置文件中 而外观模式就是将他们的关系放在一个Facade类中 降低了类类之间的耦合 ...

  4. Java描述设计模式(12):外观模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在移动互联网没有普及之前,去饭店吃饭的流程大致如下:选座位,排队,点菜,结账.后来移动互联网普及,通过手机APP就 ...

  5. (原创)我眼中的设计模式系列之外观模式(二)

    外观模式的基本概念 首先,我们要先了解一下外观模式的基本概念.那到底什么是外观模式?其实就是基于很多模块或者很多子系统提供的一个最高层的接口,控制客户端访问我们的应用程序,减少客户端直接对内部应用程序 ...

  6. 设计模式学习笔记——外观模式

    外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 这种模式涉及 ...

  7. [学习笔记]设计模式[6]-{适配器模式外观模式}

    设计原则 最少知识原则:只和你的密友谈话 这个原则的意思是,在系统设计的过程中,不要让太多的类耦合在一起,免得对系统一部分的修改会影响到其他部分.在设计系统之前,应该首先注意对象与对象之间的交互关系, ...

  8. 设计模式之外观模式php,php设计模式(十五)外观模式

    外观模式又叫门面模式: 现在都是模块化开发了: 开发中很多时候都是在使用各种扩展包: 或者在外观模式中我们叫做子系统: 外观模式的作用就是减少子系统之间的耦合: 降低子系统的使用难度: 我们举个栗子: ...

  9. java设计模式之九外观模式(Facade)

    外观模式是为了解决类与类之家的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度,该模式中没有涉及到接口 ...

  10. 《研磨设计模式》chap3 外观模式Facade

    1. 场景1 客户自己装机,需要一一去买配件:cpu.主板... 找专业的公司,由公司去处理: 2. 场景2 代码生成工具有4个模块 client使用时依次创建3个对象 public class Cl ...

最新文章

  1. 队列(常用数据结构之一)
  2. Lua和C#调用探秘
  3. 一文详解Serverless架构模式
  4. bzoj4448 SCOI2015 情报传递 message
  5. C语言-目标文件/链接文件
  6. 深度学习开源项目学习
  7. Atitit.注解and属性解析(2)---------语法分析 生成AST attilax总结 java .net
  8. 廖雪峰python教程-廖雪峰Python教程的配套视频教程,全套完整版!
  9. python把英语句子成分字母_python把英语句子成分字母
  10. 杭州亲历重要时间点记录
  11. Modelsim搭建只有driver的UVM验证平台
  12. 人工智能(Artificial Intelligence-AI)、机器学习(Machine Learning)、深度学习(Deep Learning)之间区别
  13. 亚马逊多账户操作需要知道哪些规则
  14. 微信读书调整“时长兑书币”规则
  15. 两个向量夹角的cos值
  16. 计蒜客--天上的星星
  17. 打起来了,打起来了!!
  18. (私人收藏)红色项目工作计划总结汇报PPT模板
  19. map和对象之间的互相转换
  20. while else 循环

热门文章

  1. 转折后的总结--2014年找工作
  2. 【算法学习】B-Tree编程实现(C++模板类封装)
  3. 【Linux学习】linux源代码版本控制RCS
  4. 0515 银行转帐功能演练
  5. 动态数组的各种操作 0104 c#
  6. 控件的布局 1124
  7. css3的新增选择器 200303
  8. 崛起于Springboot2.X之Mysql读写分离(6)
  9. 应用Quick BI实现首购用户和用户首购的三种运营场景监控
  10. Laravel 支付宝SDK在Laravel5的封装