设计模式(4)-外观模式(Facade)

本文介绍了外观模式,它通过提供一个简单的接口来隐藏复杂的内部逻辑。通过一个UML图展示了AirCondition、Fan、Light电器类如何通过Facade类简化调用。代码示例中,使用了Qt的LoginDlg类作为外观模式的应用,简化了界面设计和用户登录鉴权。文章鼓励读者分享对外观模式的理解,并提供了源码下载链接。
摘要由CSDN通过智能技术生成

【描述】外观模式通过在对必需的逻辑和方法的集合前创建简单的外观接口,隐藏来自调用的复杂性。

【UML图】

图1 外观模式UML图

(1) AirCondition、Fan、Light电器类定义了一个on和off的方法;

(2) Facade类定义了on和off的方法,并调用了AirCondition、Fan、Light类的on和off方法,隐藏调用的复杂性;

(3) 与组合模式的不同在于Facade和AirCondition、Fan、Light电器类是关联的关系,而不是组合的关系。

 

【示例代码】

aircondition.h

#ifndef AIRCONDITION_H
#define AIRCONDITION_H

class AirCondition
{
public:
    AirCondition();
    ~AirCondition();

public:
    void on();
    void off();
};

#endif // AIRCONDITION_H

 

aircondition.cpp

#include <QDebug>
#include "aircondition.h"

AirCondition::AirCondition()
{
    qDebug()<<"construct AirCondition";
}

AirCondition::~AirCondition()
{
    qDebug()<<"destruct AirCondition";
}

void AirCondition::on()
{
    qDebug()<<"AirCondition on";
}

void AirCondition::off()
{
    qDebug()<<"AirCondition off";
}


fan.h

#ifndef FAN_H
#define FAN_H

class Fan
{
public:
    Fan();
    ~Fan();

public:
    void on();
    void off();
};

#endif // FAN_H


fan.cpp

#include <QDebug>
#include "fan.h"

Fan::Fan()
{
    qDebug()<<"construct Fan";
}

Fan::~Fan()
{
    qDebug()<<"destruct Fan";
}

void Fan::on()
{
    qDebug()<<"Fan on";
}

void Fan::off()
{
    qDebug()<<"Fan off";
}


light.h

#ifndef LIGHT_H
#define LIGHT_H

class Light
{
public:
    Light();
    ~Light();

public:
    void on();
    void off();
};

#endif // LIGHT_H


light.cpp

#include <QDebug>
#include "light.h"

Light::Light()
{
    qDebug()<<"construct Light";
}

Light::~Light()
{
    qDebug()<<"destruct Light";
}

void Light::on()
{
    qDebug()<<"Light on";
}

void Light::off()
{
    qDebug()<<"Light off";
}


facade.h

#ifndef FACADE_H
#define FACADE_H

#include "aircondition.h"
#include "fan.h"
#include "light.h"

class Facade
{
public:
    Facade();
    ~Facade();

private:
    AirCondition *_airCondition;
    Fan *_fan;
    Light *_light;

public:
    void on();
    void off();
};

#endif // FACADE_H


facade.cpp

#include <QDebug>
#include "facade.h"

Facade::Facade()
{
    qDebug()<<"construct Facade";

    _airCondition = new AirCondition;
    _fan = new Fan;
    _light = new Light;
}

Facade::~Facade()
{
    qDebug()<<"destruct Facade";

    delete _airCondition;
    delete _fan;
    delete _light;
}

void Facade::on()
{
    qDebug()<<"Facade::on";

    _airCondition->on();
    _fan->on();
    _light->on();
}

void Facade::off()
{
    qDebug()<<"Facade::off";

    _airCondition->off();
    _fan->off();
    _light->off();
}


main.cpp

#include "facade.h"

int main(void)
{
    Facade *facade = new Facade;
    facade->on();
    facade->off();

    return 0;
}


【运行结果】

construct Facade 
construct AirCondition 
construct Fan 
construct Light 
Facade::on 
AirCondition on 
Fan on 
Light on 
Facade::off 
AirCondition off 
Fan off 
Light off

 

【结果分析】
Facade的on方法为电器类on方法的集合提供了接口,可以根据需要定义不同的on方法。

 

【实例剖析】

外观模式是我们常用的设计模式,有时候不知不觉就用到了。看下面一个登陆界面的设计实例。

先看UML图,

图2

(1) LoginDlg继承了QDialog类,实现用户登录鉴权;

(2) LoginDlg调用了QLabel、QLineEdit进行界面设计,界面设计的代码单独分离,构建了外观方法,提供给构造函数调用;

(3) 提供了cancel方法,cancel调用了QLineEdit相关对象的clear方法,实质上是一个外观打包。

 

【代码清单】

LoginDlg::LoginDlg()
{
    //qDebug()<<"construct_login";
    initDlg();
    initConnect();
}

LoginDlg::~LoginDlg()
{
    delete label_username;
    delete label_passwd;
    delete lineEdit_username;
    delete lineEdit_passwd;
    delete pushButton_ok;
    delete pushButton_cancel;

    //qDebug()<<"desstruct_login";
}

void LoginDlg::initDlg()
{
    setWindowFlags(Qt::FramelessWindowHint);
    label_username = new QLabel;
    label_username->setText(tr("用 户 名:"));
    label_passwd = new QLabel;
    label_passwd->setText(tr("用户密码:"));
    lineEdit_username = new QLineEdit;
    lineEdit_username->setFocus();
    lineEdit_passwd = new QLineEdit;
    lineEdit_passwd->setEchoMode(QLineEdit::Password);

    pushButton_ok = new QPushButton;
    pushButton_ok->setText(tr("确定"));
    pushButton_ok->setIcon(style()->standardIcon(QStyle::SP_DialogOkButton));
    pushButton_cancel = new QPushButton;
    pushButton_cancel->setText(tr("取消"));
    pushButton_cancel->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton));

    QGridLayout *gridLayout = new QGridLayout;
    gridLayout->addWidget(label_username,0,0);
    gridLayout->addWidget(lineEdit_username,0,1);
    gridLayout->addWidget(label_passwd,1,0);
    gridLayout->addWidget(lineEdit_passwd,1,1);

    QHBoxLayout *buttonLayout = new QHBoxLayout;
    buttonLayout->addStretch();
    buttonLayout->addWidget(pushButton_ok);
    buttonLayout->addStretch();
    buttonLayout->addWidget(pushButton_cancel);
    buttonLayout->addStretch();

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addLayout(gridLayout);
    mainLayout->addLayout(buttonLayout);
    mainLayout->addStretch();

    setLayout(mainLayout);
}

void LoginDlg::initConnect()
{
    connect(pushButton_cancel,SIGNAL(clicked()),this,SLOT(cancel()));
    connect(pushButton_ok,SIGNAL(clicked()),this,SLOT(Login()));
}

void LoginDlg::cancel()
{
    lineEdit_username->clear();
    lineEdit_passwd->clear();

    close();
}


LoginDlg类中initDlg、cancel方法,应用了外观模式。cancel方法运用了多态特性,覆盖了LoginDlg的父类QDialog的cancel方法,是LoginDlg类的一个私有槽函数。外观模式的应用使得构造函数更为清晰,initConnect方法更为简单。这时可以利用:

connect(pushButton_cancel,SIGNAL(clicked()),this,SLOT(cancel()));

来取代

connect(pushButton_cancel,SIGNAL(clicked()),lineEdit_username,SLOT(clear()));
connect(pushButton_cancel,SIGNAL(clicked()),lineEdit_passwd,SLOT(clear()));
connect(pushButton_cancel,SIGNAL(clicked()),this,SLOT(close()));


将界面设计的代码从构造函数中,单独分离,也是一种好的设计方式。

 

*对外观模式有更好的见解,欢迎留言,交流学习。

 

【源码下载】

Qt设计模式1-8测试源码:http://download.csdn.net/detail/tandesir/4984275
 声明:该源码仅供学习交流,勿用于商业目的。

 

转载请标明出处,仅供学习交流,勿用于商业目的

Copyright @ http://blog.csdn.net/tandesir

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值