二十三种设计模式[10] - 外观模式(Facade Pattern)

前言

       外观模式,又称门面模式,对象结构型模式。在《设计模式 - 可复用的面向对象软件》一书中将之描述为“ 为系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 ”。

模式

Facade_1

需要角色如下:

  • Facade(门面):子系统为外部提供的入库,负责将外部的调用委派给子系统实现;
  • Subsystem(子系统);与Facade相互独立,负责功能的实现;

场景

       在日常生活中,我们经常接触到与外观模式相识的场景。比如操作系统就是电脑提供给我们的Facade,用来控制电脑执行相应的操作。苹果手机通过App Store下载APP,App Store就是提供给我们的Facade。如果没有这些,我们在使用电脑时就需要使用汇编来操作电脑,在下载APP时就需要分别去每个APP的官网下载。由于Facade的存在使得我们更加方便的与其它事物交互。

Facade_2

示例

Facade_3

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class AppA
{
    public void Download()
    {
        Console.WriteLine("寻找appA的下载地址");
        Console.WriteLine("访问appA的下载地址");
        Console.WriteLine("开始下载");
        Console.WriteLine("appA下载完毕");
    }
 
    public void Install()
    {
        Console.WriteLine("寻找appA的安装文件");
        Console.WriteLine("开始安装");
        Console.WriteLine("appA安装完毕");
    }
}
 
public class AppB
{
    public void Download()
    {
        Console.WriteLine("寻找appB的下载地址");
        Console.WriteLine("访问appB的下载地址");
        Console.WriteLine("开始下载");
        Console.WriteLine("appB下载完毕");
    }
 
    public void Install()
    {
        Console.WriteLine("寻找appB的安装文件");
        Console.WriteLine("开始安装");
        Console.WriteLine("appB安装完毕");
    }
}
 
public class AppStoreFacade
{
    private AppA _appA = null;
    private AppA appA
    {
        get
        {
            if(this._appA == null)
            {
                this._appA = new AppA()
            }
 
            return this._appA;
        }
    }
 
    private AppB _appB = null;
    private AppB appB
    {
        get
        {
            if(this._appB == null)
            {
                this._appB = new AppB()
            }
 
            return this._appB;
        }
    }
 
    public void DownloadAppA()
    {
        this.appA.Download();
        Console.WriteLine("---------");
        this.appA.Install();
    }
 
    public void DownloadAppB()
    {
        this.appB.Download();
        Console.WriteLine("---------");
        this.appB.Install();
    }
}
 
static void Main(string[] args)
{
    AppStoreFacade facade = new AppStoreFacade();
    facade.DownloadAppA();
    Console.ReadKey();
}

       如上所示,在Facade模式下,我们暴露给用户的只有一个AppStoreFacade类,用户只能通过该类使用该系统的某些功能时(比如下载APP),利用这个类使该系统对用户透明。

       在所有的设计模式中一直强调的就是“ 针对接口编程,而不是针对实现编程 ”。接口能够保证所有实现类的一致性,方便我们对其进行扩展。所以我们可以将AppStoreFacade抽象出一个接口,并通过一个抽象工厂 (Abstract Factory) 来获取Facade实例。这样做的好处是在需求发生变更时只需要增加新的Facade类以及对应的抽象工厂实例即可。并且在同时存在多个系统需要对外提供Facade时(比如在Android中同时存在多个应用市场类软件)能够使这几个系统对用户更加透明。

Facade_4

总结

       外观模式,就是把一个系统对外提供的操作进行封装让用户更加方便的使用,并且将用户与系统进行解耦,使系统的内部模块更容易扩展与维护。但用户方便使用的同时也牺牲了该系统对于用户的灵活性。

 

       以上,就是我对外观模式的理解,希望对你有所帮助。

       示例源码:https://gitee.com/wxingChen/DesignPatternsPractice

       系列汇总:https://www.cnblogs.com/wxingchen/p/10031592.html

       本文著作权归本人所有,如需转载请标明本文链接(https://www.cnblogs.com/wxingchen/p/10078618.html)

posted @   王兴Chen  阅读(254)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示