動態給對象添加額外職責。就增加功能而言,Decorator 比生成子類更靈活。
網遊武器系統:初期未考慮強化與磨損。策劃後續要求強化、修理系統。武器類需對外提供強化、磨損、修理方法。若用繼承:
繼承層次與子類數量爆炸。引入 Decorator 靈活賦予額外職責。
using System;
using System.Collections.Generic;
using System.Text;
namespace DecoratorExample
{
class Program
{
static void Main(string[] args)
{
Weapon w = new Rifle();
w.ShowInfo();
Enhance enhancedWeapon = new Enhance(w);
enhancedWeapon.EnhanceAmmo();
enhancedWeapon.ShowInfo();
Wear wornWeapon = new Wear(w);
wornWeapon.WearByRate(0.8);
wornWeapon.ShowInfo();
}
}
abstract class Weapon
{
public double Ammo { get; set; }
public double Attack { get; set; }
public double Speed { get; set; }
public string Name { get; set; }
public abstract void ShowInfo();
}
class Rifle : Weapon
{
public Rifle() { Ammo = 100; Attack = 10; Speed = 5; Name = "Rifle"; }
public override void ShowInfo()
{
Console.WriteLine($"ammo\t{Ammo}");
Console.WriteLine($"attack\t{Attack}");
Console.WriteLine($"speed\t{Speed}");
Console.WriteLine($"name\t{Name}");
}
}
abstract class Decorator : Weapon
{
protected Weapon w;
public Decorator(Weapon w) { this.w = w; }
public override void ShowInfo() => w.ShowInfo();
}
class Enhance : Decorator
{
public Enhance(Weapon w) : base(w) { }
public void EnhanceAmmo() { w.Ammo += 20; Console.WriteLine(">>>>>>>>Enhanced"); }
}
class Wear : Decorator
{
public Wear(Weapon w) : base(w) { }
public void WearByRate(double rate) { w.Speed *= rate; w.Attack *= rate; Console.WriteLine(">>>>>>>>Worn"); }
}
}
EnhanceAmmo/WearByRate),屬半透明裝飾(非針對抽象構件編程)。