Net设计模式实例之状态模式(State Pattern)
一、状态模式简介(Brief Introdu ction)
状态模式(State Pattern),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
二、解决的问题(What To Solve)
状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
三、状态模式分析(Analysis)
1、状态模式结构
Context类:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态。
State类:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
ConcreteStateA,ConcreteStateB,ConcreteStateC类:具体状态类,每一个子类实现一个与Context的一个状态相关的行为。
2、源代码
1、Context类:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态 |
public class Context { private State state; public { 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 { Context context = new Context(new ConcreteStateA()); context.Request(); context.Request(); context.Request(); Console.Read(); } |
3、程序运行结果
四.案例分析(Example)
1、场景
银行账户根据余额可分为三种状态RedState,SilverState,GoldState,这些状态分别代表了透支帐户(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 { 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及其具体状态类RedState,SilverState,GoldState |
/// <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 { // 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
如果你认为此文章有用,请点击底端的【推荐】让其他人也了解此文章,
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南