c#设计模式之:外观模式(Facade)
一、引言
在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ”门面“模式。下面就具体介绍下外观模式。
二、外观模式的详细介绍
2.1定义
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直接通过外观类来调用内部子系统中方法,从而外观模式让客户和子系统之间避免了紧耦合。
2.2 外观模式的结构图
介绍了外观模式的定义之后,让我们具体看看外观模式的由来以及实现,下面与学校中一个选课系统为例来解释外观模式,例如在选课系统中,有注册课程子系统和通知子系统,在不使用外观模式的情况下,客户端必须同时保存注册课程子系统和通知子系统两个引用,如果后期这两个子系统发生改变时,此时客户端的调用代码也要随之改变,这样就没有很好的可扩展性,下面看看不使用外观模式下选课系统的实现方式和客户端调用代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 不使用外观模式的情况
/// 此时客户端与三个子系统都发送了耦合,使得客户端程序依赖与子系统
/// 为了解决这样的问题,我们可以使用外观模式来为所有子系统设计一个统一的接口
/// 客户端只需要调用外观类中的方法就可以了,简化了客户端的操作
/// 从而让客户和子系统之间避免了紧耦合
/// </summary>
class Client
{
static void Main(string[] args)
{
SubSystemA a = new SubSystemA();
SubSystemB b = new SubSystemB();
SubSystemC c = new SubSystemC();
a.MethodA();
b.MethodB();
c.MethodC();
Console.Read();
}
} // 子系统A
public class SubSystemA
{
public void MethodA()
{
Console.WriteLine("执行子系统A中的方法A");
}
} // 子系统B
public class SubSystemB
{
public void MethodB()
{
Console.WriteLine("执行子系统B中的方法B");
}
} // 子系统C
public class SubSystemC
{
public void MethodC()
{
Console.WriteLine("执行子系统C中的方法C");
}
}
然而外观模式可以解决我们上面所说的问题,下面具体看看使用外观模式的实现:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
2
3
4
5
6
7
8
9
10
11
/// <summary>
/// 以学生选课系统为例子演示外观模式的使用
/// 学生选课模块包括功能有:
/// 验证选课的人数是否已满
/// 通知用户课程选择成功与否
/// 客户端代码
/// </summary>
class Student
{
private static RegistrationFacade facade = new RegistrationFacade(); static void Main(string[] args)
{
if (facade.RegisterCourse("设计模式", "Learning Hard"))
{
Console.WriteLine("选课成功");
}
else
{
Console.WriteLine("选课失败");
} Console.Read();
}
} // 外观类
public class RegistrationFacade
{
private RegisterCourse registerCourse;
private NotifyStudent notifyStu;
public RegistrationFacade()
{
registerCourse = new RegisterCourse();
notifyStu = new NotifyStudent();
} public bool RegisterCourse(string courseName, string studentName)
{
if (!registerCourse.CheckAvailable(courseName))
{
return false;
} return notifyStu.Notify(studentName);
}
} #region 子系统
// 相当于子系统A
public class RegisterCourse
{
public bool CheckAvailable(string courseName)
{
Console.WriteLine("正在验证课程 {0}是否人数已满", courseName);
return true;
}
} // 相当于子系统B
public class NotifyStudent
{
public bool Notify(string studentName)
{
Console.WriteLine("正在向{0}发生通知", studentName);
return true;
}
}
#endregion
使用了外观模式之后,客户端只依赖与外观类,从而将客户端与子系统的依赖解耦了,如果子系统发生改变,此时客户端的代码并不需要去改变。外观模式的实现核心主要是——由外观类去保存各个子系统的引用,实现由一个统一的外观类去包装多个子系统类,然而客户端只需要引用这个外观类,然后由外观类来调用各个子系统中的方法。然而这样的实现方式非常类似适配器模式,然而外观模式与适配器模式不同的是:适配器模式是将一个对象包装起来以改变其接口,而外观是将一群对象 ”包装“起来以简化其接口。它们的意图是不一样的,适配器是将接口转换为不同接口,而外观模式是提供一个统一的接口来简化接口。
三、外观的优缺点
3.1】、外观模式的优点:
(1)、外观模式对客户屏蔽了子系统组件,从而简化了接口,减少了客户处理的对象数目并使子系统的使用更加简单。
(2)、外观模式实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件是紧耦合的。松耦合使得子系统的组件变化不会影响到它的客户。
3.2】、外观模式的缺点:
(1)、如果增加新的子系统可能需要修改外观类或客户端的源代码,这样就违背了”开——闭原则“(不过这点也是不可避免)。
3.3】、在以下情况下可以考虑使用外观模式:
(1)、外一个复杂的子系统提供一个简单的接口
(2)、提供子系统的独立性
(3)、在层次化结构中,可以使用外观模式定义系统中每一层的入口。其中三层架构就是这样的一个例子。
四、总结
Facade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Facade很多时候更是一种架构设计模式。注意区分Facade模式、Adapter模式、Bridge模式与Decorator模式:
Facade模式注重简化接口
Adapter模式注重转换接口
Bridge模式注重分离接口(抽象)与其实现
Decorator模式注重稳定接口的前提下为对象扩展功能
c#设计模式之:外观模式(Facade)的更多相关文章
- 乐在其中设计模式(C#) - 外观模式(Facade Pattern)
原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...
- 8.4 GOF设计模式三: 外观模式 Facade
GOF设计模式三: 外观模式 Facade “现有系统”功能强大.复杂,开发“新系统”需要用到其中一部分,但又要增加一部 分新功能,该怎么办?4.1 Facade Pattern: Key Fea ...
- 二十四种设计模式:外观模式(Facade Pattern)
外观模式(Facade Pattern) 介绍为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.示例有一个Message实体类,某对象对它 ...
- [设计模式] 10 外观模式 facade
外观模式应该是用的很多的一种模式,特别是当一个系统很复杂时,系统提供给客户的是一个简单的对外接口,而把里面复杂的结构都封装了起来.客户只需使用这些简单接口就能使用这个系统,而不需要关注内部复杂的结构. ...
- 设计模式 笔记 外观模式 Facade
//---------------------------15/04/16---------------------------- //Facade 外观模式-----对象结构型模式 /* 1:意图: ...
- 设计模式之外观模式(Facade)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 【设计模式】—— 外观模式Facade
前言:[模式总览]——————————by xingoo 模式意图 外观模式主要是为了为一组接口提供一个一致的界面.从而使得复杂的子系统与用户端分离解耦. 有点类似家庭常用的一键开关,只要按一个键,台 ...
- 结构型设计模式之外观模式(Facade)
结构 意图 为子系统中的一组接口提供一个一致的界面,F a c a d e 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 适用性 当你要为一个复杂子系统提供一个简单接口时.子系统往往因 ...
- python : 设计模式之外观模式(Facade Pattern)
#为啥要用外观模式举例说明 这个例子很形象,直接从人家博客上贴过来的,参考链接在下面 不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶.茶具和开水,如图1(A)所示,而 ...
- 【UE4 设计模式】外观模式 Facade Pattern
概述 描述 外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.外观模式又称为门面模式,它是一 ...
随机推荐
- Embarcadero RAD Studio 2016 Product Approach and Roadmap
delphi 2016 路线图 http://community.embarcadero.com/article/news/16211-embarcadero-rad-studio-2016-pro ...
- JBPM4.4学习笔记
1.JBPM4表说明: JBPM4_DEPLOYMENT 流程定义表 JBPM4_DEPLOYPROP 流程定义属性表 JBPM4_EXECUTION 流程实例表 JBPM4_HIST_ACTINST ...
- DataTable相关
设置主键列: this.tableTestData.PrimaryKey = new DataColumn[] { this.tableTestData.Columns[0] };
- ABAP内表数据和JSON格式互转
本程序演示ABAP内表数据如何转为JSON格式,以及JSON数据如何放入内表. 注:json字符串格式如:jsonstr = '[ {flag: "0",message: &quo ...
- 利用fetch进行POST传参
fetch(config.host+"url",{ method:"POST", mode: 'cors',跨域请求 headers: { ...
- Java核心技术-异常、断言和日志
程序发生错误时至少做到以下几点: *向用户通告错误 *保存所有的工作结果 *允许用户以妥善的形式退出程序 Java使用一种称为异常处理的错误捕获机制处理异常. 本章第一部分介绍Java的异常,第二部分 ...
- Linux版本信息如何查询
1.输入"uname -a ",可显示电脑以及操作系统的相关信息.2.输入"cat /proc/version",说明正在运行的内核版本.3.输入"c ...
- loadrunner-27077报错解决办法
警告 -27077: “每次迭代模拟一个新用户”运行时设置为“开”时,“vuser_init”节将包含 Web 函数.这可能会产生具有多次迭代的不可预测结果 [MsgId: MWAR-27077] ...
- XSS的原理分析与解剖(第二篇)[转]
0×01 前言: 上节(http://www.freebuf.com/articles/web/40520.html)已经说明了xss的原理及不同环境的构造方法.本期来说说XSS的分类及挖掘方法. 当 ...
- Mosquitto 单向SSL配置
Mosquitto 单向SSL配置 摘自:https://blog.csdn.net/a_bcd_123/article/details/70167833 2017年04月14日 06:56:06 s ...