状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
要点:
1. 策略模式和状态模式是双胞胎,它们有相同的类图,但是它们的意图不同。策略模式是围绕可以互换的算法来成功创建业务的,然而状态模式是通过改变对象内部的状态来帮助对象控制自己的行为.
2. Context将与状态相关的操作委托给当前的Concrete State对象处理。
3. Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。
4. Context或Concrete State类都可决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行状态转换。也就是说可以在State中保存对Concrete State的引用,在必要时设置具体的状态,做到状态的转换。
5. 一般来讲,当状态转换是固定的时候,状态转换就适合放在Context中。然而,当转换是更动态的时候,通常会放到具体的状态类中进行。(具体状态类持有Context的引用,实现状态的转换)
实现:
摘要:本文深入浅出的讲述了设计模式中的
状态
模式
,
并给出了简单的示例
,
例子浅显易懂
,
并附带源代码。
状态模式属于对象创建型模式,其意图是允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了他的类。比较常见的例子是在一个表示网络连接的类TCPConnection,一个TCPConnection对象的状态处于若干不同的状态之一:连接已经建立(Established),正在监听,连接已经关闭(closed)。当一个TCPConnection对象收到其他对象的请求时,他根据自身的状态作出不同的反应。例如:一个Open请求的结果依赖于该连接已关闭还是连接已建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。这一种模式的关键思想是引入了一个称为TCPState的抽象类表示网络的连接状态,TCPState类为各种表示不同的操作状态的字类声明了一个公共接口。TCPState的子类实现与特定的状态相关的行为。例如,TCPEstablished和TCPClosed类分别实现了特定于TCPConnection的连接已建立状态和连接已关闭状态的行为。
举例来说:一个人具有生气,高兴和抓狂等状态,在这些状态下做同一个事情可能会有不同的结果,一个人的心情可能在这三种状态中循环转变。使用一个moodState类表示一个人的心情,使用mad,Happy,Angry类代表不同的心情。使用UML图表示如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/695b87ca8cb8b1ca079ad0ddab3ed20f.gif)
适用性:在下面的两情况下均可以使用State模式:
- 一个对象的行为取决于它的状态,并且必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支的条件豫剧,并且这些分支依赖于该对象的状态,这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构,State模式将每一个条件分支放入一个单独的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
参与者:
- Context(环境,Person)定义客户感兴趣的类。
- State(Moodstate):定义一个接口以封装与Context的一个特定状态相关的行为
- ConcreteState Subclasses(具体状态子类,如Angry)每一个子类实现一个与Context的状态相关的行为。
他们的协作关系是:
- Context将于状态相关的请求委托给当前的ConcreteState对象处理。
- Context可将自身作为一个参数传递给处理该请求的状态对象,这使得状态对象在必要的时候可访问Context。
- Context是客户使用的主要接口,客户可用状态对象来配置一个Context,一旦一个Context配置完毕,他的客户不再需要直接与状态对象打交道。
- Context或者ConcreteState子类都可以决定哪个状态是另外那个状态的后继者,以及是在何种条件下进行状态转换。
相应的代码:
//MoodState代码
package state;
public interface MoodState{
public void doSomething();
public void changeState();
}
//Angry代码:
package state;
public class Angry implements MoodState{
Person p;
public Angry(Person p){
this.p = p;
}
public void doSomething(){
System.out.println("I'm angry!");
}
public void changeState(){
p.setState(new Happy(p));
}
}
//Happy代码:
package state;
public class Happy implements MoodState{
Person p;
public Happy(Person p){
this.p = p;
}
public void doSomething(){
System.out.println("I'm happy!");
}
public void changeState(){
p.setState(new Mad(p));
}
}
//Mad代码:
package state;
public class Mad implements MoodState{
Person p;
public Mad(Person p){
this.p=p;
}
public void doSomething(){
System.out.println("I'm Mad");
}
public void changeState(){
p.setState( new Angry(p));
}
}
//Person代码:
package state;
public class Person{
private MoodState state;
public Person(){
state = new Mad(this);
}
public void setState(MoodState state){
this.state = state;
}
public void doSomething(){
state.doSomething();
state.changeState();
}
}
//Client代码:
package state;
public class Client{
public static void main(String[] args){
Person p = new Person();
for(int i=0;i<10;i++)
p.doSomething();
}
}