状态模式

 

同一个对象,内部属性不同的时候,具备的状态也不同

例子为银行的存款,默认申请的都是银卡,如果金额小于0并且在银行可容忍的状态内的话,为红色状态,如果数量很大,那么为金卡状态,否则为超大金额(这里暂时不论这个,其实都是一样的,只不过多加一个类而已)

红卡每次取钱需要服务费(这个也没什么用)

 (各个状态之间通过属性限制,可以自由的进行切换,原理就是在内部进行各自的判别,达到一定数量的时候,切换到需要的实例上去)(通过账户类默认一个实例进入到状态列表中,自动实现各个状态动态切换选择)

多个状态切换的时候, 应用每个状态的内部状态类,完成类字段属性的传递!

   //抽象状态类
    abstract class State
    {
        protected Account account;
        protected double balance;//总金额

        public double Balance { get { return balance; } set { balance = value; } }
        public Account Account { get { return account; } set{ account = value; } }
        protected double interest;//利率
        protected double lowerLimit;//最小限制
        protected double upperLimit;//最大限制

        public abstract void Deposit(double amount);//存钱
        public abstract void Withdraw(double amount);//取钱
        public abstract void PayInterest();//支付利息
    }
    #region 具体状态类别
    //红色状态卡
    class RedState : State
    {
        double serviceFee;//服务费
        public RedState(State state)
        {
            this.account = state.Account;
            this.Balance = state.Balance;
            Initialize();
        }
        public 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 PayInterest()
        {
            //红卡表示在可容忍的情况下,欠费,无利息
        }

        public override void Withdraw(double amount)
        {
            amount = amount - serviceFee;
            Console.WriteLine("No funds available for withdrawal!");
        }

        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 PayInterest()
        {
            balance += interest*balance;
            StateChangeCheck();
        }

        public override void Withdraw(double amount)
        {
            balance -= amount;
            StateChangeCheck();
        }
        private void StateChangeCheck()
        {
            if (Balance > upperLimit)
            {
                account.State = new GoldState(this);
            }
            else if(Balance<lowerLimit)
            {
                account.State = new RedState(this);
            }
        }
    }
    //金卡
    class GoldState : State
    {
        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 PayInterest()
        {
            balance += interest * balance;
            StateChangeCheck();
        }

        public override void Withdraw(double amount)
        {
            balance -= amount;
            StateChangeCheck();
        }
        private void StateChangeCheck()
        {
            if (Balance > upperLimit)
            {
                Console.WriteLine("金额太大了,需要开会讨论一下了");
            }
            else
            {
                account.State = new SilverState(this);
            }
        }
    }
    #endregion

 

    // 账户类
    class Account
    {
        public State State { get; set; }
        private string owner;
        public double Balance { get {return State.Balance; } }
        public Account(string name)
        {
            this.owner = name;
            State = new SilverState(0.0, this);//默认就是银卡
        }
        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}\n",
              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);
        }
    }
 //实现
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.Read();
        }

状态模式让对象最终知道它属于哪个状态,策略模式让对象找到属于自己的本身情况对应类别该执行的方法。

posted @ 2020-01-12 11:37  程序杰杰  阅读(204)  评论(0编辑  收藏  举报