专栏首页C++的沉思外观模式-分析和C++实现
原创

外观模式-分析和C++实现

外观模式结构

image.png
  1. Facade 定义子系统的多个模块对外的高层接口,通常需要调用内部的多个模块,从而把客户的请求代理给适当的子系统。
  2. 模块 接受Facade对象的委派,真正实现功能,各个模块之间可能有交互。但请注意,Facade对象知道各个模块,但是各个模块不应该知道Facade对象。

外观模式实例代码

由于上面外观模式的结构过于抽象,因此把它具体点。假设系统内有三个模块,分别是AModuleBModuleCModule,它们分别有一个示意的方法,那么整体结构如下图所示。

代码实现

#include <iostream>
#include <memory>

/**
 * A模块接口
 */ 
class AModuleApi {
public:
    virtual void testA() = 0;
    virtual ~AModuleApi() {}
};

/**
 * A模块接口具体实现
 */ 
class AModuleImpl : public AModuleApi {
public:
    void testA() override 
    {
        std::cout << "operate method testA in AModule" << std::endl;
    }
};

/**
 * B模块接口
 */ 
class BModuleApi {
public:
    virtual void testB() = 0;
    virtual ~BModuleApi() {}
};

/**
 * C模块接口具体实现
 */ 
class BModuleImpl : public BModuleApi {
public:
    void testB() override 
    {
        std::cout << "operate method testB in BModule" << std::endl;
    }
};

/**
 * C模块接口
 */ 
class CModuleApi {
public:
    virtual void testC() = 0;
    virtual ~CModuleApi() {}
};

/**
 * C模块接口具体实现
 */ 
class CModuleImpl : public CModuleApi {
public:
    void testC() override 
    {
        std::cout << "operate method testC in CModule" << std::endl;
    }
};

/**
 * 外观对象
 */ 
class Facade {
public:
    /**
     * 示意方法,满足客户需求的功能
     */ 
    static void test()
    {
        /**
         * 在内部实现的时候,可能会调用到内部的多个模块
         * 用智能指针new模块对象,其实可以用局部对象调用,
         * 考虑到模块对象可能比较大,担心占用栈空间过大
         */ 
        std::shared_ptr<AModuleApi> aptr(new AModuleImpl());
        aptr->testA();

        std::shared_ptr<BModuleApi> bptr(new BModuleImpl());
        bptr->testB();

        std::shared_ptr<CModuleApi> cptr(new CModuleImpl());
        cptr->testC();
    }
};

void test()
{
    Facade::test();
}

int main(int argc, char** argv)
{
    test();
    return 0;
}

运行结果:

operate method testA in AModule
operate method testB in BModule
operate method testC in CModule

以上例子,Facade类其实相当于ABC模块的外观界面,Facade类也被称为ABC模块对外的接口,那么客户端就不需要知道系统内部的实现细节,甚至客户端都不需要知道ABC模块的存在,客户端跟Facade类交互就好了,从而更好实现了客户端和子系统中ABC模块的解耦,让客户端更容易地使用系统。

外观模式的目的

外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散解耦,从而让外部能够更简单地使用子系统。这点要特别注意,因为外观是当做子系统对外接口的实现,虽然也可以在这里定义一些子系统没有到额功能,但不建议这么做。外观应该是包装已有的功能,它主要负责组合已有功能来实现客户需要,而不是添加新的实现。

外观模式的好处

能够选择性地暴露接口的方法,尽量减少子系统接口功能的暴露。一个模块的接口中定义的方法可以分为两部分,一部分是给子系统外部使用的,一部分是子系统内部的模块间相互调用时使用的。有了Facade接口,那么用于子系统内部的接口功能就不用暴露给子系统的外部。

外观接口的本质

封装交互,简化调用

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于zmq RPC简单C++实现

    需要启动rpc_server,然后启动rpc_client,请求Strcat和add返回结果:

    evenleo
  • 归并快排算法比较及求第K大元素

    核心思想:将数组从中间分成前后两部分,然后对前后两部分分别进行排序,再将排序好的两个部分有序合并在一起,这样整个数组有序。全文图示来源于王争的《数据结构和算法之...

    evenleo
  • C++多线程如何获取真正安全的单例

    如果你认为有两种可能,1、2和3、4的话,那说明你是按典型的程序员思维看问题的--没有像编译器和处理器一样处理问题。事实上, 1、4也是一种可能的结果。有两个基...

    evenleo
  • 外观模式

     外观模式又称为门面模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。我们还是用通俗的语言来解释这句话...

    用户1148394
  • 如何开发一款堪比APP的微信小程序(腾讯内部团队分享)

    一夜之间,微信小程序刷爆了行业网站和朋友圈,小程序真的能如张小龙所说让用户“即用即走”吗?其功能能和动辄几十兆安装文件的APP相比吗?开发小程序,是不是意味着...

    顶级程序员
  • LeetCode系列——两数之和

    石的三次方
  • 从技术小白到老司机,这20本书帮你“快进”20年

    导读:文艺复兴以来,源远流长的科学精神和逐步形成的学术规范,使西方国家在自然科学的各个领域取得了垄断性的优势;也正是这样的优势,使美国在信息技术发展的六十多年间...

    华章科技
  • 最接近的三数之和(leetcode16)

    给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假...

    Vincent-yuan
  • 事务 - 2PC

    在上一篇文章中我们介绍了本地事务,随着软件复杂度的上升,我们会需要一种可以在多个数据库之间完成事务(分布式事务)的方法,而这个方法也必须能够保证ACID。于是就...

    颇忒脱
  • git 合并两个仓库

    林德熙

扫码关注云+社区

领取腾讯云代金券