Unity_设计模式_状态模式_05

来源:互联网 发布:linux如何安装win7 编辑:程序博客网 时间:2024/05/22 01:25

在软件系统中:
有些对象具有多种状态。
这些状态在某些情况下能够相互转换。
对象在不同的状态下将具有不同的行为。
复杂的条件判断语句来进行状态的判断和转换操作 ,导致代码的可维护性和灵活性下降,出现新的状态时,代码的扩展性很差,客户端代码也需要进行相应的修改,违背了开闭原则。

差劲的写法
class TestXYZ
{
int behaviour;
//Getter and Setter
……
public void HandleAll()
{
if (behaviour == 0)
{ //do something }
else if (behaviour == 1)
{ //do something }
else if (behaviour == 2)
{ //do something }
else if (behaviour == 3)
{ //do something }
… some more else if …
}
}
状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。对象行为型模式。
又名状态对象(Objects for States)。
用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。
将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。
对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致处理。

这里写图片描述
状态模式包含以下3个角色:
Context((聚合)环境类)
State((关联对象(针对抽象编程))抽象状态类)
ConcreteState((继承)具体状态类)

继承实现抽象

using UnityEngine;
using System.Collections;
using System;

namespace Statepattern

//抽象类;public abstract class State{    public abstract void Handle();}//继承(接口,抽象类,非抽象类);//抽象类;//子类继承父类,实现重写;public class StateA : State{    public override void Handle()    {        Debug.Log("this is stateA");    }}public class StateB : State{    public override void Handle()    {        Debug.Log("this is stateB");    }}public class StateC : State{    public override void Handle()    {        Debug.Log("this is stateC");    }}

}

聚合父类对象

针对抽象编程

using UnityEngine;
using System.Collections;
using System;

namespace Statepattern

//聚合抽象对象 针对抽象编程;public class StateManager{    //代表当前行为 具体行为通过向量转型决定;    private State _currentState;    //集聚 注入;    public void SetState(State state)    {        _currentState = state;    }    public void DoState()    {        _currentState.Handle();    }}

实现代码多态

using UnityEngine;
using System.Collections;
using System;

namespace Statepattern
{

//继承实现抽象;//抽象类;public abstract class State{    public abstract void Handle();}//继承(接口,抽象类,非抽象类);//抽象类;//子类继承父类,实现重写;public class StateA : State{    public override void Handle()    {        Debug.Log("this is stateA");    }}public class StateB : State{    public override void Handle()    {        Debug.Log("this is stateB");    }}public class StateC : State{    public override void Handle()    {        Debug.Log("this is stateC");    }}//聚合抽象对象 针对抽象编程(依赖倒转原则);public class StateManager:Singleton<StateManager>{    //代表当前行为 具体行为通过向量转型决定;    private State _currentState;    //集聚 注入;    public void SetState(State state)    {        _currentState = state;    }    public void DoState()    {        _currentState.Handle();    }}public class Test{    public static void Update()    {        //每次输入时就回进行一次里氏代换        if (Input.GetKeyDown(KeyCode.A))        {            StateManager.Instance.SetState(new StateA());            StateManager.Instance.DoState();        }        if (Input.GetKeyDown(KeyCode.C))        {            StateManager.Instance.SetState(new StateC());            StateManager.Instance.DoState();        }        if (Input.GetKeyDown(KeyCode.B))        {            StateManager.Instance.SetState(new StateB());            StateManager.Instance.DoState();        }    }}

}
测试类
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour {

// Use this for initializationvoid Start () {}   // Update is called once per framevoid Update () {    Statepattern.Test.Update();}

}

使用环境类实现状态转化
对于客户端而言,无须关心状态类,可以为环境类设置默认的状态类,将状态的转换工作交给环境类(或具体状态类)来完成,具体的转换细节对于客户端而言是透明的
可以通过环境类来实现状态转换,环境类作为一个状态管理器,统一实现各种状态之间的转换操作
模式优点
封装了状态的转换规则,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中。
将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。
允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,可以避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。
可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
模式缺点
会增加系统中类和对象的个数,导致系统运行开销增大。
结构与实现都较为复杂,如果使用不当将导致程序结构和代码混乱,增加系统设计的难度。
对开闭原则的支持并不太好,增加新的状态类需要修改负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需要修改对应类的源代码。
模式适应环境
对象的行为依赖于它的状态(例如某些属性值),状态的改变将导致行为的变化。
在代码中包含大量与对象状态有关的条件语句,这些条件语句的出现会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,并且导致客户类与类库之间的耦合增强。
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour
{

void Start(){    //验证    StateManager con = new StateManager();    con.SetState(new StateA());    Debug.Log(con.state_current);    con.SetState(new StateB());    Debug.Log(con.state_current);    con.SetState(new StateC());    Debug.Log(con.state_current);}}//抽象的状态类 abstract class State {public abstract void Handle();}//抽象类的实例StateA,用来表示各种状态class StateA : State{public override void Handle(){    Debug.Log("我是状态A");}}//抽象类的实例StateB,用来表示各种状态class StateB : State{public override void Handle(){    Debug.Log("我是状态B");}}//抽象类的实例StateC,用来表示各种状态class StateC : State{public override void Handle(){    Debug.Log("我是状态C");}}//状态管理类。负责状态的切换,执行不同代码块class StateManager{//当前状态的字段,可以用来查看当前状态public State state_current;//改变当前变量的方法public void SetState(State state){    this.state_current = state;    this.state_current.Handle();}}