设计模式2:state pattern

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

这句黑话,我头几次看,不能理解。但当踏踏实实敲一遍代码后,有了一点自己的理解:
举个例子,一个游戏角色有行走,跳,跑等几个状态,我们如何编码让游戏对象从一个状态到另一个状态时,行为也自动随之改变,而之后修改状态时,无需再来修改高层的类呢。设计模式里有一个原则,对接口编程,不对实现编程。如何联系对象和对象状态呢?我们用接口(抽象类,接口,父类,总之一句话,实现运行时多态即可)。

四人帮GOF的设计模式里有张图,非常简洁清晰的说明了问题。
在这里插入图片描述

其中Context就是游戏对象,游戏对象有一个State类型的游戏状态成员,request()方法调用State->handle实现功能即可。

测试代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace HeroineState {

    public class Heroine{
        public void HandleInput() { state.HandleInput(); }
        public HeroineState NextState() { return state = state.NextState(); }

        //public HeroineState State { get; set; }
        private HeroineState state = StandingState.GetStand;

    }


    public class HeroineState {

        //private static StandingState standing; // 如果类是抽象类就只是声明了,其子类实例化
        //private static JumpingState jumping;
        //private static StandingState standing = new StandingState();  // 子类父类共享的字段. 如果类包含静态字段,则提供在类加载时初始化它们的静态构造函数。或者声明时直接初始化

        public virtual void HandleInput() { }
        public virtual HeroineState NextState() { return null; }
    }

    public class StandingState:HeroineState{

        private StandingState() { }
        private static StandingState standing = new StandingState();
        public static StandingState GetStand {
            get {
                return standing;
            }
        }

        public float chargeTime = 0;


        public override void HandleInput() {
            if(Input.GetButton("Fire123"))
                Debug.Log("Fire when standing!!");
        }

        public override HeroineState NextState() {
            if (Input.GetButton("jump")) {
                Debug.Log("stand to jump");
                return JumpingState.GetJump;
            }
            else if (Input.GetButton("Stand")) {
                Debug.Log("keep standing");
                return this;
            }
            //Debug.Log("No if call");
            return this;
        }
    }

    public class JumpingState : HeroineState {

        private JumpingState() { }
        private static JumpingState jumping = new JumpingState();
        public static JumpingState GetJump {
            get {
                return jumping;
            }
        }

        public float chargeTime = 0;


        public override void HandleInput() {
            if (Input.GetButton("Fire123"))
                Debug.Log("Fire when jumping!!");
        }

        public override HeroineState NextState() {
            if (Input.GetButton("Stand")) {
                Debug.Log("jump to stand");
                return StandingState.GetStand;     
            }
            else if(Input.GetButton("jump")){
                Debug.Log("keep jumping!");
                return this;
            }
            //Debug.Log("No if call");
            return this;
        }
    }


}

猜你喜欢

转载自blog.csdn.net/vc43vc/article/details/82938548
今日推荐