1 状态模式介绍
2 状态模式结构
3 状态模式实现
代码示例
java
//抽象状态接口
public interface State {
//声明抽象方法,不同具体状态类可以有不同实现
void handle(Context context);
}
java
/**
* 上下文类
**/
public class Context {
//维持一个对状态对象的有引用
private State currentState;
public Context() {
this.currentState = null;
}
public Context(State currentState) {
this.currentState = currentState;
}
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State currentState) {
this.currentState = currentState;
}
@Override
public String toString() {
return "Context{" +
"currentState=" + currentState +
'}';
}
}
java
public class ConcreteStateA implements State {
@Override
public void handle(Context context) {
System.out.println("进入到状态模式A......");
context.setCurrentState(this);
}
@Override
public String toString() {
return "当前状态: ConcreteStateA";
}
}
java
public class ConcreteStateB implements State {
@Override
public void handle(Context context) {
System.out.println("进入到状态模式B......");
context.setCurrentState(this);
}
@Override
public String toString() {
return "当前状态: ConcreteStateB";
}
}
java
public class Client {
public static void main(String[] args) {
Context context = new Context();
State state1 = new ConcreteStateA();
state1.handle(context);
System.out.println(context.getCurrentState().toString());
System.out.println("=================================");
State state2 = new ConcreteStateB();
state2.handle(context);
System.out.println(context.getCurrentState().toString());
}
}
4 状态模式应用实例
- 不使用设计模式
java
/**
* 交通灯类有三种状态
* 红灯(禁行) ,黄灯(警示),绿灯(同行)
**/
public class TrafficLight {
//初始化状态
private String state = "红色";
//切换为绿灯,通行状态
public void switchToGreen(){
if("绿".equals(state)){ //当前是绿灯
System.out.println("当前为绿灯,无需切换!");
}else if("红".equals(state)){
System.out.println("红灯不能切换为绿灯");
}else if("黄".equals(state)){
state = "绿";
System.out.println("绿灯亮起...时长: 60秒");
}
}
//切换为黄灯,警示状态
public void switchToYellow() {
if ("黄".equals(state)) { //当前是黄灯
System.out.println("当前为黄灯,无需切换!");
} else if ("红".equals(state) || "绿".equals(state)) {
System.out.println("红灯不能切换为绿灯");
state = "黄";
System.out.println("黄灯亮起...时长:10秒");
}
}
//切换为红灯,禁止状态
public void switchToRed(){
if("红".equals(state)){ //当前是红灯
System.out.println("当前为红灯,无需切换!");
}else if("绿".equals(state)){
System.out.println("绿灯不能切换为红灯");
}else if("黄".equals(state)){
state = "红";
System.out.println("红灯亮起...时长: 90秒");
}
}
}
问题: 状态切换的操作全部在一个类中,如果有很多的交通灯进行联动,这个程序
的逻辑就会变得非常复杂,难以维护.
2) 使用状态模式,将交通灯的切换逻辑组织起来,把跟状态有关的内容从交通灯类
里抽离出来,使用类来表示不同的状态.
java
/**
* 交通灯类
**/
public class TrafficLight {
//初始化-红灯
State state = new RedState();
public void setState(State state) {
this.state = state;
}
//切换为绿灯,通行状态
public void switchToGreen(){
state.switchToGreen(this);
}
//切换为黄灯,警示状态
public void switchToYellow() {
state.switchToYellow(this);
}
//切换为红灯,禁止状态
public void switchToRed(){
state.switchToRed(this);
}
}
java
/**
* 交通灯状态接口
**/
public interface State {
void switchToGreen(TrafficLight trafficLight); //切换为绿灯
void switchToYellow(TrafficLight trafficLight); //切换为黄灯
void switchToRed(TrafficLight trafficLight); //切换为红灯
}
java
public class RedState implements State {
@Override
public void switchToGreen(TrafficLight trafficLight) {
System.out.println("红灯不能切换为绿灯!");
}
@Override
public void switchToYellow(TrafficLight trafficLight) {
System.out.println("黄灯亮起...时长: 10秒");
}
@Override
public void switchToRed(TrafficLight trafficLight) {
System.out.println("当前为红灯,无需切换!");
}
}
java
public class GreenState implements State {
@Override
public void switchToGreen(TrafficLight trafficLight) {
System.out.println("当前是绿灯,无需切换!");
}
@Override
public void switchToYellow(TrafficLight trafficLight) {
System.out.println("黄灯亮起...时长: 10秒");
}
@Override
public void switchToRed(TrafficLight trafficLight) {
System.out.println("绿灯不能够切换为红灯!");
}
}
java
public class YellowState implements State {
@Override
public void switchToGreen(TrafficLight trafficLight) {
System.out.println("绿灯亮起...时长:60秒!");
}
@Override
public void switchToYellow(TrafficLight trafficLight) {
System.out.println("当前是黄灯,无需切换!");
}
@Override
public void switchToRed(TrafficLight trafficLight) {
System.out.println("红灯亮起...时长:90秒!");
}
}
java
public class Client {
public static void main(String[] args) {
TrafficLight trafficLight = new TrafficLight();
trafficLight.switchToRed();
trafficLight.switchToGreen();
trafficLight.switchToYellow();
}
}
通过代码重构,将"状态" 接口化、模块化,最终将它们从臃肿的交通类中抽了出来,
消除了原来TrafficLight类中的if...else,代码看起来干净而优雅.