C# 设计模式-状态模式

一.介绍  

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

二.实现

  举个例子,用银行账户的状态来实现状态模式,状态分为两种,一种是正常有钱可以取的状态,一种是已经透支了不能再取钱的状态。每次存钱取钱都会刷新一下这个账户的状态。

public class Account
{
    public State State { get; set; }
    public string Owner { get; set; }
    public Account(string owner)
    {
        this.Owner = owner;
        this.State = new NormalState(0.0, this);
    }

    public double Balance { get { return State.Balance; } } // 余额
    // 存钱
    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}", this.State.GetType().Name);
        Console.WriteLine();
    }
}

// 抽象状态类
public abstract class State
{
    // Properties
    public Account Account { get; set; }
    public double Balance { get; set; } // 余额
    public double LowerLimit { get; set; } // 下限
    public double UpperLimit { get; set; } // 上限

    public abstract void Deposit(double amount); // 存款
    public abstract void Withdraw(double amount); // 取钱
}

// Red State意味着Account透支了
public class RedState : State
{
    public RedState(State state)
    {
        // Initialize
        this.Balance = state.Balance;
        this.Account = state.Account;
        LowerLimit = -100.00;
        UpperLimit = 0.00;
    }

    // 存款
    public override void Deposit(double amount)
    {
        Balance += amount;
        StateChangeCheck();
    }
    // 取钱
    public override void Withdraw(double amount)
    {
        Console.WriteLine("没有钱可以取了!");
    }

    private void StateChangeCheck()
    {
        if (Balance > UpperLimit)
        {
            Account.State = new NormalState(this);
        }
    }
}

// Normal State正常状态
public class NormalState : State
{
    public NormalState(State state)
        : this(state.Balance, state.Account)
    {
    }

    public NormalState(double balance, Account account)
    {
        this.Balance = balance;
        this.Account = account;
        LowerLimit = 0.00;
        UpperLimit = 1000.00;
    }

    public override void Deposit(double amount)
    {
        Balance += amount;
        StateChangeCheck();
    }
    public override void Withdraw(double amount)
    {
        Balance -= amount;
        StateChangeCheck();
    }

    private void StateChangeCheck()
    {
        if (Balance < LowerLimit)
        {
            Account.State = new RedState(this);
        }
    }
}

//调用
public static void Main(string[] args)
{
    // 开一个新的账户
    var account = new Account("Learning Hard");

    // 进行交易
    // 存钱
    account.Deposit(1000.0);
    account.Deposit(200.0);
    account.Deposit(600.0);

    // 取钱
    account.Withdraw(2000.00);
    account.Withdraw(500.00);
}

  Account类内部存储着State的状态,State的抽象类定义了改变状态所需要执行的方法,具体状态类则是实现抽象类的方法,根据情况重新改变Account的状态。

三.总结

  优点

  1.将状态判断的逻辑放在每一个状态类里,可以简化判断的逻辑。

  2.当有新的状态出现时,可以通过增加新的状态类来拓展,拓展性好。

  缺点:

  1.如果状态类过多的话,会导致有非常多的状态类,加大了开销。

posted @ 2021-02-03 16:23  shine声  阅读(348)  评论(0编辑  收藏  举报