設計模式(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();
}

 

//裝飾模式是爲已有功能動態地添加更多功能的一種方式。
//裝飾模式把每一個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象。
//優勢: 把類中的裝飾功能從類中搬移去除,這樣能夠簡化原有的類。
// 有效地把類的核心職能和裝飾功能區分開了,並且能夠去除相關類中重複的裝飾邏輯。component

相關文章
相關標籤/搜索