当前位置: 首页 > news >正文

网站开发 网页制作个人网站建设

网站开发 网页制作,个人网站建设,小程序制作价格,招商门户网站建设方案状态模式 一. 说明 状态模式通常描述一个类不同行为的多个状态变更,对象的行为依赖它的状态,它是一种行为型模式。 状态模式可以用来消除代码中大量的if-else结构,它明确对象是有状态的、对象的不同状态对应的行为不一样、行为之间是可以切…

状态模式

一. 说明

状态模式通常描述一个类不同行为的多个状态变更,对象的行为依赖它的状态,它是一种行为型模式。
状态模式可以用来消除代码中大量的if-else结构,它明确对象是有状态的、对象的不同状态对应的行为不一样、行为之间是可以切换的。简单来讲,就是对象的状态只允许在某个或某些行为下发生改变,否则不允许该行为操作对象状态。

我们用生活中购物订单的例子来说明状态模式,图示如下:
在这里插入图片描述
从图示中可以看出:

  • 未支付的订单只能被用户做支付或者取消操作
  • 已支付的订单只能被用户发货前催单 (按催单对象不同分为两种催单形式)
  • 已发货的订单只能被用户发货后催单
  • 已签收的订单只能被用户评价或删除
  • 已删除的订单用户已经看不到了,无法做任何操作

总的来说就是用户订单的某个状态只能被用户的某个对应行为所改变,而其他行为是无法操作的。

二.应用场景

  1. 线上购物时的订单状态随着不同行为而变化
  2. 营销活动的上线审批流程,活动也是有状态变化的
  3. 游戏时控制的角色在不同环境下有不同的状态(buff加成或debuff时角色属性有不同的变化)

三.代码示例

以购物下单为例,我们在OrderService里实现几个行为:支付、取消订单、催单、判断是否可评价、删除订单这几个行为,按一般的写法是这样的:

先创建OrderService接口,提供几个方法

public interface OrderService {/*** 订单支付*/boolean pay(OrderDTO orderDTO);/*** 订单取消*/boolean cancel(OrderDTO orderDTO);/*** 催单*/boolean reminder(OrderDTO orderDTO);/*** 订单评价校验*/boolean isEvaluable(OrderDTO orderDTO);/*** 删除订单*/boolean delete(OrderDTO orderDTO);
}

实现Service接口,每个行为都需要判断在特定状态下才能操作

public class OrderServiceImpl implements OrderService {@Overridepublic boolean pay(OrderDTO orderDTO) {if (orderDTO.getState() == StateEnum.UNPAID) {System.out.println("pay-订单支付流程");orderDTO.setState(StateEnum.PAID);System.out.println("pay-订单支付成功");return true;}System.out.println("pay-该订单无法支付,当前状态为:" + orderDTO.getState().getName());return false;}@Overridepublic boolean cancel(OrderDTO orderDTO) {if (orderDTO.getState() == StateEnum.UNPAID) {System.out.println("cancel-订单取消流程");orderDTO.setState(StateEnum.CANCEL);System.out.println("cancel-订单取消成功");return true;}System.out.println("cancel-该订单无法取消,当前状态为:" + orderDTO.getState().getName());return false;}@Overridepublic boolean reminder(OrderDTO orderDTO) {if (orderDTO.getState() == StateEnum.PAID) {System.out.println("reminder-订单催单成功,催单对象为卖家");return true;}if (orderDTO.getState() == StateEnum.DELIVERED) {System.out.println("reminder-订单催单成功,催单对象为物流");return true;}System.out.println("reminder-该订单无法催单,当前状态为:" + orderDTO.getState().getName());return false;}@Overridepublic boolean isEvaluable(OrderDTO orderDTO) {if (orderDTO.getState() == StateEnum.SIGNED) {System.out.println("evaluable-订单可以评价");return true;}System.out.println("evaluable-该订单无法评价,当前状态为:" + orderDTO.getState().getName());return false;}@Overridepublic boolean delete(OrderDTO orderDTO) {if (orderDTO.getState() == StateEnum.SIGNED) {System.out.println("delete-订单删除流程");orderDTO.setState(StateEnum.DELETED);System.out.println("delete-订单删除成功");return true;}System.out.println("delete-订单无法删除,当前状态为:" + orderDTO.getState().getName());return false;}
}

编写测试代码

public static void main(String[] args) {OrderDTO orderDTO = new OrderDTO();orderDTO.setOrderId("202400001");orderDTO.setState(StateEnum.UNPAID);OrderService service = new OrderServiceImpl();service.pay(orderDTO);service.pay(orderDTO);service.cancel(orderDTO);service.reminder(orderDTO);orderDTO.setState(StateEnum.DELIVERED);service.reminder(orderDTO);orderDTO.setState(StateEnum.SIGNED);service.isEvaluable(orderDTO);service.delete(orderDTO);}

在这里插入图片描述

如上图代码所示,这些代码的特点是,OrderService下的每一方法(即行为),都需要考虑订单的各个状态,业务逻辑相对来说复杂一些,如果要增加一个新的订单状态,每个方法都要按需调整,扩展性不高,不符合开闭原则。

我们在SpringBoot环境中使用状态模式重构以上的订单流程:

首先需要引入另一组service,用来表示订单状态的一组业务,命名为OrderStateService,提供与OrderService一致的行为方法

public interface IOrderStateService {StateEnum getState();/*** 订单支付*/boolean pay(OrderDTO orderDTO);/*** 订单取消*/boolean cancel(OrderDTO orderDTO);/*** 催单*/boolean reminder(OrderDTO orderDTO);/*** 订单评价校验*/boolean isEvaluable(OrderDTO orderDTO);/*** 删除订单*/boolean delete(OrderDTO orderDTO);
}

再编写抽象业务,实现接口的方法,提供默认的实现,默认实现都是该订单状态不支持该行为操作,我们把真正的行为实现落地到具体的实现类上。

@Slf4j
public abstract class AbstractOrderStateService implements IOrderStateService {@Overridepublic boolean pay(OrderDTO orderDTO) {log.info("pay-该订单无法支付,当前状态为:{}", orderDTO.getState().getName());return false;}@Overridepublic boolean cancel(OrderDTO orderDTO) {log.info("cancel-该订单无法取消,当前状态为:{}", orderDTO.getState().getName());return false;}@Overridepublic boolean reminder(OrderDTO orderDTO) {log.info("reminder-该订单无法催单,当前状态为:{}", orderDTO.getState().getName());return false;}@Overridepublic boolean isEvaluable(OrderDTO orderDTO) {log.info("evaluable-该订单无法评价,当前状态为:{}", orderDTO.getState().getName());return false;}@Overridepublic boolean delete(OrderDTO orderDTO) {log.info("delete-该订单无法删除,当前状态为:{}", orderDTO.getState().getName());return false;}
}

再重写每个状态对应允许的行为操作,一旦重写即表示该状态允许该行为操作

//未支付状态重写支付、取消、删除方法
@Slf4j
@Service
public class UnpaidOrderStateService extends AbstractOrderStateService {@Overridepublic StateEnum getState() {return StateEnum.UNPAID;}@Overridepublic boolean pay(OrderDTO orderDTO) {log.info("pay-订单支付成功,当前订单状态:{}", orderDTO.getState().getName());orderDTO.setState(StateEnum.PAID);return true;}@Overridepublic boolean cancel(OrderDTO orderDTO) {log.info("cancel-订单取消成功,当前订单状态:{}", orderDTO.getState().getName());orderDTO.setState(StateEnum.CANCEL);return true;}@Overridepublic boolean delete(OrderDTO orderDTO) {log.info("delete-订单取消成功,当前订单状态:{}", orderDTO.getState().getName());orderDTO.setState(StateEnum.DELETED);return true;}
}
//已支付状态重写催单方法
@Slf4j
@Service
public class PaidOrderStateService extends AbstractOrderStateService {@Overridepublic StateEnum getState() {return StateEnum.PAID;}@Overridepublic boolean reminder(OrderDTO orderDTO) {log.info("发货前催单成功, 催单对象为卖家,当前订单状态:{}", orderDTO.getState().getName());return true;}
}
//已发货状态重写催单方法
@Slf4j
@Service
public class DeliveredOrderStateService extends AbstractOrderStateService {@Overridepublic StateEnum getState() {return StateEnum.DELIVERED;}@Overridepublic boolean reminder(OrderDTO orderDTO) {log.info("发货后催单成功, 催单对象为物流,当前订单状态:{}", orderDTO.getState().getName());return true;}
}
//已签收状态重写判断评价和删除方法
@Slf4j
@Service
public class SignedOrderStateService extends AbstractOrderStateService {@Overridepublic StateEnum getState() {return StateEnum.SIGNED;}@Overridepublic boolean isEvaluable(OrderDTO orderDTO) {log.info("订单允许评价,当前订单状态:{}", orderDTO.getState().getName());return true;}@Overridepublic boolean delete(OrderDTO orderDTO) {log.info("订单删除成功,当前订单状态:{}", orderDTO.getState().getName());orderDTO.setState(StateEnum.DELETED);return true;}
}
//已删除状态不做任何操作
@Service
public class DeletedOrderStateService extends AbstractOrderStateService {@Overridepublic StateEnum getState() {return StateEnum.DELETED;}
}
//已取消状态不做任何操作
@Service
public class CancelOrderStateService extends AbstractOrderStateService {@Overridepublic StateEnum getState() {return StateEnum.CANCEL;}
}

编写获取具体StateService的工厂类

@Component
public class OrderStateFactory {private final Map<StateEnum, IOrderStateService> stateMap = new HashMap<>();@Resourceprivate Set<IOrderStateService> orderStateServiceSet;@PostConstructpublic void init() {orderStateServiceSet.forEach(service -> {stateMap.put(service.getState(), service);});}public IOrderStateService getOrderStateService(StateEnum state) {return stateMap.get(state);}}

改造OrderService的实现类

@Service
public class OrderServiceImpl implements OrderService {@Resourceprivate OrderStateFactory orderStateFactory;@Overridepublic boolean pay(OrderDTO orderDTO) {return orderStateFactory.getOrderStateService(orderDTO.getState()).pay(orderDTO);}@Overridepublic boolean cancel(OrderDTO orderDTO) {return orderStateFactory.getOrderStateService(orderDTO.getState()).cancel(orderDTO);}@Overridepublic boolean reminder(OrderDTO orderDTO) {return orderStateFactory.getOrderStateService(orderDTO.getState()).reminder(orderDTO);}@Overridepublic boolean isEvaluable(OrderDTO orderDTO) {return orderStateFactory.getOrderStateService(orderDTO.getState()).isEvaluable(orderDTO);}@Overridepublic boolean delete(OrderDTO orderDTO) {return orderStateFactory.getOrderStateService(orderDTO.getState()).delete(orderDTO);}
}

编写测试代码

public static void test(){OrderServiceImpl service = (OrderServiceImpl) applicationContext.getBean("orderServiceImpl");OrderDTO orderDTO = new OrderDTO();orderDTO.setOrderId("202400001");orderDTO.setState(StateEnum.UNPAID);service.pay(orderDTO);service.pay(orderDTO);service.cancel(orderDTO);service.reminder(orderDTO);orderDTO.setState(StateEnum.DELIVERED);service.reminder(orderDTO);orderDTO.setState(StateEnum.SIGNED);service.isEvaluable(orderDTO);service.delete(orderDTO);}

在这里插入图片描述

可以看到,重构后实现了相同的业务功能,并且完全干掉了if-else的判断代码。后续新增某个订单状态,我们只需要扩展StateService的具体状态实现即可。虽然整个模块的类增加了,略显复杂,但我们牺牲复杂性去换取高可维护性和扩展性是相当值得的。

四. 总结

在状态模式中,我们把每一种状态都独立成一个类进行处理,这满足了单一职责和开闭原则。状态模式强调的是行为和状态的对应,只有在特定的业务场景下使用它,在通常三层架构的web开发中,对象的状态和对象行为一般都是分离的,所以在开发中我们使用地并不多。

状态模式和状态机也是有关系的,状态机类似一种开发引擎便于我们在开发中使用,它同样采用的是状态模式的思想实现的。

http://www.hrbkazy.com/news/55811.html

相关文章:

  • 免费asp网站程序下载开鲁网站seo不用下载
  • 网站建设电话销售开场白怎么制作网站
  • 做高端品牌网站企业seo自助建站系统
  • 企业建网站群制作网站用什么软件
  • 可以查企业备案的网站百度推广一个点击多少钱
  • 深圳制作网站制作公司如何引流被动加好友微信
  • 如何在电商上购物网站2022最新版百度
  • 开发网站的财务分析apple私人免费网站怎么下载
  • 兖州网站建设哪家好页面seo优化
  • 怎么用asp.net做网站如何做网站的教程
  • 网络活动策划方案网站优化公司哪家好
  • 网站设计制作案例在百度上打广告找谁推广产品
  • 网站建设的分类应用市场
  • 商业网站的特点微信怎么做推广
  • 威远移动网站建设松松软文
  • 12306 网站谁做的武汉做网络推广的公司
  • 软件开发 网站建设今天最火的新闻头条
  • 刚察县公司网站建设吉林seo推广
  • 礼泉住房和城乡建设局网站google开户
  • 网站设计所用到的技术优化网址
  • 网站友情链接怎么弄互联网广告营销
  • 学asp.net 做网站 书籍长沙seo服务哪个公司好
  • 骨骼型的网站免费b站推广网站破解版
  • 企业如何在网站做认证郑州做网站推广
  • 手机app软件开发用什么语言天天seo百度点击器
  • wordpress备份数据库结构伟哥seo博客
  • 乐山住房和规划建设局门户网站百度推广价格表
  • 网站备案背景布佛山网站建设工作
  • 重庆网站建设培训网络安全有名的培训学校
  • 厦门做网站公司郑州关键词排名顾问