zoukankan      html  css  js  c++  java
  • 设计模式(3)--装饰模式

    //单一原则: 一个类而言,应该仅有一个引起它变化的原因。
    //开放-封闭原则: 类/模块/函数等等,应该可以扩展,但是不可修改。
    //依赖倒装原则: 抽象不应该依赖细节,洗劫应该依赖于抽象。换句话说是,要针对接口编程,不要对实现编程。
    //A.高层模块不应该依赖低层模块。两个都应该依赖抽象。
    //B.抽象不应该依赖细节。细节应该依赖抽象。
    //里氏代换原则: 子类型必须能够替换掉它们的父类型。
    
    //3.装饰模式
    //ver1
    class Person
    {
    private:
    	string _name;
    public:
    	Person(string name)
    	{
    		_name = name;
    	}
    	void Show()
    	{
    		//...
    	}
    };
    
    //服饰抽象类
    class Finery
    {
    public:
    	virtual void Show() = 0;
    };
    
    //T恤类
    class TShirts : public Finery
    {
    public:
    	virtual void Show()
    	{
    		//..
    	}
    };
    
    //垮裤类
    class BigTrouser : public Finery
    {
    public:
    	virtual void Show()
    	{
    		//..
    	}
    };
    
    //领带类
    class Tie : public Finery
    {
    public:
    	virtual void Show()
    	{
    		//..
    	}
    };
    
    void main11()
    {
    	Person *ppc = new Person("fun");
    	TShirts *pd1 = new TShirts();
    	BigTrouser *pd2 = new BigTrouser();
    	Tie *pd3 = new Tie();
    
    	//装扮1
    	pd1->Show();
    	pd2->Show();
    	ppc->Show();
    	//装扮2
    	pd1->Show();
    	pd3->Show();
    	ppc->Show();
    	//缺点: 一个一个显示出来; 组装应该在内部进行; 
    }
    

    //装饰模式: 动态地给一个对象添加一些额外的职责,就增加功能类说,装饰模式比生成子类更为灵活;

    //3.装饰模式
    //ver2
    
    //Component是定义一个对象接口,可以给这些对象动态地添加职责。
    //ConcreteComponent是定义一个具体的对象,也可以给这个对象添加一些职责。
    //Decorator抽象装饰类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,无需知道Decorator的存在;
    //ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
    
    class Component
    {
    public:
    	virtual void Operation() = 0; //接口
    };
    
    class ConcreteComponent : public Component
    {
    	virtual void Operation()
    	{
    		//...
    	}
    };
    
    class Decorator : public Component
    {
    protected:
    	Component *pcomponent;
    public:
    	void SetComponent(Component *pcom)
    	{
    		pcomponent = pcom;
    	}
    	virtual void Operation()
    	{
    		if (pcomponent != NULL)
    		{
    			pcomponent->Operation();
    		}
    	}
    };
    
    class ConcreteDecoratorA : public Decorator
    {
    private:
    	string addState;
    public:
    	virtual void Operation()
    	{
    		Decorator::Operation(); //先运行Component的Operation,再执行本类的操作。
    		addState = "New State";
    		//...
    	}
    };
    
    class ConcreteDecoratorB : public Decorator
    {
    private:
    	void AddBehavior() //本类独有的操作;
    	{
    		//...
    	}
    public:
    	virtual void Operation()
    	{
    		Decorator::Operation();
    		AddBehavior();
    	}
    };
    
    void main12()
    {
    	ConcreteComponent * pc = new ConcreteComponent();
    	ConcreteDecoratorA * d1 = new ConcreteDecoratorA();
    	ConcreteDecoratorB * d2 = new ConcreteDecoratorB();
    
    	d1->SetComponent(pc); //先用 ConcreteDecoratorA 来包装 ConcreteComponent; 会执行 ConcreteComponent::Operation()
    	d2->SetComponent(d1); //再用 ConcreteDecoratorB 来包装 ConcreteDecoratorA
    	d2->Operation(); //最终执行 d2->Operation()
    	//装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了。
    	//每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
    }
    

    //如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
    //如果只有一个ConcreteDecorator类,那么久没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合成一个类.

    //3.装饰模式
    //ver3
    class Person
    {
    private:
    	string _name;
    public:
    	Person(){} //用于 TShirts 等派生类构造默认的构造函数;
    	Person(string name)
    	{
    		_name = name;
    	}
    	virtual void Show()
    	{
    
    	}
    };
    
    //服饰类
    class Finery : public Person
    {
    protected:
    	Person component;
    
    public:
    	void Decorate(Person comp)
    	{
    		component = comp;
    	}
    
    	virtual void Show()
    	{
    		component.Show();
    	}
    };
    
    //具体服饰类
    class TShirts : public Finery
    {
    public:
    	virtual void Show()
    	{
    		//do something
    		Finery::Show();
    	}
    };
    
    class BigTrouser : public Finery
    {
    public:
    	virtual void Show()
    	{
    		//do something.
    		Finery::Show();
    	}
    };
    
    void main31()
    {
    	Person * ppc = new Person("fun");
    
    	TShirts * pd1 = new TShirts();
    	BigTrouser * pd2 = new BigTrouser();
    
    	pd1->Decorate(*ppc);
    	pd2->Decorate(*pd1);
    	pd2->Show();
    }
    

    //装饰模式是为已有功能动态地添加更多功能的一种方式。
    //装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。
    //优点: 把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
    // 有效地把类的核心职能和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。

  • 相关阅读:
    udelay、mdelay、ndelay、msleep使用比较说明
    linux多线程驱动中调用udelay()对整个系统造成的影响(by liukun321咕唧咕唧)
    linux设备驱动那点事儿之平台设备理论篇
    misc_register、 register_chrdev 的区别总结
    platform_driver与file_operations两种方法开发led驱动
    rc522 ,pn544区别
    内核驱动中常见的miscdevice、platform_device、platform_driver
    file_operations结构2
    file_operations结构体解析 1
    android5.0问题
  • 原文地址:https://www.cnblogs.com/sylar-liang/p/6021587.html
Copyright © 2011-2022 走看看