Answer.Geng 阅读(46) 评论(0)

模式简介


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

将一个系统拆分成若干个子系统,有利于子系统具有较强地可重用性,也更容易对子系统进行定制。但是与此同时增加了系统的复杂度,外观模式为子系统中较为通用的操作提供了一个简单的接口。如下所示,左图中客户端直接访问子系统,进行一系列复杂地调用,但是对于大多数用户来说,他们并不关心这些调用细节,只希望完成一些基本操作。右图为子系统提供了一个外观类Facade,这个类定义了一个统一的接口,客户端只需要与外观类进行通讯,从而降低了使用成本。

结构说明


角色说明

  • Facade

外观类,它知道哪些子系统负责处理请求,将客户端的请求传递给适当的子系统对象。

  • Subsystem Classes

子系统类,实现单个的功能,处理由Facade对象指派的任务。

工作原理

客户程序通过发送请求给Facade的方式与子系统通讯,Facade将调用信息传递给适当的子系统对象。使用Facade的客户程序不需要直接访问子系统对象。

示例分析


本节我们讲述一个很古老的问题,把大象放进冰箱,总共需要几步。

第一步:把冰箱门打开

第二步:把大象塞进去

第三步:把冰箱门关上

想想怎样通过程序来实现,这里我们会创建Refrigerator类以及Elephant类,分别代表子系统类。

class Refrigerator
{
    public void OpenTheDoor()
    {
        Console.WriteLine("Open the refrigerator door");
    }

    public void CloseTheDoor()
    {
        Console.WriteLine("close the refrigerator door");
    }
}

class Elephant
{
    public void PutIntoTheRefrigerator()
    {
        Console.WriteLine("put the elephant into the refrigerator");
    }
}

客户端调用:

class Program
{
    static void Main(string[] args)
    {
        Refrigerator refrigerator = new Refrigerator();
        refrigerator.OpenTheDoor();
        Elephant elephant = new Elephant();
        elephant.PutIntoTheRefrigerator();
        refrigerator.CloseTheDoor();
        Console.ReadLine();
    }
}

当然这样没有任何问题。只是我们的客户端并不需要知道这么多的细节,不需要知道Refrigerator类以及Elephant类,只知道我们有一个万能答题工具——AnswerFacade,只需要将问题抛给Facade类,它就能帮助我们回答。

class AnswerFacade
{
    private Refrigerator refrigerator = new Refrigerator();
    private Elephant elephant = new Elephant();

    public void Answer()
    {
        refrigerator.OpenTheDoor();
        elephant.PutIntoTheRefrigerator();
        refrigerator.CloseTheDoor();
    }
}

客户端调用:

class Program
{
    static void Main(string[] args)
    {
        AnswerFacade facade = new AnswerFacade();
        facade.Answer();
        Console.ReadLine();
    }
}

输出结果:

适用场景


  • 要为一个复杂的系统提供一个简单的接口。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。

  • 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
  • 在层次话结构当中,可以适用外观模式定义系统中每一曾的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合。

使用外观模式的优点


  • 对客户端隐藏了子系统组件,减少了客户端处理的对象的数量,使得子系统使用起来更加方便。

  • 实现了客户端与子系统之间的松耦合,子系统的组件修改不会直接影响到客户端,只需要调整外观类即可。
  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类,可根据需要直接对子系统类进行调用。