概念和作用
状态模式允许一个对象在其内部状态改变时改变它的行为,使得对象看起来像是修改了它的类。核心思想是将状态相关的行为封装到独立的状态类中,并通过委托方式动态切换状态逻辑。其作用是:
1.消除大量条件分支(如 if-else)。
2.将状态转换逻辑局部化到具体状态类中。
3.提高代码可维护性和扩展性(符合开闭原则)。
使用场景
1.对象行为依赖多个状态,且状态转换频繁。
2.需要消除大量状态判断分支(如电商订单、游戏角色状态)。
3.需要清晰分离不同状态的业务逻辑。
示例
订单状态场景分析------假设订单有以下状态和规则:
1.新建状态 (New):可完成订单、可取消订单。
2.已完成状态 (Completed):不可重复完成、不可取消。
3.已取消状态 (Cancelled):不可完成、不可重复取消。
实现代码(状态模式版)
1.定义状态接口
interface OrderState {
void complete(Order order);
void cancel(Order order);
}
2.实现具体状态类:新建、已完成、已取消
// 新建状态
class NewState implements OrderState {
@Override
public void complete(Order order) {
System.out.println("订单完成!");
order.setState(new CompletedState());
}
@Override
public void cancel(Order order) {
System.out.println("订单已取消!");
order.setState(new CancelledState());
}
}
// 已完成状态
class CompletedState implements OrderState {
@Override
public void complete(Order order) {
System.out.println("已完成订单不可重复完成!");
}
@Override
public void cancel(Order order) {
System.out.println("已完成订单不可取消!");
}
}
// 已取消状态
class CancelledState implements OrderState {
@Override
public void complete(Order order) {
System.out.println("已取消订单不可完成!");
}
@Override
public void cancel(Order order) {
System.out.println("已取消订单不可重复取消!");
}
}
3.订单类
class Order {
private OrderState state;
public Order() {
this.state = new NewState(); // 初始状态
}
public void setState(OrderState state) {
this.state = state;
}
// 委托给当前状态处理
public void complete() {
state.complete(this);
}
public void cancel() {
state.cancel(this);
}
}
4.测试类
public class StatePatternDemo {
public static void main(String[] args) {
Order order = new Order();
order.complete(); // 输出:订单完成!
order.cancel(); // 输出:已完成订单不可取消!
order = new Order();
order.cancel(); // 输出:订单已取消!
order.complete(); // 输出:已取消订单不可完成!
}
}
优缺点
|----------------------|--------------|
| 优点 | 缺点 |
| 消除复杂的条件判断 | 增加类的数量 |
| 状态转换逻辑集中管理 | 小规模场景可能过度设计 |
| 符合开闭原则(新增状态无需修改现有代码) | 状态间依赖可能增加复杂度 |
不使用状态模式的实现
class Order {
private String state; // "NEW", "COMPLETED", "CANCELLED"
public void complete() {
if ("NEW".equals(state)) {
System.out.println("订单完成!");
state = "COMPLETED";
} else if ("COMPLETED".equals(state)) {
System.out.println("已完成订单不可重复完成!");
} else if ("CANCELLED".equals(state)) {
System.out.println("已取消订单不可完成!");
}
}
public void cancel() {
if ("NEW".equals(state)) {
System.out.println("订单已取消!");
state = "CANCELLED";
} else if ("COMPLETED".equals(state)) {
System.out.println("已完成订单不可取消!");
} else if ("CANCELLED".equals(state)) {
System.out.println("已取消订单不可重复取消!");
}
}
}
问题
1.违反开闭原则:新增状态需修改所有方法。
2.条件分支膨胀,难以维护。
3.状态逻辑分散,无法复用。