设计模式

发布于 2017-11-07  706 次阅读


工厂模式

建立一个函数或对象,用来实例化对象。

public class SpriteFactory : MonoBehaviour {

     public object[] allSprites;

     void Start () {
         
         LoadSprite("Number");
     }

     public void LoadSprite(string name) {

         allSprites = Resources.LoadAll(name);

     }

     public GameObject GetSprite(int index) {
         
         GameObject tempObj = new GameObject("tempGame");
         Image tempImage = tempObj.AddComponent<Image>();
         tempImage.sprite = allSprites[index] as Sprite;

         return tempObj;
     } 

     int index = 0;

     void Update () {

         if(Input.GetKeyDown(KeyCode.A)) {
             index++;
             GameObject tempObj = GetSprite(index % 9);
             tempObj.transform.parent = transform;
             tempObj.transform.position = new Vector3(index * 20, 20, 0);
         }
     }
 }

策略模式

传入一个参数,调用同一个API,得到不同的结果。

public class StrageBase {

     public virtual void Caculte() {

     }
 }

 public class PersonStrage:StrageBase {

     float myTax;

     public PersonStrage(float tax) {
         myTax = tax;
     }

     public override void Caculte() {

         myTax *= 0.18f;
         Debug.Log("Person=" + myTax);
     }
 }

 public class BussinessStrage : StrageBase {

     float myTax;

     public BussinessStrage(float tax) {

         myTax = tax;
     }

     public override void Caculte() {

         myTax *= 0.30f;
         Debug.Log("Bussiness=" + myTax);
     }
 }

 public class CaculateStrage {

     public void Caculate(StrageBase tempStrage) {

         tempStrage.Caculte();
     }
 }

 public class StrageCoding : MonoBehaviour {

     void Start () {
         CaculateStrage myCaculate = new CaculateStrage();

         PersonStrage person = new PersonStrage(2000);
         myCaculate.Caculate(person);

         BussinessStrage bussiness = new BussinessStrage(3000);
         myCaculate.Caculate(bussiness);
     }
 }

观察者模式

观察者不断询问实际干活的人,是否已经到达预定时间。

public class ObserverCoding : MonoBehaviour {

     Animation player;

     public void PlayAnima() {

         timeCount = 0;
         player.Play();
     }

     public bool IsFinish() {
         
         return player.isPlaying;
     }


     void Start () {
         
     }

     float timeCount;

     void Update () {

         if(Input.GetKey(KeyCode.A)) {

             PlayAnima();
         }

         if(!IsFinish()) {

             timeCount += Time.deltaTime;

             // 播放0.5秒后,Do Something
             if(timeCount > 0.5f) {

                 Debug.Log("Do Something");
             }
         }
     }
 }
[/cc]</pre>
<h2>代理模式</h2>
代理下达一个任务,实际干活的人,干完活之后,主动报告。
<pre>[cc lang="csharp" escaped="true"] 
public delegate void PlayFinish();

 public class DelegateAnimation {

     public Animation player;

     PlayFinish playDelegate;

     float timeCount;

     public DelegateAnimation(PlayFinish tempDelegate) {

         playDelegate = tempDelegate;
     }


     public void PlayerAnimation() {

         timeCount = 0;
         player.Play();
     }

     public bool IsFinish() {
         
         return player.isPlaying;
     }

     public void Update() {

         if(!IsFinish()) {

             timeCount += Time.deltaTime;

             if(timeCount > 0.5f) {
                 playDelegate();
                 Debug.Log("Do Something!");
             }
         }
     }
 }

 public class DelegateCoding : MonoBehaviour {

     //DelegateAnimation anim;

     DelegateAnimation[] anim;

     void PlayFinish() {
         
     }

     void Start () {

         anim = new DelegateAnimation[10];

         for(int i = 0; i < anim.Length; i++) {

             anim[i] = new DelegateAnimation(PlayFinish);
             anim[i].PlayerAnimation();
         }

         //anim = new DelegateAnimation(PlayFinish);
         //anim.PlayerAnimation();
     }
     
     void Update () {
         
         //anim.Update();

         for(int i = 0; i < anim.Length; i++) {

             anim[i].Update();
         }
     }
 }

单例模式

单例模式最好在各个模块管理类中使用。

public class SingleCoding : MonoBehaviour {

     public static SingleCoding instance = null;

     void Awake() {
         
         instance = this;    
     }
 }

门面模式

管理的东西没有一点逻辑关系,聚集起来能形成一个功能。

public class FacadeCoding : MonoBehaviour {

     public GameObject lightOn;
     public GameObject lightOff;
     public GameObject light;

     public void SwitchLightOn() {

         light.SetActive(true);
     }

     public void SwitchLightOff() {

         light.SetActive(false);
     }
 }
[/cc]</pre>
<h2>建造者模式</h2>
上层调用->AssetBundleLoad到内存->AssetBundle.LoadAsset。
自上而下的,每一个环节提供不同的功能,分工明确。
<pre>[cc lang="csharp" escaped="true"] 
// 内存层
 public class IABresources {

     // 内存中的 assetBundle
     AssetBundle abAssetBundle;

     public Object LoadRes(string res) {

         return abAssetBundle.LoadAsset(res);
     }
     public Object[] LoadReses(string res) {

         return abAssetBundle.LoadAssetWithSubAssets(res);
     }
 }

 // 从硬盘中 Load AssetBundle
 public class AssetBundleLoad {

     Dictionary<string, IABresources> assetBundleManager = new Dictionary<string, IABresources>();

     private string bundleName;

     public string BundleName { get;set; }

     public IEnumerator LoadAssetBundle(string path) {

         WWW tempLoader = new WWW(path);

         while(!tempLoader.isDone) {
             yield return tempLoader;
         }

         assetBundleManager.Add(bundleName, tempLoader.assetBundle as IABresources);
     }

     public object LoadSingle(string bundleName, string res){

         if(assetBundleManager.ContainsKey(bundleName)) {

             IABresources tempAB = assetBundleManager[bundleName];
             return tempAB.LoadRes(res);
         }
     }

     public Object[] LoadMuti(string bundleName, string res) {

         if(assetBundleManager.ContainsKey(bundleName)) {

             IABresources tempAB = assetBundleManager[bundleName];
             return tempAB.LoadReses(res);
         }
     }

 }

 public class BuildCoding : MonoBehaviour {

     void Start () {

         AssetBundleLoad loader = new AssetBundleLoad();
         loader.BundleName = "test.u3d";
         StartCoroutine(loader.LoadAssetBundle("//path/to/test.u3d"));
     }
 }

中介者模式

以扣血为例,NPC和Player两者的扣血,由第三方负责调用。

// 迪米特原则  最少的引用其他类
 public class ActorBase : MonoBehaviour {

     public virtual void ReduceBlood() {}
 }

 public class NPC : ActorBase {

     public override void ReduceBlood() {

         // Do Something
     }
 }

 public class Charactor : ActorBase {

     public override void ReduceBlood() {

         // Do Something
     }
 }



 public class MediatorCoding : MonoBehaviour {

     Charactor player;
     NPC npc;

     /// <summary>
     /// Caculates the blood.
     /// </summary>
     /// <param name="attacked">被攻击</param>
     /// <param name="attack">攻击</param>
     public void CaculateBlood(ActorBase attacked, ActorBase attack) {

         float tempDistance = Vector3.Distance(attacked.transform.position, attack.transform.position);

         if(tempDistance < 10) {

             attacked.ReduceBlood();
         }
     }
 }

状态者模式

以动画状态机来举例子,将所有的动画的状态抽象出一个基类,每个状态分别继承此类,
为维护动画状态写一个管理类。这样会有很多类,但是便于维护和管理,结构和逻辑都
很清晰。

public abstract class FSMState {

     private byte statID;

     public virtual void OnBeforEntor() {}

     public virtual void CopyState() {}

     public abstract void OnEnter() {}

     public virtual void Update() {}

     public virtual void OnLeave() {}
 }

 public class FSMManager {

     private FSMState[] fsmManager;

     // 增加了几个状态 
     private byte curAdd;
     private byte curStateID;


     public FSMManager(byte stateNumber) {

         curAdd = 0;
         curStateID = 0;

         fsmManager = new FSMState[stateNumber];
     }

     public void AddState(FSMState tempState) {

         if(curAdd < fsmManager.Length) {

             fsmManager[curAdd] = tempState;
             curAdd++;
         }
     }

     public void ChangeState(byte stateID) {

         fsmManager[curStateID].OnLeave();
         fsmManager[curStateID].CopyState(fsmManager[curStateID]);
         fsmManager[curStateID].OnBeforEntor();
         fsmManager[curStateID].OnEnter();

         curStateID = stateID;
     }

     public void Update() {
         
         fsmManager[curStateID].Update();
     }
 }

 public class AttackFSM : FSMState {

     public override void OnEnter() {
         
         // Animator.set XXXX
     }
 }

 public class WalkFSM : FSMState {

     public override void OnEnter() {

     }
 }

 public class FSM : MonoBehaviour {

     public enum FSMStateID {
         Idle,
         Attack,
         Walk,
         MaxValue
     }

     FSMStateID stateID;

     FSMManager manager;

     void Start() {

         WalkFSM tempWalk = new WalkFSM();
         AttackFSM tempAttack = new AttackFSM();

         manager = new FSMManager(FSMStateID.MaxValue);

         manager.AddState(tempWalk);
         manager.AddState(tempAttack);
     }

     public void PlayAttack() {

         manager.ChangeState(FSMStateID.Attack);
     }

     void Update() {

         manager.Update();
     }
 }

-


What doesn’t kill you makes you stronger.