zoukankan      html  css  js  c++  java
  • 【设计模式】穿什么有这么重要? 装饰模式

    一,定义

            英文名字:Decorator Pattern,又称装饰者模式。

            装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

     

    二,总结

            装饰模式什么时候实用?

            当系统需要新功能的时候,向旧的类中添加新的代码,而新的代码装饰了原有类的核心职责或主要行为。

            如果在主类中添加新的字段,新的方法和新的逻辑,从而增加了主类的复杂度。而这些新添加的类仅仅是满足特定情况的特殊需要。

            解决方案:装饰模式,把每个要装饰的功能放在单独的类中,并让这个类包装它要装饰的对象,因此要执行特殊行为时,客户端可以在运行时候有顺序,有选择的装饰包装对象。

     

     

    三,例子

             取自大话设计模式,小菜穿衣服。根据所穿不同衣服,穿衣服的顺序分析一个人风格?内裤内穿是普通人,内裤外穿是超人。

     

            1)小菜扮靓第一版

                  下面程序,通过控制台可以完成扮靓的基本衣服类型。

                   缺点:

                            如果要增加 “超人” 的装扮(内裤外穿),怎么办?

                            更改Person 类就违背了 开放 - 封闭原则,如何优化呢?把服饰写成子类,方便扩展衣物子类。

    #include <iostream>
    using namespace std;
    
    class Person
    {
    private:
    	string name;
    public:
    	Person(string Iname)//最好和 name 区分(不要再采用name) 
    	{
    		name = Iname; //name没有this 
    	}
    	~Person(){}
    	void WearTShirts()
    	{
    		cout<<"t恤"<<endl;
    	}
    	void WearBigTrouser()
    	{
    		cout<<"垮裤"<<endl;
    	}
    	void WearSneakers()
    	{
    		cout<<"破球鞋"<<endl;
    	}
    	void WearSuit()
    	{
    		cout<<"西装"<<endl;
    	}
    	void WearTie()
    	{
    		cout<<"领带"<<endl;
    	}
    	void WearLeaterShoes()
    	{
    		cout<<"皮鞋"<<endl;
    	}
    	
    	void show()
    	{
    		cout<<"装扮的"<<this->name<<endl; 
    	} 
    	
    };
    
    int main()
    {
    	Person xiaocai("小菜"); //没有new的创建对象方法  
    	cout<<"第一种装扮"<<endl;
    	
    	xiaocai.WearTShirts();
    	xiaocai.WearBigTrouser();
    	xiaocai.WearSneakers();
    	xiaocai.show();
    	
    	
    	Person *daniu =new Person("大牛"); //没有new
    	cout<<"第二种装扮"<<endl;
    	
    	daniu->WearSuit();
    	daniu->WearTie();
    	daniu->WearLeaterShoes();
    	daniu->show();
    		
    	 
    	return 0; 
    } 
    

                    2)小菜扮靓第二版

                          改进:增加了Finery 服饰抽象类,和各种具体服饰子类,方便了扩展各种服饰子类,而不必更改Person类,符合开放--封闭原则。

                          缺点:要显示穿的什么,还得在客户端dtx.show() //显示t恤 , kk.show() //显示垮裤。相当于光着身子在大庭广众之下穿衣服,如何改进?

                                      要内部组装完毕,然后显示出穿的什么来。这个貌似建造者模式(但是建造者模式要求建造过程是稳定的,这里可以内穿西装外套t恤)

     

    #include <iostream>
    using namespace std;
    
     
    class Person
    {
    public:
    	Person(string name)
    	{
    		m_Name = name;
    	};
    
    	void Show(void)
    	{
    		cout << "装扮的"<< m_Name <<endl;
    	};
    private:
    	string m_Name;
    };
    
    class Finery//服饰抽象类
    {
    public:
    	virtual void Show(void) = 0;
    };
    
    
    class TShirts :public Finery
    {
    public:
    	void Show(void)
    	{
    		cout << "大T恤" <<endl;
    	};
    };
    
    class BigTrouser :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "垮裤" <<endl;
    	};
    };
    
    class Sneakers :public Finery
    {
    public:
    	void Show(void)
    	{
    		cout << "破球鞋" <<endl;
    	};
    };
    
    class Suit :public Finery
    {
    public:
    	void Show(void)
    	{
    		cout << "西装" <<endl;
    	};
    };
    
    
    class Tie :public Finery
    {
    public:
    	void Show(void)
    	{
    		cout << "领带" <<endl;
    	};
    };
    
    class LeatherShoe :public Finery
    {
    public:
    	void Show(void)
    	{
    		cout << "皮鞋" << endl;
    	};
    };
    
    int main()
    {
    	Person* xiaocai = new Person("小菜");
    	Finery* dtx = new TShirts(); 
    	Finery* kk = new BigTrouser();
    	Finery* pqx = new Sneakers();
    
    	dtx->Show();
    	kk->Show();
    	pqx->Show();
    	xiaocai->Show();
    	return 0;
    }
    


                           3)小菜扮靓第三版

                            结构:Person类需要穿衣服,让抽象装饰类继承Person类。然后继承抽象服饰类,初始化服饰子类。

                            改进:相对于第二版,可以先将衣服穿好 (装饰过程)                          

     Sneakers* pqx = new Sneakers();
     BigTrouser* kk = new BigTrouser();
     TShirts* dtx = new TShirts();

     pqx->Decorator(xiaocai);
     kk->Decorator(pqx);
     dtx->Decorator(kk);

                                          然后再显示出来       dtx.show()

     

    #include <string>
    #include <iostream>
    
    class Person
    {
    public:
    	Person(std::string name)
    	{
    		m_name = name;
    	};
    	virtual void Show(void)
    	{
    		std::cout << "装扮的" << m_name << std::endl;
    	};
    	Person(){};
    private:
    	std::string m_name;
    };
    
    //服饰类
    class Finery :public Person
    {
    public:
    	void Decorator(Person* comp)
    	{
    		this->m_pComponent = comp;
    	};
    
    	void Show(void)
    	{
    		if (m_pComponent != NULL)
    		{
    			m_pComponent->Show();
    		}
    	};
    protected:
    	Person* m_pComponent;
    };
    
    //具体服饰类
    class TShirts :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "大T恤" << std::endl;
    		Finery::Show();
    	}
    };
    
    class BigTrouser :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "垮裤" << std::endl;
    		Finery::Show();
    	};
    };
    
    class Sneakers :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "破球鞋" << std::endl;
    		Finery::Show();
    	};
    };
    
    class Suit :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "西装" << std::endl;
    		Finery::Show();
    	};
    };
    
    
    class Tie :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "领带" << std::endl;
    		Finery::Show();
    	};
    };
    
    class LeatherShoe :public Finery
    {
    public:
    	void Show(void)
    	{
    		std::cout << "皮鞋" << std::endl;
    		Finery::Show();
    	};
    };
    
    int main()
    {
    	Person* xiaocai = new Person("小菜");
    	std::cout << "第一个装扮" << std::endl;
    	
    	Sneakers* pqx = new Sneakers();
    	BigTrouser* kk = new BigTrouser();
    	TShirts* dtx = new TShirts();
    
    	pqx->Decorator(xiaocai);
    	kk->Decorator(pqx);
    	dtx->Decorator(kk);
    	dtx->Show();
    
    	std::cout << "第二个装扮" << std::endl;
    	LeatherShoe* px = new LeatherShoe();
    	Tie* tie = new Tie();
    	Suit* suit = new Suit();
    	px->Decorator(xiaocai);
    	tie->Decorator(px);
    	suit->Decorator(tie);
    	suit->Show();
    	return 0;
    }
    


     

  • 相关阅读:
    打印乘法口诀
    打印三角形
    java语言基础
    java环境配置
    postgresql新建插入存储过程
    postman做自动化
    fiddler抓包篡改数据实例
    log4j常用4个日志级别
    来一个简单点的表单提交
    mapper文件简单格式
  • 原文地址:https://www.cnblogs.com/secbook/p/2654991.html
Copyright © 2011-2022 走看看