跳到主要内容

行为型-命令模式

命令模式是一种行为型设计模式, 其核心就是将请求封装成一个一个对象传递给调用者, 然后再由调用者

命令模式的作用

  • 降低耦合, 请求发送者和接收者之间没有关系, 只要发请求给链即可
  • 简化代码设计, 方便扩展, 有了新的处理者之后只需要添加到链上就行了, 每个处理者都只负责处理某种特定场景

命令模式适用于什么场景

比方说我们的角色套了几层护盾, 在受到攻击时可以使用护盾一层一层处理, 以此降低最终产生的伤害, 此时就可以将这些护盾组成一条链, 将攻击发给这个链, 处理之后得出最终的伤害值

类图

代码

首先定义伤害, FireDamage 是在基伤的上增加20%的火焰伤害

public interface IDamage
{
double BaseDamage { get; set; }
double Damage { get; }
}
public class FireDamage : IDamage
{
public double BaseDamage { get; set; } = 10;
public double Damage => BaseDamage * (1 + Fire);
public double Fire { get; set; } = 0.2;
}

然后定义几种护盾, 以护盾作为我们后期使用的责任链

public interface IShield
{
IShield Next { get; set; }
IDamage Block(IDamage damage);
}
public class BaseShield : IShield
{
public IShield Next { get; set; }
public IDamage Block(IDamage damage)
{
damage.BaseDamage *= 0.9;
if (Next == null || damage.Damage <= 0)
return damage;
return Next.Block(damage);
}
}
public class FireShield : IShield
{
public IShield Next { get; set; }
public IDamage Block(IDamage damage)
{
if (damage is FireDamage fireDamage)
{
fireDamage.Fire *= 0.9;
if (Next == null || fireDamage.Damage <= 0)
return fireDamage;
return Next.Block(fireDamage);
}
return damage;
}
}
public class HolyShield : IShield
{
public IShield Next { get; set; }
public IDamage Block(IDamage damage)
{
damage.BaseDamage *= 0.5;
if (Next == null || damage.Damage <= 0)
return damage;
return Next.Block(damage);
}
}

不同的护盾会有不同的减伤机制, 也只会处理固定类型的伤害

public class Character
{
public IShield Shield { get; set; }
public double HP { get; set; }
public void BlockDamage(IDamage damage)
{
var blockedDamage = Shield.Block(damage);
if (blockedDamage.Damage > 0)
HP -= blockedDamage.Damage;
}
}

在设计角色时只需要知道第一个护盾节点即可, Block 内部会自行判断是否需要继续传递

如何去使用

var shieldChain = new BaseShield()
{
Next = new FireShield()
{
Next = new HolyShield()
}
};
var damage = new FireDamage();
var character = new Character() { HP = 100, Shield = shieldChain };
character.BlockDamage(damage);