Facade模式
外观模式又被称为门面模式。它是通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
其实在实际生活中,像服务员、前台人员等等都充当【外观角色】。因为有了服务员,比如我们可以直接向她点餐、直接让他添点茶水、直接问他厕所怎么走等等,服务员的角色就聚合了很多“子系统”的功能,对于客户(客户端)而言,就只需要知道找服务员即可。如果自己去一个一个的问具体的人(具体服务),是很不方便的而且繁杂的。

1、场景描述

上面描述了服务员角色, 我们就用代码来实现这一场景。比如一个餐厅的功能有如下几个:

  • 点餐
  • 添茶
  • 加汤

以上的各个功能,我们统一经过服务员来实现。

2、实现

  1. /// <summary>
  2. /// 点餐
  3. /// </summary>
  4. public class Order
  5. {
  6. public void Excute()
  7. {
  8. Console.WriteLine("点餐");
  9. }
  10. }
  11. /// <summary>
  12. /// 汤
  13. /// </summary>
  14. public class Soup
  15. {
  16. public void AddSoup()
  17. {
  18. Console.WriteLine("加汤");
  19. }
  20. }
  21. /// <summary>
  22. /// 茶水
  23. /// </summary>
  24. public class Tea
  25. {
  26. public void AddTea()
  27. {
  28. Console.WriteLine("添茶");
  29. }
  30. }
  31. /// <summary>
  32. /// 服务员
  33. /// </summary>
  34. public class Waiter
  35. {
  36. private Order order;
  37. private Soup soup;
  38. private Tea tea;
  39. public Waiter()
  40. {
  41. order = new Order();
  42. soup = new Soup();
  43. tea = new Tea();
  44. }
  45. /// <summary>
  46. /// 点餐
  47. /// </summary>
  48. public void Order()
  49. {
  50. order.Excute();
  51. }
  52. /// <summary>
  53. /// 加汤
  54. /// </summary>
  55. public void AddSoup()
  56. {
  57. soup.AddSoup();
  58. }
  59. /// <summary>
  60. /// 添茶
  61. /// </summary>
  62. public void AddTea()
  63. {
  64. tea.AddTea();
  65. }
  66. }
  67. // 客户端
  68. Waiter waiter = new Waiter();
  69. waiter.Order();
  70. waiter.AddTea();
  71. waiter.AddSoup();

3、优缺点

上面的代码中, 尽管子系统很多(点餐、添茶、加汤),但对于客户端而言,只需要知道服务员这个类即可。总结起来外观模式有如下优点:

  • 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它客户端
  • 屏蔽具体的实现细节

缺点就是:

  • 对于新增子系统,外观角色也会随之改变。在一定程度上违背了“开闭原则”

    4、应用场景

    其实对于外观模式我们平时用得很多,只要涉及到对多个子系统整合封装,提供统一接口的类基本都是外观模式。比如对多个数据库的调用统一封装等。 平时微服务中使用的Gateway网关其实也是一个外观模式。所以当我们需要封装多个子系统的时候就需要用到外观模式了。外观模式并没有那么高大上,只是有一个显得高大上的名字而已。