设计模式以外观模式

2018-09-20 01:33:12linux

外观模式(Facade Pattern)

  仍是用大话设计模式中的例子:股票和基金来讲明外观模式。股票买入者直接操做股票,他须要了解几千只股票的各类信息还须要预测它的涨跌,这样买入者和股票直接有着直接的联系,在软件开发种,这就是高耦合(模块和模块之间的联系过多)。买入基金,则由专业的基金经理人操做用户的资源,买入者只须要和基金经理人打交道,具体股票的细节,则由基金经理人来处理。ios

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

UML类图

其中:SubSystemOne、SubSystemTwo、SubSystemThree、SubSystemFour 构成了一个子系统。bash

Facade:外观类,知道哪些子系统,它们有哪些功能,通常Client把像子系统的请求委托给Facade,而后Facade再把这个请求转给适合的子系统对象。(System和Facade实际上是聚合关系,它们之间没有太多的耦合性)架构

SubSystem:子系统,子系统能够同时有多个,一个系统能够是类的集合或者是一个单独的类。每一个子系统能够单独被Client调用也能够被Facade调用,对于Client来讲它不知道有Facade的存在,Facade对子系统而言就是一个Client。ide

外观模式的优缺点

优势:函数

  1.Client只与Facade打交道,下降了Client代码的复杂度。spa

  2.下降了Client和System的耦合度,子系统有调整时不会影响到Client或者影响较小,可以经过调整Facade来适应子系统的改变。设计

  3.下降了大型软件中的编译依赖性,并简化了系统在不一样平台之间而定移植过程,由于设计良好的子系统,通常而言是相互独立的,一个系统的改变不会影响到其它子系统,而子系统的内部变化(指实现细节)也不会影响到外观,因此只须要编译有变化的子系统便可(对GCC编译器)。code

  4.模式仅提供了一个访问子系统的统一入口,可是并不阻止用户直接使用子系统类。

 

缺点:

  1.不能很好地限制Client使用子系统,若是要给Client添加使用限制,将多是整个模式丧失它的灵活性,也会增长其复杂度(试想一下为每一个子系统添加定制化的限制,在实现是将会有多复杂)

  2.在不引入抽象外观类(Facade)的状况下,增长子系统,要对应的调整Facade和Client(考虑下简单工厂模式),这会违背开放-封闭原则。

使用场景

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

代码示例

  问题模型:假设咱们在开发一个GUI程序,经过界面咱们可以产生一组通用数据,可是这组通用数据须要被不一样的子系统按需选择,并进行对应的处理。好比咱们能在bash终端输入不一样的命令调用不一样的处理程序。咱们假设这是一个外观模式(但真实的应用状况不是这样,由于,linux下的各类命令其实是由我的开发者自行开发的程序,在使用时,bash终端输入程序名 参数便可使用命令提供的服务)。那么如今main函数就是客户代码,S1表示调用子系统S1执行某种操做,S2表示调用S2执行某种操做等等。网上有个电商的例子,我以为比较好,它没有我这个这么理想化,子系统之间的数据没有耦合。

1.3个子系统

#ifndef SUBSYSTEMA_H_
#define SUBSYSTEMA_H_

#include <iostream>

class SubSystemA
{
public:
    void methodA()
    {
    std::cout << "I am SystemA!" << std::endl;
    }
    SubSystemA() = default;
    ~SubSystemA() = default;
};
#endif
SubSystemA
#ifndef SUBSYSTEMB_H_
#define SUBSYSTEMB_H_
#include <iostream>
#include <ctime>
class SubSystemB
{
public:
    void methodB()
    {
    auto systTime = time(nullptr);
        tm *struSysTime = localtime(&systTime);
    char szTime[16] = {0};
        sprintf(szTime,"%04d-%02d-%02d",struSysTime->tm_year+1990,struSysTime->tm_mon+1,struSysTime->tm_mday);
    std::cout << "Today is:" << szTime << std::endl;
    }
    SubSystemB() = default;
    ~SubSystemB() = default;
};
#endif
SubSystemB
#ifndef SUBSYSTEMC_H_
#define SUBSYSTEMC_H_

#include <iostream>
#include <ctime>

class SubSystemC
{
public:
    void methodC()
    {
    auto systTime = time(nullptr);
    tm *struSysTime = localtime(&systTime);
        char szTime[16] = {0};
        sprintf(szTime,"%02d:%02d:%02d",struSysTime->tm_hour,struSysTime->tm_min,struSysTime->tm_sec);
    std::cout << "Now Time is:"<< szTime << std::endl;
    }
    SubSystemC() = default;
    ~SubSystemC() = default;
};
#endif
SubsystemC

2.Facade外观类,也是这个模式的核心

#ifndef FACADE_H_
#define FACADE_H_
#include "SubSystemA.h"
#include "SubSystemB.h"
#include "SubSystemC.h"
#include <string>
class Facade
{
public:
    void noteSubSystem(const std::string strParam);
    Facade() = default;
    ~Facade() = default;
private:
    SubSystemA m_objSubSystemA;
    SubSystemB m_objSubSystemB;
    SubSystemC m_objSubSystemC;
};
#endif 

#include "Facade.h"

void Facade::noteSubSystem(const std::string strSystemName)
{
    if(strSystemName == "SubSystemA")
    m_objSubSystemA.methodA();
    else if(strSystemName == "SubSystemB")
    m_objSubSystemB.methodB();
    else if(strSystemName == "SubSystemC")
    m_objSubSystemC.methodC();
    else
    std::cout << "Param Error" << std::endl;
}    
Facade

3.客户端代码

#include "Facade.h"

using namespace std;

int main(int argc,char*argv[])
{
    if(argc != 2)
    {
    std::cout << "The count of param is Error!" <<std::endl;
    return (0);
    }
    std::string strParam = argv[1];
    Facade objFacade;
    objFacade.noteSubSystem(strParam);
    return (1);
}
Client

 

  外观模式的使用:

  1.在设计阶段就要有意识的把不一样的层分离(三层架构:数据访问层、业务逻辑层、表示层,在层与层之间创建外观Facade)

  2.开发阶段,子系统由于不断的重构变的愈来愈复杂。增长外观模式。能够提供一个简单的接口,减小它们之间的依赖

  3.为新系统开发一个外观Facade类,来提供设计粗糙或高度负责的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互全部的复杂工做。

 

 

 

 

 

 

 

d

相关文章
相关标签/搜索