首页 > 编程语言 >Facade 外观模式简介与 C# 示例【结构型5】【设计模式来了_10】

Facade 外观模式简介与 C# 示例【结构型5】【设计模式来了_10】

时间:2023-12-27 20:25:06浏览次数:48  
标签:10 外观 示例 接口 public 模式 Facade 设计模式 子系统

Facade 外观模式简介与 C# 示例【结构型5】【设计模式来了_10】

 

阅读目录


回到顶部

〇、简介

1、什么是外观模式?

一句话解释:

  将一系列需要一起进行的操作,封装到一个类中,通过对某一个方法的调用,自动完成一系列操作。

外观模式是一种简单而又实用的设计模式,它的目的是提供一个统一的接口,使得客户端可以通过这个接口来访问子系统中的一组接口,而无需关心子系统中接口的具体实现。外观模式将子系统中的接口封装在一个外观类中,使得子系统的内部细节对客户端隐藏起来。

官方意图描述:为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

一个比喻:(课表与调休日)

  假如今天是周六需要补国庆放假周一的课,那么只需要公告一下,今天按周一的课表上课就行了,不需要逐一通知课表上的任课老师。此时‘周一的课’就是一个封装后的方法,调了这个方法后,就无需再调用每节课的任课老师,课表会进行一一对应。

2、外观模式的优缺点和适用场景

优点:

  • 提供了一个统一的接口:外观模式提供了一个统一的接口,使得客户端可以通过这个接口来访问子系统中的一组接口,而无需关心子系统中接口的具体实现。这样可以使得代码更容易理解和维护。
  • 隐藏子系统的复杂性:外观类将子系统的功能封装起来,客户端只需要调用外观类的方法即可完成操作,从而隐藏了子系统的复杂性。
  • 提高了代码的可扩展性:外观模式提供了一个统一的接口,使得客户端可以通过这个接口来访问子系统中的一组接口,而无需关心子系统中接口的具体实现。这样可以使得代码更容易扩展,当需要添加新的子系统时,只需要添加一个新的外观类即可。

缺点:

  • 增加了系统的复杂性:外观模式引入了外观类和子系统之间的依赖关系,使得系统的结构和实现变得更加复杂。
  • 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则:因此,在设计外观类时,需要考虑到将来可能会增加新的子系统,使得外观类的源代码可以容易地扩展。
  • 可能增加系统的耦合度:外观类和子系统之间的依赖关系可能会导致系统的耦合度增加,从而影响系统的可维护性和可测试性。
  • 可能降低系统的灵活性:由于外观类将子系统的功能封装起来,因此可能会限制客户端对子系统的定制和扩展。

适用场景:

  • 子系统复杂:当子系统的调用接口非常复杂时,可以使用外观模式来简化客户端与子系统之间的交互。
  • 层次复杂:当系统结构层次复杂时,每个层级都一个使用外观对象作为该层入口,可以简化层次间的调用接口。
  • 需要隐藏子系统的细节:当子系统的实现细节不应该被客户端直接访问时,可以使用外观模式来隐藏这些细节。
  • 需要降低耦合度:当客户端和子系统之间的耦合度太高时,可以使用外观模式来降低它们之间的耦合度。
回到顶部

一、外观模式的代码实现

下面是一个关于家庭影院HomeTheaterFacade的示例代码,假设整个影院由四部分(媒体播放器、低音炮、扬声器、遥控)组成,然后通过家庭影院类,将子系统的开关集成到一起,最终实现一键播放和关机:

  // 测试一下
  class Program
  {
  static void Main(string[] args)
  {
  HomeTheaterFacade homeTheaterFacade=new HomeTheaterFacade();
  homeTheaterFacade.PlayMovie();
  homeTheaterFacade.StopMovie();
  Console.ReadLine();
  }
  }
  public class HomeTheaterFacade // 家庭影院外观
  {
  private MediaPlayer mp; // 媒体播放机
  private Subwoofer subwoofer; // 低音炮
  private Amplifier amplifier; // 扬声器
  private RemoteControl remoteControl; // 无线遥控
  public HomeTheaterFacade()
  {
  mp = new MediaPlayer();
  subwoofer = new Subwoofer();
  amplifier = new Amplifier();
  remoteControl = new RemoteControl();
  }
  public void PlayMovie()
  {
  mp.Open();
  subwoofer.PowerOn();
  amplifier.PowerOn();
  remoteControl.Play();
  }
  public void StopMovie()
  {
  remoteControl.Stop();
  amplifier.PowerOff();
  subwoofer.PowerOff();
  mp.Close();
  }
  }
  public class MediaPlayer
  {
  public void Open()
  {
  Console.WriteLine("Opening the movie...");
  }
  public void Close()
  {
  Console.WriteLine("Closing the movie...");
  }
  }
  public class Subwoofer
  {
  public void PowerOn()
  {
  Console.WriteLine("Powering on the subwoofer...");
  }
  public void PowerOff()
  {
  Console.WriteLine("Powering off the subwoofer...");
  }
  }
  public class Amplifier
  {
  public void PowerOn()
  {
  Console.WriteLine("Powering on the amplifier...");
  }
  public void PowerOff()
  {
  Console.WriteLine("Powering off the amplifier...");
  }
  }
  public class RemoteControl
  {
  public void Play()
  {
  Console.WriteLine("Playing the movie...");
  }
  public void Stop()
  {
  Console.WriteLine("Stopping the movie...");
  }
  }

后续如果又想添加灯光效果,那可以再新增一个类,然后把开关也加在PlayMovie()StopMovie()两方法中即可。

回到顶部

二、结构

由上一章节的代码可类比出外观模式的结构:

Facade(HomeTheaterFacade):

  Facade 知道哪些子系统类负责处理请求,还可将客户的请求代理给适当的子系统对象。

SubsystemClasses 子系统类(MediaPlayer、Subwoofer、Amplifier、RemoteControl):

  包含子系统功能实现;处理由 Facade 对象指派的任务;没有 Facade 的任何相关信息,即没有指向 Facade 的指针。

回到顶部

三、相关模式

Abstract Factory 模式可以与 Facade 模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。Abstract Factory 也可以代替 Facade 模式隐藏那些与平台相关的类。

Mediator 模式与 Facade 模式的相似之处是,它抽象了一些已有的类的功能。然而,Mediator 的目的是对同类之间的任意通信进行抽象,通常集中不属于任何单个对象的功能。Mediator 的同类对象知道中介者并与它通信,而不是直接与其他同类对象通信。相对而言 Facade 模式仅对子系统对象的接口进行抽象,从而使它们更容易使用;它并不定义新功能,子系统也不知道 Facade 的存在。

通常来讲,仅需要一个 Facade 对象,因此 Facade 对象通常属于 Singleton 模式。

本文来自博客园,作者:橙子家,微信号:zfy1070491745,有任何疑问欢迎沟通,一起成长! 您的支持,博主的动力!

标签:10,外观,示例,接口,public,模式,Facade,设计模式,子系统
From: https://www.cnblogs.com/sexintercourse/p/17931347.html

相关文章

  • Builder 生成器模式简介与 C# 示例【创建型2】【设计模式来了_2】
    Builder生成器模式简介与C#示例【创建型2】【设计模式来了_2】 阅读目录〇、简介1、什么是生成器模式?2、优缺点和使用场景一、简单的示例代码二、生成器模式结构三、在.Net框架中的实际应用四、相关模式回到顶部〇、简介1、什么是生成器模式?一句话......
  • 18 aurora 8b10b回环测试
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述8B/10B编码是1983年由IBM公司的AlWidmer和PeterFranaszek所提出的数据传输编码标准,目前已经被广泛应......
  • Decorator 装饰者模式简介与 C# 示例【结构型4】【设计模式来了_9】
    Decorator装饰者模式简介与C#示例【结构型4】【设计模式来了_9】 阅读目录〇、简介1、什么是装饰者模式2、优缺点和适用场景一、通过示例代码简单实现二、装饰者模式的结构三、相关模式回到顶部〇、简介1、什么是装饰者模式一句话解释:  通过继承统......
  • 10 ADC模块FEP-DAQ9248采集显示波形方案
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述本方案通过把DAQ9248采集到的数据,通过示波器显示驱动进行在屏幕上显示ADC采集的波形数据。2系统框图......
  • openGauss学习笔记-175 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作
    openGauss学习笔记-175openGauss数据库运维-备份与恢复-导入数据-管理并发写入操作示例本章节以表test为例,分别介绍相同表的INSERT和DELETE并发,相同表的并发INSERT,相同表的并发UPDATE,以及数据导入和查询的并发的执行详情。CREATETABLEtest(idint,namechar(50),addressva......
  • [LeetCode Hot 100] LeetCode102. 二叉树的层序遍历
    题目描述思路方法一:递归/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.val=val;}*TreeNode(intval,TreeNodelef......
  • [LeetCode Hot 100] LeetCode543. 二叉树的直径
    题目描述思路所谓二叉树的直径,就是左右子树的最大深度之和。方法一:/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.val=va......
  • [LeetCode Hot 100] LeetCode104. 二叉树的最大深度
    题目描述思路熟练掌握二叉树的遍历算法方法一:层序遍历(迭代)+计数/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.val=val;......
  • [LeetCode Hot 100] LeetCode110. 平衡二叉树
    题目描述思路LeetCode104.二叉树的最大深度变种方法一:后序遍历(递归、dfs)/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.......
  • [LeetCode Hot 100] LeetCode111. 二叉树的最小深度
    题目描述思路二叉树的最小深度就是第一个叶子节点所在的层数方法一:前序遍历(递归、dfs)/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intva......