二十三种设计模式[10]

前言

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

模式

Facade_1

需要角色如下:

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

场景

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

Facade_2

示例

Facade_3

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)

原文地址:https://www.cnblogs.com/wxingchen/p/10078618.html