zoukankan      html  css  js  c++  java
  • 如何在不改变函数的情况下,此函数加上新功能,用装饰模式!

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

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

      

  • 相关阅读:
    Ubuntu在用root账户使用xftp连接时提示拒绝连接
    Ubuntu设置root账户密码
    Ubuntu安装Nginx
    Ubuntu不能上网解决办法
    Ubuntu16.04修改静态ip地址
    Ubuntu下vi编辑器不听话
    thinkpad t420安装debian需要注意的细节
    debian7配置iptables
    debian的甘特图工具
    debian修改ssh端口
  • 原文地址:https://www.cnblogs.com/xuhuajie/p/9809610.html
Copyright © 2011-2022 走看看