在一些复杂的业务当中,涉及到某个业务有多个状态,按照传统写法无非就是if else
,其实还是有一种比较优雅的实现方式,就是设计模式中的状态机模式。没有spring之前虽然也能实现状态机模式,但是并不优雅。下面来说一个用springboot来实现状态机模式的案例。
举一个例子,比如订单:订单当中涉及到多个状态的跳转,有的时候还需要对修改状态前的逻辑进行判断,这个时候用状态机模式就是很好的实现。
1、引入部分依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <groupId>org.example</groupId> <artifactId>order_demo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <artifactId>spring-boot-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.3.0.RELEASE</version> </parent> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies>
|
主要的包结构:
2、订单类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
@AllArgsConstructor @NoArgsConstructor @Data public class Order implements Serializable {
private Long id;
private BigDecimal price;
private Integer status;
private Date createTime; }
|
3、创建订单状态处理超类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package org.example.bll;
import org.example.pojo.Order;
public interface OrderState {
void handle(Order newOrder,Order oldOrder); }
|
4、各个状态处理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package org.example.bll;
import org.example.pojo.Order;
public class OrderStateCommon implements OrderState { @Override public void handle(Order newOrder, Order oldOrder) {
}
public void buildOrderLog(Order order) { System.out.println("保存日志订单状态: " + order.getStatus()); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import org.example.pojo.Order; import org.springframework.stereotype.Component;
import java.util.Objects;
@Component(OrderStateFactory.ORDER_STATUS + 1) public class OrderStateFor1 extends OrderStateCommon { @Override public void handle(Order newOrder, Order oldOrder) { if (Objects.isNull(oldOrder)){ System.out.println("不做操作"); } System.out.println("订单状态:1 处理逻辑==>"); super.buildOrderLog(newOrder); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package org.example.bll;
import org.example.pojo.Order; import org.springframework.stereotype.Component;
@Component(OrderStateFactory.ORDER_STATUS + 2) public class OrderStateFor2 extends OrderStateCommon{ @Override public void handle(Order newOrder, Order oldOrder) { System.out.println("订单状态:2 处理逻辑==>"); super.buildOrderLog(newOrder); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package org.example.bll;
import org.example.pojo.Order; import org.springframework.stereotype.Component;
@Component(OrderStateFactory.ORDER_STATUS + 3) public class OrderStateFor3 extends OrderStateCommon{ @Override public void handle(Order newOrder, Order oldOrder) { System.out.println("订单状态:3 处理逻辑==>"); super.buildOrderLog(newOrder); } }
|
5、工厂类
1 2 3 4 5 6 7 8 9 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 36 37 38
| package org.example.bll;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;
import java.util.Map; import java.util.concurrent.ConcurrentHashMap;
@Component public class OrderStateFactory {
public static final String ORDER_STATUS = "orderStatus";
@Autowired Map<String, OrderState> states = new ConcurrentHashMap<>(4);
public OrderState getState(Integer status) { if (states.containsKey(ORDER_STATUS + status)) { return states.get(ORDER_STATUS + status); } throw new RuntimeException("未找到执行状态的类"); } }
|
6、主要的入口类代码
1 2 3 4 5 6 7 8 9 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 36 37
| package org.example.service.impl;
import org.example.bll.OrderState; import org.example.bll.OrderStateFactory; import org.example.pojo.Order; import org.example.service.IOrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import java.util.Objects;
@Service public class OrderServiceImpl implements IOrderService { @Autowired private OrderStateFactory factory; @Override public void saveOrUpdateOrder(Order order) { Order oldOrder = this.getById(order.getId()); if (Objects.isNull(oldOrder)) { this.save(order); if (Objects.nonNull(order.getStatus())) { factory.getState(order.getStatus()).handle(order,null); } return; } OrderState orderState = Objects.isNull(order.getStatus()) ? factory.getState(oldOrder.getStatus()) : factory.getState(order.getStatus()); orderState.handle(order,oldOrder);
}
|
至此,所有的代码都已实现,下面开始演示‘
7、测试类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package org.example;
import org.example.pojo.Order; import org.example.service.IOrderService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal; import java.util.Date;
@RunWith(SpringRunner.class) @SpringBootTest public class OrderTest { @Autowired private IOrderService orderService;
@Test public void testOrder1() { Order order = new Order(1L, BigDecimal.ONE, 2, new Date()); orderService.saveOrUpdateOrder(order); } }
|
运行结果: