状态模式
什么是状态模式:
状态模式是指允许一个对象在内部状态改变的时候改变他的行为,并解决产生的多重if判断问题。
状态模式应用场景:
- 一个对象的行为取决于他的状态,而且他必须在运行时刻根据状态改变他的行为。
- 多重if判断问题:不同的状态不同的行为,将不同的行为进行封装。
代码逻辑:
传统多重if判断不同的状态不同的行为
public String orderState(String state) {
if (state.equals("0")) {
return "已经发货";
}
if (state.equals("1")) {
return "正在运送中...调用第三方快递接口 展示 运送信息";
}
if (state.equals("2")) {
return "正在派送中... 返回派送人员信息";
}
if (state.equals("3")) {
return "已经签收,提示给用户快递员评价";
}
if (state.equals("4")) {
return "拒绝签收, 重新开始申请退单";
}
if (state.equals("5")) {
return "订单交易失败,调用短信接口提示 ";
}
return "未找到对应的状态";
}
状态模式重组代码
- 导入pom文件依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<!-- sprinboot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
- 创建application.yml文件
###服务启动端口号
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3307/jk?useUnicode=true&characterEncoding=UTF-8
username: root
password: ****
driver-class-name: com.mysql.jdbc.Driver
####打印MyBatias日志
logging:
level:
### 开发环境使用DEBUG 生产环境info或者error
com.mayikt.member.mapper: DEBUG
- 定义共同的接口算法
public interface OrderStateService {
public void orderState();
}
- 创建共同接口的具体实现(有多少个状态就新增多少个实现类)
@Slf4j
@Component
public class ShippedAlreadyOrderState implements OrderStateService {
@Override
public void orderState() {
log.info(">>>切换为已经发货状态..");
}
}
@Slf4j
@Component
public class InTransitOrderState implements OrderStateService {
@Override
public void orderState() {
log.info(">>>切换为正在运送状态...");
}
}
@Slf4j
@Component
public class AlreadySignedOrderState implements OrderStateService {
public void orderState() {
log.info(">>>切换为已经签收状态..");
}
}
- 定义切换状态的共同入口
public class StateContext {
private OrderStateService orderStateService;
public StateContext(OrderStateService orderStateService){
this.orderStateService = orderStateService;
}
public void getNextState(){
orderStateService.orderState();
}
}
- 创建SpringUtils工具类
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
- 定义接口controller
@RestController
public class OrderController {
@RequestMapping("/order")
public String order(String stateBeanId) {
//1.使用Spring上下文获取bean中对象
OrderStateService orderState = SpringUtils.getBean(stateBeanId, OrderStateService.class);
// 2.使用上下文切换到不同的状态
StateContext stateContext = new StateContext(orderState);
stateContext.getNextState();
// 如果写多重if判断的话 整个代码流程 耗时比较长 直接Spring中精准定位到策略或者是状态的话 Map get方法的时候底层是数组
return "success";
}
}