状态者模式(StatePattern)

状态者模式介绍


状态者模式:

  1. 当一个类中有多个状态时,每个状态对应着不同的行为。那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码。这样的设计显然违背了开闭原则。状态模式正是用来解决这样的问题的。
  2. 状态者模式是对对象状态的抽象,从而把对象中对状态复杂的判断逻辑已到各个状态类里面,从而简化逻辑判断。

状态者模式的组成: 1.抽象的状态类 2.状态类的具体实现 3.使用状态的对象

例子

  1. 打篮球的时候运动员可以有正常状态、不正常状态和超常状态。
  2. 曾侯乙编钟中,’钟是抽象接口’,’钟A’等是具体状态,’曾侯乙编钟’是具体环境(Context)。
  3. 银行账户根据余额可分为RedState、SilverState和GoldState。这些状态分别代表透支账号,新开账户和标准账户。账号余额在【-100.0,0.0】范围表示处于RedState状态,账号余额在【0.0 , 1000.0】范围表示处于SilverState,账号在【1000.0, 100000.0】范围表示处于GoldState状态。下面以这样的一个场景实现下状态者模式,具体实现代码如下所示:

下面,就以银行账户的状态来实现下状态者模式。


状态者模式UML图


这里写图片描述


状态者模式的实现


Account(账户类,包含账户状态和账户的用户名):

using System;

namespace cchoop.StatePattern
{
    class Account
    {
        public State MyState { get; set; }
        public string Owner { get; set; }

        public Account(string owner)
        {
            this.Owner = owner;
            //默认状态为新开账户的状态
            this.MyState = new SilverState(0.00f, this);
        }

        //存钱
        public void Deposit(float amount)
        {
            MyState.Deposit(amount);
            Console.WriteLine("存款金额为:" + amount);
            Console.WriteLine("账户本息总金额为:" + MyState.Balance);
            Console.WriteLine("账户状态为:" + MyState.GetType().Name);
            Console.WriteLine("=======================================");
        }

        //取钱
        public void WithDraw(float amount)
        {
            MyState.WithDraw(amount);
            Console.WriteLine("取款金额为:" + amount);
            Console.WriteLine("账户本息总金额为:" + MyState.Balance);
            Console.WriteLine("账户状态为:" + MyState.GetType().Name);
            Console.WriteLine("=======================================");
        }

        //获取利息
        public void PayInterest()
        {
            MyState.PayInterest();
            Console.WriteLine("账户余额为:" + MyState.Balance);
            Console.WriteLine("账户状态为:" + MyState.GetType().Name);
            Console.WriteLine("=======================================");
        }
    }
}

State(账户的状态抽象类,所有具体的状态类必须继承自该类):

using System;

namespace cchoop.StatePattern
{
    abstract class State
    {
        public Account Account { get; set; }
        public float Balance { get; set; }     //余额
        public float Interest { get; set; }    //利率
        public float LowerLimit { get; set; }  //下限
        public float UpperLimit { get; set; }  //上限

        public abstract void Deposit(float amount);   //存款
        public abstract void WithDraw(float amount);  //取钱
        public abstract void PayInterest();         //获得的利息
        public abstract void CheckState();   //检查状态,进行状态的切换

    }
}

RedState(透支状态):

using System;

namespace cchoop.StatePattern
{
    /// <summary>
    /// 账户透支状态,账号余额在【-100.0,0.0】范围
    /// </summary>
    class RedState:State
    {
        public RedState(State state)
        {
            this.Balance = state.Balance;
            this.Account = state.Account;
            this.Interest = 0.00f;
            this.LowerLimit = -100.0f;
            this.UpperLimit = 0.0f;

        }

        public override void Deposit(float amount)
        {
            this.Balance += amount;
            CheckState();
        }

        public override void WithDraw(float amount)
        {
            Console.WriteLine("账户已经透支,没有钱可以取了喔!");
        }

        public override void PayInterest()
        {
            Console.WriteLine("账户已经透支,没有利息的!");
        }
        public override void CheckState()
        {
            if (this.Balance > this.UpperLimit)
            {
                Account.MyState = new SilverState(this);
            }
        }
    }
}

SilverState(新开户状态):

using System;

namespace cchoop.StatePattern
{
    class SilverState:State
    {
        /// <summary>
        /// 账户新开户状态,余额在【0.0 , 1000.0】范围
        /// </summary>
        public SilverState(State state)
            : this(state.Balance, state.Account)
        {

        }
        public SilverState(float balance, Account account)
        {
            this.Balance = balance;
            this.Account = account;
            this.Interest = 0.01f;
            this.LowerLimit = 0.0f;
            this.UpperLimit = 1000.0f;
        }

        public override void Deposit(float amount)
        {
            this.Balance += amount;
            CheckState();

        }

        public override void WithDraw(float amount)
        {
            this.Balance -= amount;
            CheckState();
        }

        public override void PayInterest()
        {
            this.Balance += this.Balance * this.Interest;
            CheckState();
        }


        public override void CheckState()
        {
            if (this.Balance > this.UpperLimit)
            {
                Account.MyState = new GoldState(this);
            }
            else if (this.Balance < this.LowerLimit)
            {
                Account.MyState = new RedState(this);
            }
        }

    }
}

GoldState(标准状态):

using System;

namespace cchoop.StatePattern
{
    /// <summary>
    /// 账户标准状态,账号在【1000.0, 100000.0】范围
    /// </summary>
    class GoldState : State
    {
        public GoldState(State state)
        {
            this.Balance = state.Balance;
            this.Account = state.Account;
            this.Interest = 0.05f;
            this.LowerLimit = 1000.0f;
            this.UpperLimit = 100000.0f;
        }
        public override void Deposit(float amount)
        {
            this.Balance += amount;
            CheckState();
        }

        public override void WithDraw(float amount)
        {
            this.Balance -= amount;
            CheckState();
        }

        public override void PayInterest()
        {
            this.Balance += this.Balance * this.Interest;
            CheckState();
        }

        public override void CheckState()
        {
            if (this.Balance < 0.0f)
            {
                Account.MyState = new RedState(this);
            }
            else if (this.Balance < this.LowerLimit)
            {
                Account.MyState = new SilverState(this);
            }
        }
    }
}

Customer(测试):

using System;

namespace cchoop.StatePattern
{
    class Customer
    {
        static void Main(string[] args)
        {
            Account account = new Account("cchoop");
            account.Deposit(200);
            account.WithDraw(500);
            account.WithDraw(500);
        }
    }
}

这里写图片描述


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cchoop

有用的话请杯肥宅水

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值