策略模式
当一个问题有很多种解决方法,我们要在运行时改变使用的解决方法时,就可以一使用策略模式解决。比如计算购物车价格(原价,打折,满返),出行的出行方式(地铁,公交,单车)
特点
- 将一系列算法封装起来,并且可以相互替换
- 解决使用多条件判断的问题
- 有一个接口规范这些算法
实现
在一个游戏中,角色有A,B,C三个技能,
- A技能 :造成攻击力*150% 的伤害
- B技能 :造成基础伤害的同时,附加100的额外伤害
- C技能 :造成伤害时,根据自身的状态 改变基础攻击力—
攻击力 *(1 加或减 (-1,3])*150%
Attack.cs
interface Attack
{
double hurtVal(double baseAttack);
}
BaseHurt.cs
class BaseHurt : Attack
{
public double hurtVal(double baseAttack)
{
return baseAttack * 1.5;
}
}
ExtraHurt.cs
class ExtraHurt : Attack
{
private double extraVal;
public ExtraHurt(double extraVal)
{
this.extraVal = extraVal;
}
public double hurtVal(double baseAttack)
{
return baseAttack * 1.5 + extraVal;
}
}
StateHurt.cs
class StateHurt : Attack
{
//增益或减益大于-1
double stateVal;
public StateHurt(double stateVal)
{
this.stateVal = stateVal;
}
public double hurtVal(double baseAttack)
{
return baseAttack * (1 + stateVal) * 1.5;
}
}
AttackContext.cs
class AttackContext
{
private Attack attack;
public AttackContext(Attack attack)
{
this.attack = attack;
}
public double getHurtVal(double BaseVal)
{
return attack.hurtVal(BaseVal);
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
//技能A 基础伤害
AttackContext AC = new AttackContext(new BaseHurt());
double AHurtVal = AC.getHurtVal(100);
ole.WriteLine("A技能造成伤害{0}",AHurtVal);
//B技能 额外伤害
AttackContext BC = new AttackContext(new ExtraHurt(150));
Console.WriteLine("B技能伤害{0}",BC.getHurtVal(100));
//C技能 增益减益伤害
AttackContext CC = new AttackContext(new StateHurt(1.5));
Console.WriteLine("C技能伤害{0}",CC.getHurtVal(100));
Console.ReadKey();
}
}
总结
- 优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
- 缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
- 意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
- 主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
- 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
- 如何解决:将这些算法封装成一个一个的类,任意地替换。
- 关键代码:实现同一个接口。
- 改进:可以配合工厂模式来创建Context实例