• 如何在不改变函数的情况下,此函数加上新功能,用装饰模式!


            最近项目上碰到一个需求,所有的服务器与客户端通信的协议要加上时间戳的校验,已防止用户恶意修改时间。

            我的天,现在的协议已经有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;
    }  
    

      

  • 相关阅读:
    Python内建GUI模块Tkinter(二)
    Python内建GUI模块Tkinter(一)
    验证码处理
    Python小练习
    Python中csv模块解析
    Python中xlutils解析
    Python中xlwt解析
    Python中pandas模块解析
    Python中matplotlib模块解析
    一款软件同时管理MySQL,MongoDB数据库
  • 原文地址:https://www.cnblogs.com/xuhuajie/p/9809610.html
Copyright © 2020-2023  润新知