package com.designpattern;
/**
* 状态模式
*/
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context(new NewState());
context.execute(1);
context.execute(2);
context.execute(3);
// 适合场景,数据有状态,状态就一定会流转,从状态 1 变成状态2
// 将不同的状态要执行的代码逻辑封装在不同的state类中
// 有一个 context类,负责根据传入的参数,决定这份数据的状态流转到什么状态
// 适合的场景太明显了,只要有状态,都按照标准的状态模式来实现,改进
// 不同的状态逻辑放在不同state类
// 有一个类负责状态之间的流转以及状态逻辑的执行
}
public interface State {
public void execute();
}
public static class NewState implements State {
@Override
public void execute() {
System.out.println("新建销售出库单逻辑");
}
}
public static class ApprovingState implements State {
@Override
public void execute() {
System.out.println("执行销售出库单待审批状态的逻辑");
}
}
public static class ApprovedState implements State {
@Override
public void execute() {
System.out.println("执行销售出库单已审批状态的逻辑");
}
}
public static class FinishedState implements State {
@Override
public void execute() {
System.out.println("执行销售出库单已完成状态的逻辑");
}
}
public static class Context {
private State state;
public Context(State state) {
this.state = state;
this.state.execute();
}
public void execute(int stateType) {
if (stateType == 1) {
this.state = new ApprovingState();
} else if (stateType == 2) {
this.state = new ApprovedState();
} else if (stateType == 3) {
this.state = new FinishedState();
}
state.execute();
}
}
}
模式优缺点
优点
1、封装了转换规则。
2、枚举可能的状态,在枚举状态之前需要确定状态种类。
3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点
1、状态模式的使用必然会增加系统类和对象的个数。
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
3、状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
模式适用场景
1、对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为。
2、代码中包含大量与对象状态有关的条件语句
模式总结
1、状态模式允许一个对象基于内部状态而拥有不同的行为。
2、Context会将行为委托给当前状态对象。
3、状态模式对“开闭原则”支持不是很好。