Unity---游戏设计模式(6)之策略模式


借鉴于:
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、策略模式优缺点

优点

  1. 扩展性好。
  2. 避免多重条件语句。

缺点

  1. 客户端必须知道所有的策略类,并自行决定使用哪一种。
原文地址:https://www.cnblogs.com/Fflyqaq/p/11679066.html