设计模式之状态模式

一、什么是状态模式

状态模式,对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

状态模式,属于行为型设计模式。

二、状态模式类图

设计模式之状态模式插图

三、状态模式角色

  • 抽象状态角色(State): 定义一个接口以封装使用上下文环境的一个特定状态相关的行为。
  • 具体状态角色(ConcreteState): 实现抽象状态定义的接口。
  • 环境角色(Context): 定义了客户端需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的ConcreteState对象来处理。

四、状态模式优缺点

1、优点

  1. 将所有与某个状态有关的行为放到一个类中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  2. 将不同的状态引入单独的对象中会使得状态转换变得更加明确,减少对象间的相互依赖。
  3. 有利于程序的扩展。新增状态可以通过新增状态子类来完成,满足”开闭原则“。

2、缺点

  1. 增加了系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

五、状态模式demo示例

1、Demo需求

以电商平台订单状态为例,使用状态模式实现订单状态流转,订单状态:待支付、待发货、已发货、已收货。

2、抽象类定义

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
  * @Description: 抽象状态角色:抽象订单状态类
  **/ public abstract class OrderState {
 
     /**
      * 待支付状态
      *
      * @param context
      */     public abstract void unpay(OrderContext context);
  
     /**
      * 待发货状态
      *
      * @param context
      */     public abstract void undelivered(OrderContext context);
  
     /**
      * 已发货状态
      *
      * @param context
      */     public abstract void delivered(OrderContext context);
  
     /**
      * 已收货状态
      *
      * @param context
      */     public abstract void received(OrderContext context);
 }

3、实现类定义

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
  * @Description: 具体订单状态角色:待支付状态
  **/ public class UnpayState extends OrderState {
 
     @Override
     public void unpay(OrderContext context) {
         System.out.println("订单待支付状态");
         context.setState(new UndeliveredState());
     }
  
     @Override
     public void undelivered(OrderContext context) {
         System.out.println("订单待支付状态,请先支付");
     }
  
     @Override
     public void delivered(OrderContext context) {
         System.out.println("订单待支付状态,请先支付");
     }
  
     @Override
     public void received(OrderContext context) {
         System.out.println("订单待支付状态,请先支付");
     }
 }
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
  * @Description: 具体订单状态角色:待发货状态类
  **/ public class UndeliveredState extends OrderState {
 
     @Override
     public void unpay(OrderContext context) {
         System.out.println("订单已支付,请不要重复支付");
     }
  
     @Override
     public void undelivered(OrderContext context) {
         System.out.println("订单已支付等待发货啦");
         context.setState(new DeliveredState());
     }
  
     @Override
     public void delivered(OrderContext context) {
         System.out.println("订单待发货,请先发货");
     }
  
     @Override
     public void received(OrderContext context) {
         System.out.println("订单待发货,请先发货");
     }
 }
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
  * @Description: 具体订单状态角色:已发货状态类
  **/ public class DeliveredState extends OrderState {
 
     @Override
     public void unpay(OrderContext context) {
         System.out.println("订单已支付,请不要重复支付");
     }
  
     @Override
     public void undelivered(OrderContext context) {
         System.out.println("订单已发货,请不要重复发货");
     }
  
     @Override
     public void delivered(OrderContext context) {
         System.out.println("订单已发货啦");
         context.setState(new ReceivedState());
     }
  
     @Override
     public void received(OrderContext context) {
         System.out.println("订单已发货,未收到");
     }
 }
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
  * @Description: 具体订单状态角色:已收货状态类
  **/ public class ReceivedState extends OrderState {
 
     @Override
     public void unpay(OrderContext context) {
         System.out.println("订单已支付,请不要重复支付");
     }
  
     @Override
     public void undelivered(OrderContext context) {
         System.out.println("订单已发货,请不要重复发货");
     }
  
     @Override
     public void delivered(OrderContext context) {
         System.out.println("订单已发货啦");
     }
  
     @Override
     public void received(OrderContext context) {
         System.out.println("订单已收货啦");
     }
 }

4、上下文类定义

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
  * @Description: 环境角色:订单上下文类
  **/ public class OrderContext {
 
     // 抽象订单状态对象
     private OrderState state;
  
     public void setState(OrderState state) {
         this.state = state;
     }
  
     /**
      * 订单待支付状态
      */     public void unpay() {
         state.unpay(this);
     }
  
     /**
      * 订单待发货状态
      */     public void undelivered() {
         state.undelivered(this);
     }
  
     /**
      * 订单已发货状态
      */     public void delivered() {
         state.delivered(this);
     }
  
     /**
      * 订单已收货状态
      */     public void received() {
         state.received(this);
     }
 }

5、测试

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
/**
  * @Description: 状态模式客户端测试类
  **/ public class Client {
  
     public static void main(String[] args) {
         OrderContext context = new OrderContext();
         // 1.订单待支付状态
         context.setState(new UnpayState());
         context.unpay();
         // 2.订单待发货状态
         context.setState(new UndeliveredState());
         context.undelivered();
         // 3.订单已发货状态
         context.setState(new DeliveredState());
         context.delivered();
         // 3.订单已收货状态
         context.setState(new ReceivedState());
         context.received();
     }
 }

控制台日志:

1
2
3
4
订单待支付状态
订单已支付等待发货啦
订单已发货啦
订单已收货啦

发表评论

欢迎阅读『设计模式之状态模式|Java、设计模式|Nick Tan-梓潼Blog』