设计模式(5)-装饰模式(Decorator)
【描述】不修改原代码的结构,通过装饰器给代码增加新功能。
【UML图】
图1 UML图
(1) 原始代码为Component类,提供了operation操作;
(2) 装饰器为Decorator类,提供了扩展的operation功能;
(3) 注意与模板模式(#ifndef COMPONENT_H#define COMPONENT_Hclass Component{public: Component();public: virtual void operation();};#endif // COMPONENT_H
component.cpp
#include <QDebug>#include "component.h"Component::Component(){ qDebug()<<"construct Component";}void Component::operation(){ qDebug()<<"Base Function";}
decorator.h
#ifndef DECORATOR_H#define DECORATOR_H#include "component.h"class Decorator : public Component{public: Decorator(Component component);private: Component component;public: void operation();};#endif // DECORATOR_H
decorator.cpp
#include <QDebug>#include "decorator.h"Decorator::Decorator(Component component){ qDebug()<<"construct Decorator"; this->component = component;}void Decorator::operation(){ component.operation(); qDebug()<<"Extend Function";}
main.cpp
#include "component.h"#include "decorator.h"int main(void){ Component component; component.operation(); Decorator decorator(component); decorator.operation(); return 0;}
【运行结果】
construct Component Base Function construct Component construct Component construct Decorator Base Function Extend Function
【结果分析】
借助装饰器,在没有改变原始代码的前提下,给代码增加了新功能。
【实例剖析】
#ifndef QLINEEDITWITHIM_H#define QLINEEDITWITHIM_H#include <QLineEdit>#include "inputmethod.h"class QLineEditWithIM : public QLineEdit{public: QLineEditWithIM(QLineEdit *lineEdit); ~QLineEditWithIM();private: QLineEdit *lineEdit; InputMethod *im;public: void installIM();};#endif // QLINEEDITWITHIM_H
qlineeditwithim.cpp
#include "qlineeditwithim.h"QLineEditWithIM::QLineEditWithIM(QLineEdit *lineEdit){//#ifdef Q_WS_QWS im = new InputMethod; this->lineEdit = lineEdit;//#endif}QLineEditWithIM::~QLineEditWithIM(){ delete im;}void QLineEditWithIM::installIM(){//#ifdef Q_WS_QWS installEventFilter(im); connect(im->keyboard,SIGNAL(setvalue(QString)),this,SLOT(setText(QString)));//#endif}
login.h
#ifndef LOGIN_H#define LOGIN_H#include <QDialog>#include "qlineeditwithim.h"class QLabel;class QLineEdit;class QDialogButtonBox;class QLogin : public QDialog{ Q_OBJECTpublic: QLogin(); ~QLogin();public: QLabel *managerLabel; QLabel *passwdLabel; QLineEditWithIM *managerEdit; QLineEditWithIM *passwdEdit; QPushButton *okButton; QPushButton *cancelButton; QDialogButtonBox *buttonBox;signals: void Authorize();private slots: void login(); void cancel();};#endif // LOGIN_H
login.cpp
#include <QtGui>#include "login.h"QLogin::QLogin(){ managerLabel = new QLabel(tr("&Manager:")); QLineEdit *_managerEdit = new QLineEdit; managerEdit = new QLineEditWithIM(_managerEdit); managerEdit->installIM(); managerLabel->setBuddy(managerEdit); passwdLabel = new QLabel(tr("&Passwd:")); QLineEdit *_passwdEdit = new QLineEdit; passwdEdit = new QLineEditWithIM(_passwdEdit); passwdEdit->installIM(); passwdEdit->setEchoMode(QLineEdit::Password); passwdLabel->setBuddy(passwdEdit); okButton = new QPushButton(tr("&Login")); cancelButton = new QPushButton("&Cancel"); okButton->setDefault(true); buttonBox = new QDialogButtonBox; buttonBox->addButton(okButton, QDialogButtonBox::ActionRole); buttonBox->addButton(cancelButton, QDialogButtonBox::AcceptRole); connect(okButton, SIGNAL(clicked()), this, SLOT(login())); connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(managerLabel); topLayout->addWidget(managerEdit); QHBoxLayout *midLayout = new QHBoxLayout; midLayout->addWidget(passwdLabel); midLayout->addWidget(passwdEdit); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(topLayout); mainLayout->addLayout(midLayout); mainLayout->addWidget(buttonBox); mainLayout->setMargin(20); setLayout(mainLayout); managerEdit->setFocus(); QIcon icon; icon.addFile(QString::fromUtf8(":/new/main/picture/logo.png"), QSize(), QIcon::Normal, QIcon::Off); setWindowIcon(icon); setWindowTitle("Login");}QLogin::~QLogin(){ qDebug()<<"destruct login"; delete managerLabel; delete managerEdit; delete passwdLabel; delete passwdEdit; delete okButton; delete cancelButton;}/** Name : void login()* Type : slot* Func : login when authorize* In : Null* Out : Null*/void QLogin::login(){ qDebug()<<managerEdit->text(); qDebug()<<passwdEdit->text();}/** Name : void cancel()* Type : slot* Func : cancel login* In : Null* Out : Null*/void QLogin::cancel(){ managerEdit->clear(); passwdEdit->clear(); close();}
【分析】
(1) 与模板模式的关键区别在于,QLineEditWithIM引用了QLineEdit对象;
(2) 模板模式调用的代码为
QLineEditWithIM *managerEdit; managerEdit = new QLineEditWithIM;
装饰模式调用的代码为
QLineEdit *_managerEdit = new QLineEdit;managerEdit = new QLineEditWithIM(_managerEdit);managerEdit->installIM();
实质上,在模板模式中,我们并没有使用QLineEditWithIM提供的引用对象lineEdit。而运用模板模式调用也比较简单。可见,此处将QLineEdit想象为一个模板,运用模板模式更为合适。
【学习参考】
(1) Qt输入法设计(嵌入式)
(2) 设计模式(1)-模板模式(Template))
【实例下载】
http://download.csdn.net/detail/tandesir/4418929
转载请标明出处,仅供学习交流,勿用于商业目的
Copyright @ http://blog.csdn.net/tandesir