一个功能类通常有主要的功能,但是系统有时需要新功能,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。怎样有效地把类的核心职责和装饰功能区分开,而且可以去除相关类中重复的装饰逻辑呢?装饰模式提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以再运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
实例
我们知道微信的核心功能是通信,随着用户的极速增长,它正向着一个超级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();
}
}
}
注意:
装饰模式是有选择地、按顺序地使用装饰功能包装对象!