博客地址:blog.liujunliang.com.cn
寫在前面
在遊戲中計算各個覺得的攻擊值、防禦值時,由於各個角色的職業不同,攻擊值和防禦值計算算法就會不一樣
通常使用if....else語句來抉擇不同類型之間的算法將帶來程序複雜和難以維持,當有新的算法或行爲時違背開閉原則
策略模式是對算法的包裝,是把使用算法的責任和算法本身分割開來。委託給不同的對象管理。
模式角色
環境類:對策略進行二次封裝,目的是避免高層模塊對策略的直接調用
抽象策略:這是一個抽象角色,通常由一個接口或抽象類實現,其提供所有具體策略類所需要的接口
具體策略:包裝相關的算法或行爲
模式結構圖
代碼案例
定義一個抽象類(抽象策略)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class IStrategy
{
public abstract int GetAttackValue();
public abstract int GetDefenseValue();
}
創建實現接口的實體類(具體策略)
戰士
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WarriorStrategy : IStrategy
{
public override int GetAttackValue()
{
Debug.Log("得到戰士攻擊值");
return 0;
}
public override int GetDefenseValue()
{
Debug.Log("得到戰士防禦值");
return 0;
}
}
法師
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MasterStrategy : IStrategy
{
public override int GetAttackValue()
{
Debug.Log("得到法師攻擊值");
return 0;
}
public override int GetDefenseValue()
{
Debug.Log("得到法師防禦值");
return 0;
}
}
創建環境類
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Context
{
private IStrategy strategy;
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public void SetStrategy(IStrategy strategy)
{
this.strategy = strategy;
}
public int GetAttackValue()
{
return strategy.GetAttackValue();
}
public int GetDefenseValue()
{
return strategy.GetDefenseValue();
}
}
使用Context來查看當它改變策略Strategy時的行爲變化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main : MonoBehaviour
{
private Context context;
// Use this for initialization
void Start ()
{
context = new Context(new WarriorStrategy());
context.GetAttackValue();
context.GetDefenseValue();
context.SetStrategy(new MasterStrategy());
context.GetAttackValue();
context.GetDefenseValue();
}
}
運行Unity,一切正常
模式優點
1、避免使用多重條件
2、易於擴展
3、策略類之間只有切換