借鉴于:
http://www.uml.org.cn/sjms/201009092.asp
《设计模式Head First》
策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
策略模式的功能是把具体的算法实现,从具体的业务处理里面独立出来,把它们实现成为单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换。
设计原则1:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。以便以后可以轻易的改动或者扩充此部分。
设计原则2:针对接口编程,而不是针对实现编程。
针对接口编程,核心就是利用多态性。也可以说是针对超类型编程,超类型可以是接口或者抽象类。
不好的做法:行为来自于基类的具体实现、或是继承某个接口并由子类自行实现。这两种方法都依赖于实现。
好的做法:我们使用超类型(父类)声明变量类型,而不是某个具体的子类,超类型方法的具体实现放在其子类中。这样我们就可以在程序执行时根据实际情况执行到不同的子类行为。
这样就具有很好的可维护性和可扩展性。
设计原则3:多用组合,少用继承。
用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。用组合的方法扩展对象的行为,就可以在运行时动态的进行扩展。
1、策略模式
策略模式UML
策略模式原型代码
假如我们是商家,对于不同的Vip用户要打不同的折扣。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StrategyMode : MonoBehaviour
{
private void Start()
{
double money = 1000f;
Strategy strategyNormal = new ConcreteStrategy1();
Strategy strategyVip = new ConcreteStrategy2();
Strategy strategySuperVip = new ConcreteStrategy3();
Price priceNormal = new Price(strategyNormal);
Debug.Log("普通用户花费:" + priceNormal.CalculateMoney(money));
Price priceVip = new Price(strategyVip);
Debug.Log("Vip用户花费:" + priceVip.CalculateMoney(money));
Price priceSuperVip = new Price(strategySuperVip);
Debug.Log("超级Vip用户花费:" + priceSuperVip.CalculateMoney(money));
}
}
public class Price
{
private Strategy mStrategy;
public Price(Strategy strategy)
{
mStrategy = strategy;
}
public double CalculateMoney(double money)
{
if (mStrategy != null)
{
return mStrategy.Calculate(money);
}
return -1;
}
}
public interface Strategy
{
double Calculate(double money);
}
public class ConcreteStrategy1 : Strategy
{
public double Calculate(double money)
{
Debug.Log("普通用户,不打折。");
return money;
}
}
public class ConcreteStrategy2 : Strategy
{
public double Calculate(double money)
{
Debug.Log("Vip用户,打9折。");
return money * 0.9f;
}
}
public class ConcreteStrategy3 : Strategy
{
public double Calculate(double money)
{
Debug.Log("超级Vip用户,打8折。");
return money * 0.8f;
}
}
2、策略模式例子
在游戏中,游戏中角色等级变化时,许多属性也会变化。在写属性的变化算法上,就可以用到策略模式去计算值的变化。
策略模式实例UML图
策略模式实例代码
/// <summary>
/// 策略模式
/// 计算当角色等级增加时,属性的提升
/// </summary>
public interface IAttributeStrategy
{
int GetExtraHPValue(int lv);
int GetExtraAttackValue(int lv);
}
/// <summary>
/// 战士属性
/// </summary>
public class SoldierAttributeStrategy : IAttributeStrategy
{
public int GetExtraHPValue(int lv)
{
//每级增加10血量
return (lv - 1) * 10;
}
public int GetExtraAttackValue(int lv)
{
//每级增加2攻击力
return (lv - 1) * 2;
}
}
/// <summary>
/// 敌人属性
/// </summary>
public class EnemyAttributeStrategy : IAttributeStrategy
{
public int GetExtraHPValue(int lv)
{
//每级增加15血量
return (lv - 1) * 15;
}
public int GetExtraAttackValue(int lv)
{
//每级增加3攻击力
return (lv - 1) * 3;
}
}
当角色升级时,就可以根据策略模式获取需要增加的属性值。
3、策略模式优缺点
优点
- 扩展性好。
- 避免多重条件语句。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一种。