如何在不改变函数的情况下,此函数加上新功能,用装饰模式!
最近项目上碰到一个需求,所有的服务器与客户端通信的协议要加上时间戳的校验,已防止用户恶意修改时间。
我的天,现在的协议已经有50多条了,要改好多好多地方啊,有没有什么办法在不改变原先函数的情况下,增加这个相同的功能呢。
先看看模型。
class IAnimal { public: virtual void PrintMyName()=0; }; class Rabbit : public IAnimal { public: virtual void PrintMyName() { cout << "My Name is Rabbit"<<endl; } }; class Duck : public IAnimal { public: virtual void PrintMyName() { cout << "My Name is Duck" << endl; } }; class Tiger : public IAnimal { public: virtual void PrintMyName() { cout << "My Name is Tiger" << endl; } }; void test1() { cout << "which animal you like most:" << endl; cout << "1 for Rabbit 2 for Duck 3 for Tiger 4 for break" << endl; while(1) { int i; cin >> i; IAnimal* pBase = NULL; switch (i) { case 1: pBase = new Rabbit; break; case 2: pBase = new Duck; break; case 3: pBase = new Tiger; break; case 4: return; } if (pBase) { pBase->PrintMyName(); } } }
现在想改变这个PrintMyName(),经过不断摸索(其实也就一上午。。),发现装饰模式可行,并且改动量最少。
比如现在要加上fun功能。
改变基线如下:
class IAnimal { public: virtual void PrintMyName()=0; void fun() { cout << "please add fun " << endl; } };
增加装饰类!:
class Decorate :public IAnimal { public: Decorate(IAnimal* pBase) { m_pBase = pBase; } virtual void PrintMyName() { fun(); m_pBase->PrintMyName(); } private: IAnimal * m_pBase; };
这样就改变了PringMyName的功能。
如何使用呢?
void test2() { cout << "which animal you like most:" << endl; cout << "1 for Rabbit 2 for Duck 3 for Tiger 4 for break" << endl; while (1) { int i; cin >> i; IAnimal* pBase = NULL; switch (i) { case 1: pBase = new Rabbit; break; case 2: pBase = new Duck; break; case 3: pBase = new Tiger; break; case 4: return; } if (pBase) { pBase = &Decorate(pBase); //加上这一行!!!! pBase->PrintMyName(); } } }
只要加上一行就好啦!
自己运行下吧
int main(int argc, const char *argv[]) { test1(); test2(); int i; cin >> i; }