首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

设计方式(5)-装饰模式(Decorator)

2012-07-29 
设计模式(5)-装饰模式(Decorator)【描述】不修改原代码的结构,通过装饰器给代码增加新功能。【UML图】图1 UML图

设计模式(5)-装饰模式(Decorator)

【描述】不修改原代码的结构,通过装饰器给代码增加新功能。

【UML图】

设计方式(5)-装饰模式(Decorator)

图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

 

 

 

 

 




 

 

 

 

 

热点排行