zoukankan      html  css  js  c++  java
  • 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. 客户端必须知道所有的策略类,并自行决定使用哪一种。
  • 相关阅读:
    RN常用布局和CSS
    RN常用组件
    海屯天地技术服务支持
    微前端应用解决方案
    React组件复用方式
    Webpack-CodeSplit(按需加载)
    Webpack-CodeSplit(静态文件篇)
    Webpack抽离第三方类库以及common解决方案
    Javascript十六种常用设计模式
    React hooks详解
  • 原文地址:https://www.cnblogs.com/Fflyqaq/p/11679066.html
Copyright © 2011-2022 走看看