一個功能類通常有主要的功能,但是系統有時需要新功能,而這些新加入的東西僅僅是爲了滿足一些只在某種特定情況下才會執行的特殊行爲的需要。怎樣有效地把類的核心職責和裝飾功能區分開,而且可以去除相關類中重複的裝飾邏輯呢?裝飾模式提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象,因此,當需要執行特殊行爲時,客戶代碼就可以再運行時根據需要有選擇地、按順序地使用裝飾功能包裝對象了。
實例
我們知道微信的核心功能是通信,隨着用戶的極速增長,它正向着一個超級App發展。除了核心功能外,它有加入了遊戲板塊,並且遊戲越來越多,大概包括《飛機大戰》、《天天星連萌》、《天天飛車》、《節奏大師》、《天天愛消除》、《天天酷跑》、《天天炫鬥》、《歡樂鬥地主》。每個用戶喜好不同,會下載不同的遊戲。
結構圖爲:
編寫代碼:
先建立一個功能類,再建立一個繼承它的裝飾類,然後再建立相應具體的繼承裝飾類的具體裝飾類,然後客戶端代碼方面要注意裝飾過程是層層遞進、有順序的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 裝飾模式
{
class Program
{
class 微信
{
public 微信()
{ }
private string name;
public 微信(string name)
{
this.name = name;
}
public virtual void play()
{
Console.WriteLine("玩這些遊戲的{0}", name);
}
}
//遊戲類
class Game:微信
{
protected 微信 component;
public void decorate(微信 component)
{
this.component = component;
}
public override void play()
{
if (component !=null )
{
component.play();
}
}
}
//具體遊戲類
class 天天酷跑:Game
{
public override void play()
{
Console.Write("天天酷跑 ");
base.play();
}
}
class 天天飛車 : Game
{
public override void play()
{
Console.Write("天天飛車 ");
base.play();
}
}
class 天天愛消除 : Game
{
public override void play()
{
Console.Write("天天愛消除 ");
base.play();
}
}
class 天天連萌 : Game
{
public override void play()
{
Console.Write("天天連萌 ");
base.play();
}
}
class 節奏大師 : Game
{
public override void play()
{
Console.Write("節奏大師 ");
base.play();
}
}
class 飛機大戰 : Game
{
public override void play()
{
Console.Write("飛機大戰 ");
base.play();
}
}
static void Main(string[] args)
{
微信 xl = new 微信("小樑");
Console.WriteLine("\n第一種下載: ");
天天飛車 fc = new 天天飛車();
天天酷跑 kp = new 天天酷跑();
天天連萌 lm = new 天天連萌();
fc.decorate(xl);
kp.decorate(fc);
lm.decorate(kp);
lm.play();
Console.WriteLine("\n第二種下載:");
飛機大戰 fj = new 飛機大戰();
節奏大師 jz = new 節奏大師();
天天愛消除 axc = new 天天愛消除();
fj.decorate(xl);
jz.decorate(fj);
axc.decorate(jz);
axc.play();
Console.Read();
}
}
}
注意:
裝飾模式是有選擇地、按順序地使用裝飾功能包裝對象!