zoukankan      html  css  js  c++  java
  • 状态模式(State Pattern)

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

    一、状态模式简介(Brief Introduction

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

    二、解决的问题(What To Solve

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

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

    三、状态模式分析(Analysis

    1、状态模式结构

     

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

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

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

    2、源代码

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

    public class Context

    {

        private State state;

     

        public State State

        {

            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

    {

        public override void Handle(Context context)

        {

            context.State = new ConcreteStateC();

        }

    }

    public class ConcreteStateC : State

    {

        public override void Handle(Context context)

        {

            context.State = new ConcreteStateA();

        }

    }

     

    4、客户端代码

    static void Main(string[] args)

    {

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

        context.Request();

        context.Request();

        context.Request();

        Console.Read();

    }

    3、程序运行结果

    四.案例分析(Example

    1、场景

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

    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)

    {

        account.State = new RedState(this);

    }

    else if (balance < lowerLimit)

    {

        account.State = new SilverState(this);

    }

    2、代码

    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 State State

            {

                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(" Balance = {0:C}", this.Balance);

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

                  this.State.GetType().Name);

            }

     

            public void PayInterest()

            {

                _state.PayInterest();

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

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

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

                  this.State.GetType().Name);

            }

        }

     

    2、抽象状态类State及其具体状态类RedStateSilverStateGoldState

    /// <summary>

        /// The 'State' abstract class

        /// </summary>

        abstract class State

        {

            protected Account account;

            protected double balance;

            protected double interest;

            protected double lowerLimit;

            protected double upperLimit;

     

            // Properties

            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();

     

        }

     

        /// <summary>

        /// A 'ConcreteState' class

        /// <remarks>

        /// Red indicates that account is overdrawn

        /// </remarks>

        /// </summary>

        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);

                }

            }

        }

        /// <summary>

     

        /// A 'ConcreteState' class

        /// <remarks>

        /// Silver indicates a non-interest bearing state

        /// </remarks>

        /// </summary>

        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;

                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);

                }

            }

        }

        /// <summary>

        /// A 'ConcreteState' class

        /// <remarks>

        /// Gold indicates an interest bearing state

        /// </remarks>

        /// </summary>

        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);

                }

            }

        }

     

    3、客户端代码

    static void Main(string[] args)

    {

        // 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();

    }

     

    3、程序运行结果

    五、总结(Summary

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

  • 相关阅读:
    volley框架使用
    Insert Interval
    candy(贪心)
    Best Time to Buy and Sell Stock
    Best Time to Buy and Sell Stock III
    distinct subsequences
    edit distance(编辑距离,两个字符串之间相似性的问题)
    trapping rain water
    word break II(单词切分)
    sudoku solver(数独)
  • 原文地址:https://www.cnblogs.com/Mayvar/p/wanghonghua_201109080323.html
Copyright © 2011-2022 走看看