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