zoukankan      html  css  js  c++  java
  • 设计模式学习笔记状态模式

    概述:                                                                                                       

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

    适用场合:                                                                                                 

    1.当一个对象的转换条件表达式过于复杂时,通常这个状态由一个或者多个枚举表示,通常有多个操作包含这一相同的的条件结构,state模式将一个条件分支放到一个类中,这使得你可以根据对象自身的情况将对象的状态作为对象,这一对象不依赖于其他对象而独立变化,把状态的判断逻辑放到表示不同状态的一系列类中。

    2.一个对象的行为取决于它的状态,并且它必须在运行时根据状态立即改变行为。

    类图:                                                                                                         

    代码示例:                                                                                                 

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

        /// <summary>
    /// 维护一个ConcreteState子类的实例,这个实例定义当前的状态
    /// </summary>
    class Context
    {
    private State state;
    /// <summary>
    /// 定义context的初始状态
    /// </summary>
    /// <param name="state"></param>
    public Context(State state)
    {
    this.state = state;
    }
    /// <summary>
    /// 可读写的状态属性,用于读取当前状态和设置新状态
    /// </summary>
    public State State
    {
    get { return state; }
    set
    {
    state
    = value;
    Console.WriteLine(
    "当前的状态:"+state.GetType().Name);
    }
    }
    /// <summary>
    /// 对请求作出处理,并设置下一状态
    /// </summary>
    public void Request()
    {
    state.Handle(
    this);
    }
    }

    2.抽象状态类

        /// <summary>
    /// 抽象状态类,每个子类实现与Context的一个状态相关的行为
    /// </summary>
    abstract class State
    {
    public abstract void Handle(Context context);
    }

    3.具体状态类

        class ConcreteStateA:State
    {
    public override void Handle(Context context)
    {
    //设置状态A的下一状态是状态B
    context.State = new ConcreteStateB();
    }
    }
        class ConcreteStateB : State
    {
    public override void Handle(Context context)
    {
    //状态B的下一状态是状态A
    context.State = new ConcreteStateA();
    }
    }

    应用示例:摘自 灵动生活                                                                                  

    View Code
        class Account
    {
    private AccountState _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 AccountState 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);
    }
    }

    /// <summary>
    /// The 'State' abstract class
    /// </summary>
    abstract class AccountState
    {
    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 : AccountState
    {
    private double _serviceFee;
    // Constructor
    public RedState(AccountState 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 : AccountState
    {
    // Overloaded constructors
    public SilverState(AccountState 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 : AccountState
    {
    // Overloaded constructors
    public GoldState(AccountState 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);
    }
    }
    }

    /// <summary>
    /// 测试状态模式案例
    /// </summary>
    static void TestStateSample()
    {
    // 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();
    }

    小结:                                                                                                           

    状态类的主要作用就是消去大量条件判断

  • 相关阅读:
    快速幂&欧拉降幂
    欧拉函数
    素数打表-筛法
    多源最短路径问题(Floyd算法)
    蓝桥杯-本质上升序列
    蓝桥杯-玩具蛇
    SDUT-计算机组成原理
    取消U盘和移动硬盘的GPT保护分区
    Windows 10 上运行 photoshop 等软件出现 loadlibrary failed with error 87 的解决方法!
    做题笔记
  • 原文地址:https://www.cnblogs.com/jqbird/p/2154186.html
Copyright © 2011-2022 走看看