如何在不改變函數的狀況下,此函數加上新功能,用裝飾模式!

        最近項目上碰到一個需求,全部的服務器與客戶端通訊的協議要加上時間戳的校驗,已防止用戶惡意修改時間。服務器

        個人天,如今的協議已經有50多條了,要改好多好多地方啊,有沒有什麼辦法在不改變原先函數的狀況下,增長這個相同的功能呢。函數

        先看看模型。blog

        

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(),通過不斷摸索(其實也就一上午。。),發現裝飾模式可行,而且改動量最少。ci

好比如今要加上fun功能。it

改變基線以下:class

class IAnimal
{
public:
	virtual void PrintMyName()=0;

	void fun()
	{
		cout << "please add fun " << endl;
	}
};

 

增長裝飾類!:test

class Decorate :public IAnimal
{
public:
	Decorate(IAnimal* pBase) { m_pBase = pBase; }
	virtual void PrintMyName()
	{
		fun();
		m_pBase->PrintMyName();
	}
private:
	IAnimal * m_pBase;
}; 

 

這樣就改變了PringMyName的功能。gc

如何使用呢?im

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;
}  
相關文章
相關標籤/搜索