- A+
解决问题
装饰器模式用于解决继承无法解决的问题。如有个需求,要开发一个登录功能,涉及qq登录、微信登录、手机登录三种方式,此时就需要创建一个login接口类,并实现三个登录子类;但如果又有个新需求,希望在所有的登录界面上加一些前缀信息,这时候,需要将三个登录子类再继承一遍,实现前缀信息显示功能;如果再有个需求,希望再前缀的基础上再增加后缀功能,则需要每个子类再继承一遍,实现后缀信息显示功能,类图如下。这样就会导致一个问题:子类膨胀。装饰器模式就是用于解决这种问题的方法。
达到目的
三种登录方式的前缀显示和后缀显示功能,其实都是一样的,没有必要为每种登录方式都开发一个前缀显示和后缀显示功能,因此,我们可以将封装一个装饰器抽象类Decorate,继承LoginInterface,并实现login方法,并创建两个子类前缀子类和后缀子类,分别继承Decorate,使用时,将被装饰类传入各个装饰类,进而达到组合装饰的效果。
代码
- #include <QDebug>
- //接口
- class CView
- {
- public:
- virtual void Draw(){}
- };
- //抽象装饰类
- class CDecorate:public CView{
- public:
- CDecorate(CView* pView):m_pView(pView){}
- public:
- virtual void Draw()
- {
- m_pView->Draw();
- }
- private:
- CView* m_pView;
- };
- //装饰类1
- class CScrollBars:public CDecorate{
- public:
- CScrollBars(CView* pView):CDecorate(pView){}
- protected:
- //绘制滚动条
- void DrawScrollBar(){
- qDebug()<<Q_FUNC_INFO<<__LINE__;
- }
- public:
- virtual void Draw()
- {
- CDecorate::Draw();
- DrawScrollBar();
- }
- };
- //装饰类2
- class CBorder:public CDecorate{
- public:
- CBorder(CView* pView):CDecorate(pView){}
- protected:
- //绘制边框
- void DrawBorder(){
- qDebug()<<Q_FUNC_INFO<<__LINE__;
- }
- public:
- virtual void Draw()
- {
- CDecorate::Draw();
- DrawBorder();
- }
- };
- //上下文,被装饰对象
- class CTextView:public CView{
- public:
- CTextView(){
- }
- protected:
- virtual void DrawTextView(){
- qDebug()<<Q_FUNC_INFO<<__LINE__;
- }
- public:
- virtual void Draw()
- {
- CView::Draw();
- DrawTextView();
- }
- };
- int main(int argc, char *argv[])
- {
- CTextView* cTextView = new CTextView();
- CScrollBars* cScrollBars = new CScrollBars(cTextView);
- CBorder* cBorder = new CBorder(cScrollBars);
- cBorder->Draw();
- }