外观模式(Facade)

外观模式(Facade)

一、简介

1. 意图

外观模式就是给很多复杂的子系统(或系统中的一组接口)提供一个一致的界面,该模式定义了一个高层接口,这一接口使得子系统更加容易使用。

2. 举例

  • 电商购物:

    • 上层接口:用于下单、查看物流信息、确认收货的用户界面
    • 底层模块:供货商、仓库、包装、送货、支付处理、售后等
  • 智能家居:

    • 上层接口:可供用户操作的UI界面
    • 底层模块:电视、灯、空调、热水器、路由器

3. 结构

// 三个子系统类
class SubSys1
{
public:
    void func1 () {cout << "SubSys1 func1" << endl;}
}

class SubSys2
{
public:
    void func2 () {cout << "SubSys2 func2" << endl;}
}

class SubSys3
{
public:
    void func3 () {cout << "SubSys3 func3" << endl;}
}

// 外观类
class Facade
{
private:
    SubSys1 * subsys1;
    SubSys2 * subsys2;
    SubSys3 * subsys3;
public:
    Facade()
    {
    	subsys1 = new SubSys1();
		subsys2 = new SubSys2();
        subsys3 = new SubSys3();
    }
    ~Facade()
    {
        delete subsys1;
        delete subsys2;
        delete subsys3;
    }
    void funcA()
    {
        subsys1->func1();
        subsus2->func2();
    }
    void funcB()
    {
        subsus3->func3();
    }
}

// 客户端调用
int main()
{
    Facade * f = new Facade();
    f->funcA();
    f->funcB();
    return 0;
}

4 .适用性:

  • 为一个复杂子系统提供一个简单接口时,子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类,这使得子系统更具有可重用性,也更容易对子系统进行定制,但也给那些不需要定制子系统的用户带来一些使用上的困难。Facade可以提供一个简单的默认视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
  • 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性
  • 当需要构建一个层次结构的子系统时,使用Facade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,则可以让它们仅通过Facade进行通信,从而简化了它们之间的依赖关系

二、示例

  • 2022下半年下午

    Facade(外观)模式是一种通过为多个复杂子系统提供一个致的接口,而使这些子系统更加容易被访问的模式,以医院为例,就医时患者需要与医院不同的职能部门交互,完成挂号、门诊、取药等操作。为简化就医流程,设置了一个接待员的职位,代患者完成上述就医步骤,患者则只需与接待员交互即可。如图6-1给出了以外观模式实现该场景的类图。

#include <iostream>
#include <string>
using namespace std;

class Patient
{
public:
    virtual string getName() = 0; // (1)
};

class Disposer
{
public:
    virtual void dispose(Patient * patient) = 0; // (2)
};

class Registry : public Disposer // 挂号
{
public:
    void dispose (Patient * patient) override
    {
        cout << "I am registering..." << endl;
    }
};

class Doctor: public Disposer // 医生门诊
{ 
public:
   void dispose (Patient *patient) override
   {
       cout << "I am diagnosing..." << patient->getName() << endl;
   }
};

class Pharmacy : public Disposer // 取药
{
    void dispose (Patient * patient) override
    {
        cout << "I am giving medicine..." << patient->getName() << endl;
    }
}

class Facade
{
private:
    Patient * patient = nullptr;
public:
    Facade (Patient * patient) {this->patient = patient;}
    ~Facade () {delete patient;}
    void dispose()
    {
        Registry * registry = new Registry();
        Doctor * doctor = new Doctor();
        Pharmacy * ph = new Pharmacy();
        
        registry->dispose(patient);
        doctor->dispose(patient);
        ph->dispose(patient);
    }
}

class ConcretePatient : public Patient
{
private:
    string name;
public:
    ConcretePatient (string name) {this->name = name;}
    string getName() override {return name;}
}

int main()
{
    Patient * patient = new ConcretePatient("name"); // (3)
    Facade * /* 4 */ f = new Facade(patient); // (5)
    f->dispose(); // (6)
}
posted @ 2023-02-21 20:23  某科学的撒把豆子  阅读(230)  评论(0)    收藏  举报