zoukankan      html  css  js  c++  java
  • 外观模式(c++实现)

    外观模式

    模式定义

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

    模式动机

    • 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
    • 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
    • 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

    UML类图

    外观模式

    源码实现

    • hero.h
    #ifndef HERO_H
    #define HERO_H
    #include <QDebug>
    
    class Hero
    {
    public:
        Hero(QString name):m_Name(name){}
        ~Hero(){}
    
        inline void ZhongDan() { qDebug() << m_Name << " 中单";}
        inline void DaYe() { qDebug() << m_Name << " 打野";}
        inline void FuZhu() { qDebug() << m_Name << " 辅助";}
        inline void FaYu() { qDebug() << m_Name << " 发育";}
        inline void KangYa() { qDebug() << m_Name << " 抗压";}
    protected:
        QString m_Name;
    };
    
    class ZhenJi : public Hero
    {
    public:
        ZhenJi():Hero("甄姬"){}
        ~ZhenJi(){}
    };
    
    class ZhaoYun : public Hero
    {
    public:
        ZhaoYun():Hero("赵云"){}
        ~ZhaoYun(){}
    };
    
    class XiangXiang : public Hero
    {
    public:
        XiangXiang():Hero("大小姐"){}
        ~XiangXiang(){}
    };
    
    class LianPo : public Hero
    {
    public:
        LianPo():Hero("廉颇"){}
        ~LianPo(){}
    };
    
    class LvBu : public Hero
    {
    public:
        LvBu():Hero("吕布"){}
        ~LvBu(){}
    };
    
    #endif // HERO_H
    
    
    • facade.h
    #ifndef FACADE_H
    #define FACADE_H
    /************************************
        * @brief	: 用外观模式封装几个不同的子系统,
        * 子系统的操作统一放到外观模式的方法去
        * 峡谷系统安排:
        * 外观类:游戏不同的阵容组合
        * 英雄类:不同的英雄,可以打不同的位置
        * 外观类组合不同的英雄,得到一个胜率值
        * @author	:   wzx
        * @date	:   2020-04-17
        * @project	:  Facade
    *************************************/
    #include "hero.h"
    
    class Facade
    {
    public:
        Facade();
        ~Facade();
        double LineUpA();
        double LineUpB();
        double LineUpC();
    
    private:
        XiangXiang* m_XX;
        ZhaoYun*    m_ZY;
        LvBu*   m_LB;
        LianPo* m_LP;
        ZhenJi* m_ZJ;
    };
    
    #endif // FACADE_H
    
    
    • facade.cpp
    #include "facade.h"
    #define DELEOBJECT(x) if(x == nullptr) { delete x; x = nullptr;}
    Facade::Facade()
    {
        m_XX = new XiangXiang();
        m_ZY = new ZhaoYun();
        m_LB = new LvBu();
        m_LP = new LianPo();
        m_ZJ = new ZhenJi();
    }
    
    Facade::~Facade()
    {
        DELEOBJECT(m_XX);
        DELEOBJECT(m_ZY);
        DELEOBJECT(m_LB);
        DELEOBJECT(m_LP);
        DELEOBJECT(m_ZJ);
    }
    
    double Facade::LineUpA()
    {
        m_XX->FaYu();
        m_ZY->DaYe();
        m_LB->KangYa();
        m_LP->FuZhu();
        m_ZJ->ZhongDan();
        return 0.88;
    }
    
    double Facade::LineUpB()
    {
        m_XX->FaYu();
        m_ZY->KangYa();
        m_LB->DaYe();
        m_LP->FuZhu();
        m_ZJ->ZhongDan();
        return 0.40;
    }
    
    double Facade::LineUpC()
    {
        m_XX->FaYu();
        m_ZY->DaYe();
        m_LB->ZhongDan();
        m_LP->KangYa();
        m_ZJ->FuZhu();
        return 0.60;
    }
    
    
    • main.cpp
    #include <QCoreApplication>
    #include "facade.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Facade facade;
        qDebug() << "胜率" << facade.LineUpA()*100 << "%" << endl;
        qDebug() << "胜率" << facade.LineUpB()*100 << "%" << endl;
        qDebug() << "胜率" << facade.LineUpB()*100 << "%" << endl;
        return a.exec();
    }
    
    
    • 运行结果

    "大小姐" 发育

    "赵云" 打野

    "吕布" 抗压

    "廉颇" 辅助

    "甄姬" 中单

    胜率 88 %

    "大小姐" 发育

    "赵云" 抗压

    "吕布" 打野

    "廉颇" 辅助

    "甄姬" 中单

    胜率 40 %

    "大小姐" 发育

    "赵云" 抗压

    "吕布" 打野

    "廉颇" 辅助

    "甄姬" 中单

    胜率 40 %

    优点

    外观模式的优点

    • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
    • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
    • 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
    • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
    • 完美的体现了依赖倒转原则和迪米特法则

    缺点

    外观模式的缺点

    • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
    • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

    参考《大话设计模式》和 https://design-patterns.readthedocs.io/zh_CN/latest/index.html

  • 相关阅读:
    OpenUrl 的跨平台实现
    通用性站点管理后台(Bee OPOA Platform)
    使用Lucene.net提升网站搜索速度整合记录
    ASP.NET MVC相关
    LeetCode:Copy List with Random Pointer
    ASP.NET交互Rest服务接口(Jquery的Get与Post方式)
    How to Prevent Cross-Site Scripting Attacks
    高性能网站建设指南
    异常
    soket.io.js + angular.js + express.js(node.js)
  • 原文地址:https://www.cnblogs.com/wzxNote/p/12718427.html
Copyright © 2011-2022 走看看