天天看点

C++装饰者模式

#ifndef CDECORATORMODE_H
#define CDECORATORMODE_H
#include<QDebug>
#include <iostream>
#include<string>
using namespace std;


#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << ":" << __func__ << "]"

/*
 * 装饰模式,动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
 */



class CDecoratorMode
{
public:
    CDecoratorMode();
};

//成绩单抽象基类
class ISchoolReport
{
public:
    ISchoolReport(void)
    {
    }
    virtual ~ISchoolReport(void)
    {
    }
    virtual void Report() = 0;
    virtual void Sign(string name) = 0;
};
//四年级成绩单
class CFouthGradeSchoolReport :
    public ISchoolReport
{
public:
    CFouthGradeSchoolReport(void);
    ~CFouthGradeSchoolReport(void);
    void Report();
    void Sign(string name);
};


//成绩单装饰基类
class CReportDecorator :
    public ISchoolReport
{
public:
    CReportDecorator(ISchoolReport *psr);
    virtual ~CReportDecorator(void);
    void Report();
    void Sign(string name);
private:
    ISchoolReport *m_pSchoolReport;
};


//成绩排名装饰者
class CSortDecorator :
    public CReportDecorator
{
public:
    CSortDecorator(ISchoolReport *psr);
    ~CSortDecorator(void);
    void Report();
private:
    void ReportSort();
};


//最高分装饰者
class CHighScoreDecorator :
    public CReportDecorator
{
public:
    CHighScoreDecorator(ISchoolReport *psr);
    ~CHighScoreDecorator(void);
    void Report();
private:
    void ReportHighScore();
};

int DecoratorTest();



#endif // CDECORATORMODE_H      
#include "cdecoratormode.h"

CDecoratorMode::CDecoratorMode()
{

}
CFouthGradeSchoolReport::CFouthGradeSchoolReport(void)
{
}
CFouthGradeSchoolReport::~CFouthGradeSchoolReport(void)
{
}
void CFouthGradeSchoolReport::Report()
{
    cout << "尊敬的XXX家长:" << endl;
    cout << "......" << endl;
    cout << "语文62  数学65  体育98  自然63" << endl;
    cout << "......" << endl;
    cout << "                家长签名:" << endl;
}
void CFouthGradeSchoolReport::Sign(string name)
{
    cout << "家长签名为:" << name.c_str() << endl;
}

CReportDecorator::CReportDecorator(ISchoolReport *psr)
{
    this->m_pSchoolReport = psr;
}
CReportDecorator::~CReportDecorator(void)
{
}
void CReportDecorator::Report()
{
    this->m_pSchoolReport->Report();
}
void CReportDecorator::Sign( string name )
{
    this->m_pSchoolReport->Sign(name);
}
CHighScoreDecorator::CHighScoreDecorator( ISchoolReport *psr ) : CReportDecorator(psr)
{
}
CHighScoreDecorator::~CHighScoreDecorator(void)
{
}
void CHighScoreDecorator::Report()
{
    this->ReportHighScore();
    this->CReportDecorator::Report();
}
void CHighScoreDecorator::ReportHighScore()
{
    cout << "这次考试语文最高是75, 数学是78, 自然是80" << endl;
}

CSortDecorator::CSortDecorator( ISchoolReport *psr ) : CReportDecorator(psr)
{
}
CSortDecorator::~CSortDecorator(void)
{
}
void CSortDecorator::ReportSort()
{
    cout << "我是排名第38名..." << endl;
}
void CSortDecorator::Report()
{
    this->CReportDecorator::Report();
    this->ReportSort();
}
//使用测试
static void DoIt()
{
    ISchoolReport *psr = new CFouthGradeSchoolReport();
    psr->Report();//看成绩单
    psr->Sign("老三");//很开心,就签字了
    delete psr;
}
static void DoNew()
{
    cout << "----------分部分进行装饰----------" << endl;
    ISchoolReport *psr = new CFouthGradeSchoolReport();//原装成绩单

    ISchoolReport *phsr = new CHighScoreDecorator(psr);//加了最高分说明的成绩单
    ISchoolReport *pssr = new CSortDecorator(phsr);//又加了成绩排名的说明
    pssr->Report();//看成绩单
    pssr->Sign("老三");//很开心,就签字了

    //先装饰哪个不重要,顺序已经在装饰内部确定好,但一定要调用最后一个装饰器的接口。
    //ISchoolReport *phsr = new CHighScoreDecorator(psr);//加了最高分说明的成绩单
    //ISchoolReport *pssr = new CSortDecorator(phsr);//又加了成绩排名的说明
    //pssr->Report();//看成绩单
    //pssr->Sign("老三");//很开心,就签字了

    delete pssr;
    delete phsr;
    delete psr;
}
int DecoratorTest()
{
    //在装饰之前,可以用继承的办法,来进行简单的修饰
//    DoIt();

    //但如果需要修饰的项目太多呢?或者装饰的项目不是固定的,继承显然会变得更复杂
    DoNew();
    return 0;
}