设计模式-----State Pattern

state pattern

  • 状态模式:状态模式一般用来实现状态机。状态机常用在游戏、工作流引擎等开发中。
  • 有限状态机(Finite-State Machine)FSM,有三个组成部分:状态(state)、事件(Event)、动作(Action)。事件也被称为转移条件(Transition Condition)。事件触发状态的转移,可能触发动作执行,也可不触发动作执行。

State Pattern 角色分析

  • Context: 环境类又称上下文类,它是拥有状态的对象,在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象,可以定义初始状态;
  • State: 抽象状态类,用于定义一个接口以封装与环境类的一个特定状态相关的行为;
  • ConcreteState: 具体状态类是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。
  • 适用场景:
    State Pattern在工作流或游戏等类型的软件中得以广泛使用,甚至可以用于这些系统的核心功能设计,如在政府OA办公系统中,一个批文的状态有多种:尚未办理;正在办理;正在批示;正在审核;已经完成等各种状态,而且批文状态不同时对批文的操作也有所差异。使用状态模式可以描述工作流对象(如批文)的状态转换以及不同状态下它所具有的行为。

代码示例

下面示例代码中,模拟context有两个状态,concreteStateA与ConcreteStateB,当context调用request()方法,触发concreteStateA转移为ConcreteStateB。
在这里插入图片描述
图2

/*
 *State Pattern
 * 
 */
using System;
using System.Collections.Generic;

namespace Pattern03
{
    class Program
    {

        static void Main(string[] args)
        {

            
            //创建context,并初始化当前状态
            Context c = new Context(new ConcreteStateA());
           //事件触发状态转移
            c.Request();
            c.Request();
            c.Request();


            Console.ReadKey();
        }
    }

    abstract class State
    {
        public abstract void Handle(Context context);
    }
    class ConcreteStateA : State
    {
        public override void Handle(Context context)
        {
            context.State = new ConcreteStateB();
        }
    }
    class ConcreteStateB : State
    {
        public override void Handle(Context context)
        {
            context.State = new ConcreteStateA();
        }
    }
    class Context
    {
        private State _state;//维护一个State对象
        public Context(State state)
        {
            this._state = state;
        }

        public State State
        {
            get { return _state; }
            set
            {
                _state = value;
                Console.WriteLine("State: " + _state.GetType().Name);
            }
        }
        public void Request()
        {
            _state.Handle(this);
        }
    }
}

示例2

示例代码状态转移图
在这里插入图片描述

/*
 * State Pattern
 */
using System;
using System.Collections;

namespace Pattern02
{
    class Program
    {

        static void Main(string[] args)
        {

            Account account = new Account("Jim Johnson");

            account.Deposit(500.0);
            account.Deposit(300.0);
            account.Deposit(550.0);
            account.PayInterest();
            account.Withdraw(2000.00);
            account.Withdraw(1100.00);

            account.Deposit(2000.00);

            Console.ReadLine();
        }

    }
    /// <summary>
    /// state
    /// </summary>
    abstract class State
    {
        protected Account account;
        protected double balance;
        protected double interest;
        protected double lowerLimit;
        protected double upperLimit;

        public Account Account
        {
            get { return account; }
            set { account = value; }
        }

        public double Balance
        {
            get { return balance; }
            set { balance = value; }
        }

        public abstract void Deposit(double amount);
        public abstract void Withdraw(double amount);
        public abstract void PayInterest();
    }
    class RedState : State

    {
        private double _serviceFee;
       
        public RedState(State state):
            this(state.Account,state.Balance)
        { }
        public RedState(Account account, double balance)
        {
            this.balance = balance;
            this.account = account;
            Initialize();
        }
        private void Initialize()
        {
            // Should come from a datasource

            interest = 0.0;
            lowerLimit = -100.0;
            upperLimit = 0.0;
            _serviceFee = 15.00;
        }

        public override void Deposit(double amount)
        {
            balance += amount;
            StateChangeCheck();
        }

        public override void Withdraw(double amount)
        {
            amount = amount - _serviceFee;
            Console.WriteLine("无可用余额!");
        }

        public override void PayInterest()
        {
            // No interest is paid

        }

        private void StateChangeCheck()
        {
            if (balance > upperLimit)
            {
                account.State = new SilverState(this);
            }
        }
    }
    class SilverState : State
    {
        public SilverState(State state) :
          this(state.Balance, state.Account)
        {
        }

        public SilverState(double balance, Account account)
        {
            this.balance = balance;
            this.account = account;
            Initialize();
        }

        private void Initialize()
        {
            // Should come from a datasource

            interest = 0.0;
            lowerLimit = 0.0;
            upperLimit = 1000.0;
        }

        public override void Deposit(double amount)
        {
            balance += amount;
            StateChangeCheck();
        }

        public override void Withdraw(double amount)
        {
            balance -= amount;
            StateChangeCheck();
        }

        public override void PayInterest()
        {
            balance += interest * balance;
            StateChangeCheck();
        }

        private void StateChangeCheck()
        {
            if (balance < lowerLimit)
            {
                account.State = new RedState(this);
            }
            else if (balance > upperLimit)
            {
                account.State = new GoldState(this);
            }
        }
    }
    class GoldState : State

    {
        // Overloaded constructors

        public GoldState(State state)
          : this(state.Balance, state.Account)
        {
        }

        public GoldState(double balance, Account account)
        {
            this.balance = balance;
            this.account = account;
            Initialize();
        }

        private void Initialize()
        {
            // Should come from a database

            interest = 0.05;
            lowerLimit = 1000.0;
            upperLimit = 10000000.0;
        }

        public override void Deposit(double amount)
        {
            balance += amount;
            StateChangeCheck();
        }

        public override void Withdraw(double amount)
        {
            balance -= amount;
            StateChangeCheck();
        }

        public override void PayInterest()
        {
            balance += interest * balance;
            StateChangeCheck();
        }

        private void StateChangeCheck()
        {
            if (balance < 0.0)
            {
                account.State = new RedState(this);
            }
            else if (balance < lowerLimit)
            {
                account.State = new SilverState(this);
            }
        }
    }

    /// <summary>
    /// Context class
    /// </summary>
    class Account

    {
        private State _state;
        private string _owner;

        // Constructor

        public Account(string owner)
        {
            // New accounts are 'Silver' by default

            this._owner = owner;
            this._state = new SilverState(0.0, this);
        }

        // Properties

        public double Balance
        {
            get { return _state.Balance; }
        }

        public State State
        {
            get { return _state; }
            set { _state = value; }
        }

        public void Deposit(double amount)
        {
            _state.Deposit(amount);
            Console.WriteLine("本次存款金额 {0:C} --- ", amount);
            Console.WriteLine(" 当前余额 = {0:C}", this.Balance);
            Console.WriteLine(" 账户状态 = {0}",
              this.State.GetType().Name);
            Console.WriteLine("");
        }

        public void Withdraw(double amount)
        {
            _state.Withdraw(amount);
            Console.WriteLine("本次取款金额 {0:C} --- ", amount);
            Console.WriteLine(" 当前余额 = {0:C}", this.Balance);
            Console.WriteLine(" 账户状态 = {0}\n",
              this.State.GetType().Name);
        }

        public void PayInterest()
        {
            _state.PayInterest();
            Console.WriteLine(" 利息 --- ");
            Console.WriteLine(" 当前余额 = {0:C}", this.Balance);
            Console.WriteLine(" 账户状态 = {0}\n",
              this.State.GetType().Name);
        }
    }
}
 
   


总结

状态模式,关键是搞清楚各状态之间的转移。也就是状态(state)、事件(Event)、动作(Action)之间事件触发的状态转移及动作执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值