需求:
现在有一把手枪。未来可能需要给手枪升级添加上光效LightEff,给手枪添加皮套Holster利用装饰模式解决方案:
根据马士兵教程类图如下:
///简单的手枪
public class TestTest : MonoBehaviour
{
public Gun gun1;
private void Awake()
{
gun1 = new Gun();
}
private void Start()
{
gun1.DrawObj();
}
}
// 枪
public class Gun
{
public virtual void DrawObj()
{
Debug.Log("绘制一把枪");
}
}
现在需要给手枪升级添加上光效LightEff,给手枪添加皮套Holster
public class TestTest : MonoBehaviour
{
public Gun gun1;
private void Awake()
{
gun1 = new Gun();
gun1 = new LightEffDecorator(gun1);
gun1 = new HolsterDecorator(gun1);
}
private void Start()
{
gun1.DrawObj();
}
}
//枪
public class Gun
{
public virtual void DrawObj()
{
Debug.Log("绘制一把枪");
}
}
//枪装饰器基类
public abstract class GunDecoratorBase : Gun
{
//被装饰的对象
protected Gun beDecoratorGo;
public GunDecoratorBase(Gun gun)
{
beDecoratorGo = gun;
}
}
//枪灯光装饰器基类
public class LightEffDecorator : GunDecoratorBase
{
public override void DrawObj()
{
Debug.Log("添加灯光效果");
beDecoratorGo.DrawObj();
}
public LightEffDecorator(Gun gun) : base(gun)
{
}
}
//枪皮套装饰器基类
public class HolsterDecorator : GunDecoratorBase
{
public override void DrawObj()
{
Debug.Log("添加皮套");
beDecoratorGo.DrawObj();
}
public HolsterDecorator(Gun gun) : base(gun)
{
}
}
但是现在只能给Gun手枪装饰,如果改天我们还要装饰比如AK47,这时候只能照着上面装饰器为ak47单独写上同样的
LightEffDecorator和HolsterDecorator这样很没必要,我们需要写的装饰器可以为多种东西装饰,所以进行如下修改
//装饰器基类不再继承Gun 也就是不在单独为手枪服务, 而是抽象出DrawGameObject,装饰器为DrawGameObject服务,而Gun和Ak47继承DrawGameObject成为其的子类
public class TestTest : MonoBehaviour
{
public DrawGameObject gun1;
public DrawGameObject ak47;
private void Awake()
{
gun1 = new Gun();
gun1 = new LightEffDecorator(gun1);
gun1 = new HolsterDecorator(gun1);
ak47 = new Ak_47();
ak47 = new LightEffDecorator(ak47);
ak47 = new HolsterDecorator(ak47);
}
private void Start()
{
gun1.DrawObj();
ak47.DrawObj();
}
}
public abstract class DrawGameObject
{
public abstract void DrawObj();
}
public class Gun : DrawGameObject
{
public override void DrawObj()
{
Debug.Log("绘制一把枪");
}
}
public class Ak_47 : DrawGameObject
{
public override void DrawObj()
{
Debug.Log("绘制一AK47");
}
}
public abstract class DecoratorBase : DrawGameObject
{
//被装饰的对象
protected DrawGameObject beDecoratorGo;
public DecoratorBase(DrawGameObject obj)
{
beDecoratorGo = obj;
}
}
public class LightEffDecorator : DecoratorBase
{
public override void DrawObj()
{
Debug.Log("添加灯光效果");
beDecoratorGo.DrawObj();
}
public LightEffDecorator(DrawGameObject obj) : base(obj)
{
}
}
public class HolsterDecorator : DecoratorBase
{
public override void DrawObj()
{
Debug.Log("添加皮套");
beDecoratorGo.DrawObj();
}
public HolsterDecorator(DrawGameObject obj) : base(obj)
{
}
}
最终得到结果
完整装饰器
设计模式切记不能死记硬背套用