状态模式(State Pattern)
状态模式属于行为型模式,它允许一个对象在其内部状态改变时改变其行为,看上去似乎是对象修改了它的类。
模式结构
- Context:环境类,负责维护一个State对象,定义了一个接口以封装与State的一个特定状态相关的行为。
- State:抽象状态类,定义了一个接口以封装与Context的一个特定状态相关的行为。
- ConcreteState:具体状态类,实现了State接口。
模式实现
下面我们通过一个简单的例子来说明状态模式。
假设我们有一个电视机,它有三种状态:开机、关机、待机。我们可以使用状态模式来实现电视机状态的转换。
代码示例
首先我们定义State接口:
public interface State {
void nextChannel();
void prevChannel();
void turnUp();
void turnDown();
}
它定义了电视机的一些基本操作,包括切换频道和调节音量。
然后我们定义三个具体状态类:
public class PowerOnState implements State {
@Override
public void nextChannel() {
System.out.println("切换到下一个频道");
}
@Override
public void prevChannel() {
System.out.println("切换到上一个频道");
}
@Override
public void turnUp() {
System.out.println("调高音量");
}
@Override
public void turnDown() {
System.out.println("调低音量");
}
}
public class PowerOffState implements State {
@Override
public void nextChannel() {
System.out.println("电视已经关机,无法操作");
}
@Override
public void prevChannel() {
System.out.println("电视已经关机,无法操作");
}
@Override
public void turnUp() {
System.out.println("电视已经关机,无法操作");
}
@Override
public void turnDown() {
System.out.println("电视已经关机,无法操作");
}
}
public class StandbyState implements State {
@Override
public void nextChannel() {
System.out.println("切换到下一个频道");
}
@Override
public void prevChannel() {
System.out.println("切换到上一个频道");
}
@Override
public void turnUp() {
System.out.println("调高音量");
}
@Override
public void turnDown() {
System.out.println("调低音量");
}
}
在具体状态类中,我们根据不同状态实现对应的操作。
最后我们定义Context类:
public class TV {
private State state;
public void setState(State state) {
this.state = state;
}
public void nextChannel() {
state.nextChannel();
}
public void prevChannel() {
state.prevChannel();
}
public void turnUp() {
state.turnUp();
}
public void turnDown() {
state.turnDown();
}
}
在Context类中,我们定义了电视机的基本操作,并定义了一个setState方法来切换电视机的状态。
下面是客户端代码:
public class Client {
public static void main(String[] args) {
TV tv = new TV();
tv.setState(new PowerOnState());
tv.nextChannel();
tv.turnUp();
tv.turnDown();
tv.setState(new PowerOffState());
tv.nextChannel();
tv.setState(new StandbyState());
tv.prevChannel();
}
}
在客户端代码中,我们创建了一个TV对象,并对它进行一系列状态操作。
优缺点
优点
- 状态模式将与特定状态相关的行为局部化到一个状态对象中,并将不同的状态分开处理。这样使用状态模式可以让我们将大块的条件语句消除,使代码更加清晰。
- 与状态相关的行为都被封装在一个类中,并且可以很方便地增加新的状态,使状态更加易于维护。
- 状态模式是开闭原则的体现。由于它使用了多态性原则,新的状态可以很容易地被添加到系统中。
缺点
- 状态模式会增加系统的结构和复杂性,因此在小程序或简单程序中使用状态模式可能会增加系统的复杂性和难度。
- 如果状态转换比较复杂,可能会导致状态类的数目增加,从而增加系统的复杂性。
模式总结
状态模式是一种将特定状态相关的行为局部化的设计模式。它以类的形式表示状态,并将每个状态所对应的行为分离到不同的类中。这样我们就能够通过改变状态对象来改变实例的行为。使用状态模式的好处是,它让我们将一个对象的状态从该对象中分离出来,并将状态的转换变得更加清晰和简单。