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

简介: 一、状态模式简介(Brief Introduction) 状态模式(State Pattern),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。 二、解决的问题(What To Solve) 状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。

一、状态模式简介(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 StateState

    {

        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 StateState

        {

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

 

版权

作者:灵动生活 郝宪玮

出处:http://www.cnblogs.com/ywqu

如果你认为此文章有用,请点击底端的【推荐】让其他人也了解此文章,

img_2c313bac282354945ea179a807d7e70d.jpg

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

相关文章
|
Java C#
使用C# (.NET Core) 实现适配器模式 (Adapter Pattern) 和外观模式 (Facade Pattern)
本文的概念内容来自深入浅出设计模式一书 现实世界中的适配器(模式) 我带着一个国标插头的笔记本电脑, 来到欧洲, 想插入到欧洲标准的墙壁插座里面, 就需要用中间这个电源适配器. 面向对象的适配器 你有个老系统, 现在来了个新供应商的类, 但是它们的接口不同, 如何使用这个新供应商的类呢? 首先, 我们不想修改现有代码, 你也不能修改供应商的代码.
1773 0
|
C#
使用C# (.NET Core) 实现组合设计模式 (Composite Pattern)
本文的概念性内容来自深入浅出设计模式一书. 本文需结合上一篇文章(使用C# (.NET Core) 实现迭代器设计模式)一起看. 上一篇文章我们研究了多个菜单一起使用的问题. 需求变更 就当我们感觉我们的设计已经足够好的时候, 新的需求来了, 我们不仅要支持多种菜单, 还要支持菜单下可以拥有子菜单.
1464 0
|
Java C# 设计模式
使用C# (.NET Core) 实现迭代器设计模式 (Iterator Pattern)
本文的概念来自深入浅出设计模式一书 项目需求 有两个饭店合并了, 它们各自有自己的菜单. 饭店合并之后要保留这两份菜单. 这两个菜单是这样的: 菜单项MenuItem的代码是这样的: 最初我们是这样设计的, 这是第一份菜单: 这是第2份菜单: 同时有两个菜单存在的问题 问题就是多个菜单把事情变复杂了.
1036 0
|
算法 C# Java
使用C# (.NET Core) 实现模板方法模式 (Template Method Pattern)
本文的概念内容来自深入浅出设计模式一书. 项目需求 有一家咖啡店, 供应咖啡和茶, 它们的工序如下: 咖啡: 茶: 可以看到咖啡和茶的制作工序是差不多的, 都是有4步, 其中有两步它们两个是一样的, 另外两步虽然具体内容不一样, 但是都做做的同一类工作.
1382 0
|
C#
使用C# (.NET Core) 实现命令设计模式 (Command Pattern)
本文的概念内容来自深入浅出设计模式一书. 项目需求 有这样一个可编程的新型遥控器, 它有7个可编程插槽, 每个插槽可连接不同的家用电器设备. 每个插槽对应两个按钮: 开, 关(ON, OFF).
860 0
|
Java C#
使用C# (.NET Core) 实现单体设计模式 (Singleton Pattern)
本文的概念内容来自深入浅出设计模式一书 由于我在给公司做内培, 所以最近天天写设计模式的文章.... 单体模式 Singleton 单体模式的目标就是只创建一个实例. 实际中有很多种对象我们可能只需要它们的一个实例, 例如: 线程池,缓存, 弹出的对话框, 用于保存设置的类, 用于logging的类, 硬件设备驱动对象等等.
1228 0
|
C#
使用C# (.NET Core) 实现抽象工厂设计模式 (Abstract Pattern)
本文的概念性内容来自深入浅出设计模式一书. 上一篇文章讲了简单工厂和工厂方法设计模式 http://www.cnblogs.com/cgzl/p/8760250.html, 使用的是披萨店的例子. 文将继续使用这个例子, 这里要用到抽象工厂.
1373 0
|
C# 设计模式 .NET
使用C# (.NET Core) 实现简单工厂(Simple Factory) 和工厂方法设计模式 (Factory Method Pattern)
本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子.   前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是接口(interface).
1460 0
|
安全 C# 数据安全/隐私保护
使用C# (.NET Core) 实现装饰模式 (Decorator Pattern) 并介绍 .NET/Core的Stream
该文章综合了几本书的内容. 某咖啡店项目的解决方案 某咖啡店供应咖啡, 客户买咖啡的时候可以添加若干调味料, 最后要求算出总价钱. Beverage是所有咖啡饮料的抽象类, 里面的cost方法是抽象的.
1393 0
|
C#
使用C# (.NET Core) 实现观察者模式 (Observer Pattern) 并介绍 delegate 和 event
观察者模式 这里面综合了几本书的资料. 需求 有这么个项目:  需求是这样的: 一个气象站, 有三个传感器(温度, 湿度, 气压), 有一个WeatherData对象, 它能从气象站获得这三个数据.
1971 0