设计模式学习总结-状态模式(State Method)
2012-07-25 15:53
411 查看
问题:
在面向对象软件设计时,常常碰到某一个对象由于状态的不同而有不同的行为。我们可以采用switch…case语句来解决问题,但是,如果这种状态变化比较频繁(状态的数量会变化),状态、判断逻辑、行为耦合在一起,当系统中需要加入新的状态时,必须修改判断逻辑(加入新的case...)。
定义:
状态模式(State Pattern)是一种行为模式。当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
意图:
定义一个Context,接收客户端配置的具体状态对象,并将与状态相关的请求委托给当前的ConcreteState对象处理,并将Context自身作为一个参数传递给处理该请求的状态对象,这使得状态对象在执行完成后,可以访问context修改状态(也可以由context控制修改)。State模式把状态的判断逻辑转移到表示不同状态的一系列类中,所有与一个特定状态相关的行为都放入每个单独的类中,使得复杂的判断逻辑简单化,并达到了解耦的目的。
参与者:
•环境(Context)角色:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态。
•状态(State)角色:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
•具体状态(ConcreteState)角色:每一个子类实现一个与Context的一个状态相关的行为。
UML:
![](http://images.cnblogs.com/cnblogs_com/ejiyuan/DesignPattern/State.JPG)
代码说明:
/// <summary>
/// Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
/// </summary>
public class Context
{
/// <summary>
/// 存储状态
/// </summary>
public StateClass State { get; set; }
/// <summary>
/// 定义Context的初始状态
/// </summary>
/// <param name="state"></param>
public Context(StateClass state)
{
this.State = state;
}
/// <summary>
/// 对请求做处理
/// </summary>
public void Request()
{
//将当前对象作为参数传递给具体的State
State.Handle(this);
}
}
/// <summary>
/// 抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为
/// </summary>
public abstract class StateClass
{
public abstract void Handle(Context context);
}
/// <summary>
/// 具体状态类,每一个子类实现一个与Context的一个状态相关的行为
/// </summary>
public class ConcreteStateA : StateClass
{
/// <summary>
/// 设置ConcreteStateA的下一个状态是ConcreteStateB
/// </summary>
/// <param name="context"></param>
public override void Handle(Context context)
{
Console.WriteLine("当前状态是 A.");
context.State = new ConcreteStateB();
}
}
public class ConcreteStateB : StateClass
{
/// <summary>
/// 设置ConcreteStateB的下一个状态是ConcreteSateA
/// </summary>
/// <param name="context"></param>
public override void Handle(Context context)
{
Console.WriteLine("当前状态是 B.");
context.State = new ConcreteStateA();
}
}
/// <summary>
/// 客户端测试代码
/// </summary>
public void StateTest()
{
//初始化一个状态
Context Context = new Context(new ConcreteStateA());
//执行请求,并修改状态。
Context.Request();
//执行请求,并修改状态。
Context.Request();
//执行请求,并修改状态。
Context.Request();
}优点:
•状态模式把各种状态转移逻辑分布到一系列State的子类中,来减少相互间的依赖。
•所有状态相关的行为都放在某个ConcereteState中,通过定义新的ConcereteState很容易地增加新的状态和转换。
缺点:
•状态的转换被定义在concreteState或context中,也就是说由concreteState或context决定下一个状态,状态的插入仍需要修改代码
适用场合:
•当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
•一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。
与策略模式区别:
策略模式关注行为的变化,但归根结底只有一个行为,变化的只是行为的实现.客户不关注这些.当新增变化时对客户可以没有任何影响.
状态模式同样关注行为的变化,但这个变化是由状态来驱动,一般来说每个状态和行为都不同.新增的状态或行为一般与已有的不同,客户需要关注这些变化.
状态模式中State及其子类中的操作都将Context传入作为参数,以便State可以通过这个指针调用Context中的方法,修改状态。而策略模式没有。
在面向对象软件设计时,常常碰到某一个对象由于状态的不同而有不同的行为。我们可以采用switch…case语句来解决问题,但是,如果这种状态变化比较频繁(状态的数量会变化),状态、判断逻辑、行为耦合在一起,当系统中需要加入新的状态时,必须修改判断逻辑(加入新的case...)。
定义:
状态模式(State Pattern)是一种行为模式。当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
意图:
定义一个Context,接收客户端配置的具体状态对象,并将与状态相关的请求委托给当前的ConcreteState对象处理,并将Context自身作为一个参数传递给处理该请求的状态对象,这使得状态对象在执行完成后,可以访问context修改状态(也可以由context控制修改)。State模式把状态的判断逻辑转移到表示不同状态的一系列类中,所有与一个特定状态相关的行为都放入每个单独的类中,使得复杂的判断逻辑简单化,并达到了解耦的目的。
参与者:
•环境(Context)角色:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态。
•状态(State)角色:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
•具体状态(ConcreteState)角色:每一个子类实现一个与Context的一个状态相关的行为。
UML:
代码说明:
/// <summary>
/// Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
/// </summary>
public class Context
{
/// <summary>
/// 存储状态
/// </summary>
public StateClass State { get; set; }
/// <summary>
/// 定义Context的初始状态
/// </summary>
/// <param name="state"></param>
public Context(StateClass state)
{
this.State = state;
}
/// <summary>
/// 对请求做处理
/// </summary>
public void Request()
{
//将当前对象作为参数传递给具体的State
State.Handle(this);
}
}
/// <summary>
/// 抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为
/// </summary>
public abstract class StateClass
{
public abstract void Handle(Context context);
}
/// <summary>
/// 具体状态类,每一个子类实现一个与Context的一个状态相关的行为
/// </summary>
public class ConcreteStateA : StateClass
{
/// <summary>
/// 设置ConcreteStateA的下一个状态是ConcreteStateB
/// </summary>
/// <param name="context"></param>
public override void Handle(Context context)
{
Console.WriteLine("当前状态是 A.");
context.State = new ConcreteStateB();
}
}
public class ConcreteStateB : StateClass
{
/// <summary>
/// 设置ConcreteStateB的下一个状态是ConcreteSateA
/// </summary>
/// <param name="context"></param>
public override void Handle(Context context)
{
Console.WriteLine("当前状态是 B.");
context.State = new ConcreteStateA();
}
}
/// <summary>
/// 客户端测试代码
/// </summary>
public void StateTest()
{
//初始化一个状态
Context Context = new Context(new ConcreteStateA());
//执行请求,并修改状态。
Context.Request();
//执行请求,并修改状态。
Context.Request();
//执行请求,并修改状态。
Context.Request();
}优点:
•状态模式把各种状态转移逻辑分布到一系列State的子类中,来减少相互间的依赖。
•所有状态相关的行为都放在某个ConcereteState中,通过定义新的ConcereteState很容易地增加新的状态和转换。
缺点:
•状态的转换被定义在concreteState或context中,也就是说由concreteState或context决定下一个状态,状态的插入仍需要修改代码
适用场合:
•当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
•一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。
与策略模式区别:
策略模式关注行为的变化,但归根结底只有一个行为,变化的只是行为的实现.客户不关注这些.当新增变化时对客户可以没有任何影响.
状态模式同样关注行为的变化,但这个变化是由状态来驱动,一般来说每个状态和行为都不同.新增的状态或行为一般与已有的不同,客户需要关注这些变化.
状态模式中State及其子类中的操作都将Context传入作为参数,以便State可以通过这个指针调用Context中的方法,修改状态。而策略模式没有。
相关文章推荐
- 设计模式学习总结:状态模式(State)
- 设计模式学习总结10 - 行为型5 - State状态模式
- 设计模式学习总结(20) 状态模式
- 学习《Head First 设计模式》的一点小小的感悟与总结(一)——设计模式简介
- 设计模式学习笔记(十四)——创建型模式总结
- [学习笔记]设计模式[a]-{状态模式}
- 学习JavaScript设计模式之状态模式
- 设计模式学习-----状态模式
- 学习JavaScript设计模式之状态模式
- 设计模式之状态模式学习理解
- 设计模式学习笔记--状态模式
- 学习设计模式经验总结
- 设计模式学习总结(13) 策略模式
- 设计模式学习笔记——结构模式(总结)
- [转]设计模式学习笔记——结构型模式总结
- 设计模式学习之路总结
- 设计模式 学习资料总结
- 设计模式学习总结(5) 原型模式
- 设计模式学习总结3 - 创建型3 - FactoryMethod工厂方法模式
- 设计模式学习总结(22) 解释器模式