天天看点

Net设计模式实例之状态模式(State Pattern)

状态模式(State Pattern),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。

当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。

Net设计模式实例之状态模式(State Pattern)

Context类:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态。

State类:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。

ConcreteStateA,ConcreteStateB,ConcreteStateC类:具体状态类,每一个子类实现一个与Context的一个状态相关的行为。

1、Context类:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态

public class Context

{

    private State state;

    public StateState

    {

        get { return state; }

        set

        {

            state = value;

            Console.WriteLine("当前状态是:" + state.GetType().Name);

        }

    }

    public Context(State state)

        this.state = state;

        Console.WriteLine("初始状态是:"+state.GetType().Name);

    public void Request()

        state.Handle(this);

}

2、抽象状态类及其具体实现类

public abstract class State

   public abstract void Handle(Context context);

public class ConcreteStateA:State

    public override void Handle(Context context)

        context.State = new ConcreteStateB();

public class ConcreteStateB: State

        context.State = new ConcreteStateC();

public class ConcreteStateC : State

        context.State = new ConcreteStateA();

4、客户端代码

static void Main(string[] args)

    Context context = new Context(new ConcreteStateA());

    context.Request();

    Console.Read();

Net设计模式实例之状态模式(State Pattern)

银行账户根据余额可分为三种状态RedState,SilverState,GoldState,这些状态分别代表了透支帐户(overdrawn accounts),新开帐户(starter accounts),标准帐户(accounts in good standing)..如下图所示

Net设计模式实例之状态模式(State Pattern)

RedState类:账号余额在范围【0.0,1000.0】表示处于处于SilverState。否则转换为其他状态。

if (balance < lowerLimit)

    account.State = new RedState(this);

else if (balance > upperLimit)

    account.State = new GoldState(this);

SilverState类:账号余额在范围【-100.0,0】表示处于处于RedState。否则转换为其他状态。

if (balance > upperLimit)

    account.State = new SilverState(this);

GoldState类:账号余额在范围【1000.0,10000000.0】表示处于处于GoldState。否则转换为其他状态。

if (balance < 0.0)

else if (balance < lowerLimit)

1、类Account,相当于Context类

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 StateState

            get { return _state; }

            set { _state = value; }

        public void Deposit(double amount)

            _state.Deposit(amount);

            Console.WriteLine("Deposited {0:C} --- ", amount);

            Console.WriteLine(" Balance = {0:C}", this.Balance);

            Console.WriteLine(" Status = {0}",

              this.State.GetType().Name);

            Console.WriteLine("");

        public void Withdraw(double amount)

            _state.Withdraw(amount);

            Console.WriteLine("Withdrew {0:C} --- ", amount);

            Console.WriteLine(" Status = {0}\n",

        public void PayInterest()

            _state.PayInterest();

            Console.WriteLine("Interest Paid --- ");

            Console.WriteLine(" Status = {0}\n",

2、抽象状态类State及其具体状态类RedState,SilverState,GoldState

/// <summary>

    /// The 'State' abstract class

    /// </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; }

            get { return balance; }

            set { balance = value; }

        public abstract void Deposit(double amount);

        public abstract void Withdraw(double amount);

        public abstract void PayInterest();

    /// <summary>

    /// A 'ConcreteState' class

    /// <remarks>

    /// Red indicates that account is overdrawn

    /// </remarks>

    class RedState : State

        private double _serviceFee;

        // Constructor

        public RedState(State state)

            this.balance = state.Balance;

            this.account = state.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("No funds available for withdrawal!");

        public override void PayInterest()

            // No interest is paid

        private void StateChangeCheck()

            if (balance > upperLimit)

            {

                account.State = new SilverState(this);

            }

    /// Silver indicates a non-interest bearing state

    class SilverState : State

        // Overloaded constructors

        public SilverState(State state)

            :

          this(state.Balance, state.Account)

        public SilverState(double balance, Account account)

            this.balance = balance;

            this.account = account;

            lowerLimit = 0.0;

            upperLimit = 1000.0;

        public override void Withdraw(double amount)

            balance -= amount;

            balance += interest * balance;

            if (balance < lowerLimit)

                account.State = new RedState(this);

            else if (balance > upperLimit)

                account.State = new GoldState(this);

    /// Gold indicates an interest bearing state

    class GoldState : State

        public GoldState(State state)

            : this(state.Balance, state.Account)

        public GoldState(double balance, Account account)

            // Should come from a database

            interest = 0.05;

            lowerLimit = 1000.0;

            upperLimit = 10000000.0;

        {

            if (balance < 0.0)

            else if (balance < lowerLimit)

3、客户端代码

    // Open a new account

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

    // Apply financial transactions

    account.Deposit(500.0);

    account.Deposit(300.0);

    account.Deposit(550.0);

    account.PayInterest();

    account.Withdraw(2000.00);

    account.Withdraw(1100.00);

    // Wait for user

    Console.ReadKey();

Net设计模式实例之状态模式(State Pattern)

状态模式(State Pattern),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。

版权

作者:灵动生活 郝宪玮

如果你认为此文章有用,请点击底端的【推荐】让其他人也了解此文章,

Net设计模式实例之状态模式(State Pattern)

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

继续阅读