中介者模式
延续责任链模式:
以上例子是增加永久防御和攻击,假设增加增益属性只在一个回合内或者一段时间内有效该如何处理?
增加一个游戏管理者:用来查询各项属性。
public class Game { public event EventHandlerqueries; public void PrefromQuery(object send, Query q) { queries?.Invoke(send, q); } } public class Query//查询对象 { public enum Argument { Attack,//攻击 Defense//防御 } public string QueryName; public Argument WhatQuery; public int value; public Query(string queryName, Argument whatQuery, int value) { QueryName = queryName; WhatQuery = whatQuery; this.value = value; } }
定义个生物类
public class Creature { private Game game; //游戏中介 public string Name;//名称 private int attack, defense;//攻击/防御【私有字段】 public Creature(Game game, string name, int attack, int defense) { this.game = game; Name = name; this.attack = attack; this.defense = defense; } public int Attack //对外查询属性 通过中介进行查询 { get { var q = new Query(Name, Query.Argument.Attack, attack); game.PrefromQuery(this, q); return q.value; } } public int Defense //对外防御属性,通过中介进行查询 { get { var q = new Query(Name, Query.Argument.Defense, defense); game.PrefromQuery(this, q); return q.value; } } public override string ToString() { return $"Name:{Name},Attack:{Attack},Defense:{Defense}"; } }
定义一个生物修改抽象模型,实现IDisposable接口,可以再释放时,执行进一步操作:
传入游戏中介和生物,在初始化时绑定自定义事件Handle
public abstract class CreatureModeifier : IDisposable { protected Game game; protected Creature creature; protected CreatureModeifier(Game game, Creature creature) { this.game = game; this.creature = creature; game.queries += Handle; } protected abstract void Handle(object sender, Query q); public void Dispose() { game.queries -= Handle; } }
我们在创建攻击类和防御类:实现抽象模型
public class DoubleAttack : CreatureModeifier { public DoubleAttack(Game game, Creature creature) : base(game, creature) { } protected override void Handle(object sender, Query q) { if (q.QueryName== creature.Name && q.WhatQuery == Query.Argument.Attack) { q.value *= 2; } } } public class IncreaseProtectionBuff : CreatureModeifier { public IncreaseProtectionBuff(Game game, Creature creature) : base(game, creature) { } protected override void Handle(object sender, Query q) { if (q.QueryName == creature.Name && q.WhatQuery == Query.Argument.Defense) { q.value += 5; } } }
来看使用:
static void Main(string[] args) { Game game = new Game();//中介 var goblin = new Creature(game, "Goblin", 3, 3);//生物 Console.WriteLine(goblin); using (var doubleAttack=new DoubleAttack(game,goblin))//增加双倍攻击BUff { Console.WriteLine(goblin); using (var def = new IncreaseProtectionBuff(game, goblin))//增加防御BUFF { Console.WriteLine(goblin); } } Console.WriteLine(goblin); }
看看结果:
只在Using范围内有效。