状态模式:封装数据的状态流转逻辑
状态模式里,非常重要的一点就是将状态之间流转的逻辑,封装在Context类里面。本来可能需要调用方自己维护复杂的状态流转逻辑,流转到不同的状态之后,执行状态对应的代码逻辑。
需求背景:
上线一个商品的流程包括:
编辑,审核,上架三个过程。处于每个流程时,状态属性
是不一样的
定义一个商品状态接口GoodsState ,来封装聚合状态的流转与判断:
对于商品所处于四种状态分别给四种实现:
待审核 WaitForApproveGoodsState、
审核未通过 ApproveRejectGoodsState、
审核通过(待上架)WaitForPutOnShelvesGoodsState、
已上架 PuttedOnShelvesGoodsState
GoodsState
/**
* 商品状态接口
* @author
*
*/
public interface GoodsState {
/**
* 执行商品流转到当前状态来的业务逻辑
* @param goods 商品
* @throws Exception
*/
void doTransition(GoodsDTO goods) throws Exception;
/**
* 判断当前商品能否执行编辑操作
* @param goods 商品
* @return 能否执行编辑操作
*/
Boolean canEdit(GoodsDTO goods) throws Exception;
/**
* 判断能否执行审核操作
* @param goods 商品
* @return
* @throws Exception
*/
Boolean canApprove(GoodsDTO goods) throws Exception;
/**
* 判断能否执行上架操作
* @param goods 商品
* @return 能否执行上架操作
* @throws Exception
*/
Boolean canPutOnShelves(GoodsDTO goods) throws Exception;
/**
* 判断能否执行下架操作
* @param goods 商品
* @return
* @throws Exception
*/
Boolean canPullOffShelves(GoodsDTO goods) throws Exception;
/**
* 能否执行删除操作
* @param goods 商品
* @return
* @throws Exception
*/
Boolean canRemove(GoodsDTO goods) throws Exception;
}
/**
* 已上架状态
* @author
*
*/
@Component
public class PuttedOnShelvesGoodsState implements GoodsState {
/**
* 日期辅助组件
*/
@Autowired
private DateProvider dateProvider;
/**
* 商品管理DAO组件
*/
@Autowired
private GoodsDAO goodsDAO;
/**
* 执行商品流转到当前状态来的业务逻辑
*
* @param goods 商品
* @throws Exception
*/
@Override
public void doTransition(GoodsDTO goods) throws Exception {
goods.setStatus(GoodsStatus.PUTTED_ON_SHELVES);
goods.setGmtModified(dateProvider.getCurrentTime());
goodsDAO.updateStatus(goods.clone(GoodsDO.class));
}
@Override
public Boolean canEdit(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canApprove(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canPutOnShelves(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canPullOffShelves(GoodsDTO goods) throws Exception {
return true;
}
@Override
public Boolean canRemove(GoodsDTO goods) throws Exception {
return false;
}
}
/**
* 待审核商品状态
* @author zhonghuashishan
*
*/
@Component
public class WaitForApproveGoodsState implements GoodsState {
/**
* 商品管理DAO组件
*/
@Autowired
private GoodsDAO goodsDAO;
/**
* 日期辅助组件
*/
@Autowired
private DateProvider dateProvider;
@Override
public void doTransition(GoodsDTO goods) throws Exception {
goods.setStatus(GoodsStatus.WAIT_FOR_APPROVE);
goods.setGmtModified(dateProvider.getCurrentTime());
goodsDAO.updateStatus(goods.clone(GoodsDO.class));
}
@Override
public Boolean canEdit(GoodsDTO goods) throws Exception {
return true;
}
@Override
public Boolean canApprove(GoodsDTO goods) throws Exception {
return true;
}
@Override
public Boolean canPutOnShelves(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canPullOffShelves(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canRemove(GoodsDTO goods) throws Exception {
return true;
}
}
/**
* 待上架状态
* @author zhonghuashishan
*
*/
@Component
public class WaitForPutOnShelvesGoodsState implements GoodsState {
/**
* 日期辅助组件
*/
@Autowired
private DateProvider dateProvider;
/**
* 商品管理DAO组件
*/
@Autowired
private GoodsDAO goodsDAO;
@Override
public void doTransition(GoodsDTO goods) throws Exception {
goods.setStatus(GoodsStatus.WAIT_FOR_PUT_ON_SHELVES);
goods.setGmtModified(dateProvider.getCurrentTime());
goodsDAO.updateStatus(goods.clone(GoodsDO.class));
}
@Override
public Boolean canEdit(GoodsDTO goods) throws Exception {
return true;
}
@Override
public Boolean canApprove(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canPutOnShelves(GoodsDTO goods) throws Exception {
return true;
}
@Override
public Boolean canPullOffShelves(GoodsDTO goods) throws Exception {
return false;
}
@Override
public Boolean canRemove(GoodsDTO goods) throws Exception {
return true;
}
}
定义一个商品状态管理的接口:
/**
* 商品状态管理器接口
* @author
*
*/
public interface GoodsStateManager {
/**
* 创建一个商品
* @param goods
* @throws Exception
*/
void create(GoodsDTO goods) throws Exception;
/**
* 当前这个商品能否执行编辑操作
* @param goods 商品
* @return 能否执行编辑操作
* @throws Exception
*/
Boolean canEdit(GoodsDTO goods) throws Exception;
/**
* 执行编辑商品的操作
* @param goods 商品
* @throws Exception
*/
void edit(GoodsDTO goods) throws Exception;
/**
* 判断能否执行审核操作
* @param goods 商品
* @return
* @throws Exception
*/
Boolean canApprove(GoodsDTO goods) throws Exception;
/**
* 执行审核操作
* @param goods
* @param approveResult
* @throws Exception
*/
void approve(GoodsDTO goods, Integer approveResult) throws Exception;
/**
* 判断能否执行上架操作
* @param goods 商品
* @return 能否执行上架操作
* @throws Exception
*/
Boolean canPutOnShelves(GoodsDTO goods) throws Exception;
/**
* 执行上架操作
* @param goods
* @throws Exception
*/
void putOnShelves(GoodsDTO goods) throws Exception;
/**
* 判断能否执行下架操作
* @param goods 商品
* @return
* @throws Exception
*/
Boolean canPullOffShelves(GoodsDTO goods) throws Exception;
/**
* 执行下架操作
* @param goods 商品
* @throws Exception
*/
void pullOffShelves(GoodsDTO goods) throws Exception;
/**
* 能否执行删除操作
* @param goods 商品
* @return
* @throws Exception
*/
Boolean canRemove(GoodsDTO goods) throws Exception;
}
/**
* 商品状态管理器实现
* @author
*
*/
@Component
public class GoodsStateManagerImpl implements GoodsStateManager {
/**
* 待审核状态
*/
@Autowired
private WaitForApproveGoodsState waitForApproveGoodsState;
/**
* 待上架状态
*/
@Autowired
private WaitForPutOnShelvesGoodsState waitForPutOnShelvesGoodsState;
/**
* 审核未通过状态
*/
@Autowired
private ApproveRejectGoodsState approveRejectGoodsState;
/**
* 已上架状态
*/
@Autowired
private PuttedOnShelvesGoodsState puttedOnShelvesGoodsState;
/**
* 商品状态工厂
*/
@Autowired
private GoodsStateFactory goodsStateFactory;
/**
* 创建一个商品
* @param goods
* @throws Exception
*/
@Override
public void create(GoodsDTO goods) throws Exception {
waitForApproveGoodsState.doTransition(goods);
}
@Override
public Boolean canEdit(GoodsDTO goods) throws Exception {
GoodsState state = goodsStateFactory.get(goods);
return state.canEdit(goods);
}
@Override
public void edit(GoodsDTO goods) throws Exception {
waitForApproveGoodsState.doTransition(goods);
}
@Override
public Boolean canApprove(GoodsDTO goods) throws Exception {
GoodsState state = goodsStateFactory.get(goods);
return state.canApprove(goods);
}
@Override
public void approve(GoodsDTO goods, Integer approveResult) throws Exception {
if (ApproveResult.APPROVE_PASS.equals(approveResult)) {
waitForApproveGoodsState.doTransition(goods);
} else if (ApproveResult.APPROVE_REJECT.equals(approveResult)) {
approveRejectGoodsState.doTransition(goods);
}
}
@Override
public Boolean canPutOnShelves(GoodsDTO goods) throws Exception {
GoodsState state = goodsStateFactory.get(goods);
return state.canPutOnShelves(goods);
}
@Override
public void putOnShelves(GoodsDTO goods) throws Exception {
puttedOnShelvesGoodsState.doTransition(goods);
}
@Override
public Boolean canPullOffShelves(GoodsDTO goods) throws Exception {
GoodsState state = goodsStateFactory.get(goods);
return state.canPullOffShelves(goods);
}
@Override
public void pullOffShelves(GoodsDTO goods) throws Exception {
waitForApproveGoodsState.doTransition(goods);
}
@Override
public Boolean canRemove(GoodsDTO goods) throws Exception {
GoodsState state = goodsStateFactory.get(goods);
return state.canRemove(goods);
}
}
封装一个商品状态工厂、根据商品状态code获取相应的状态实现类,然后根据实现获取不同状态的可编辑状态。
/**
* 商品状态工厂
* @author
*
*/
@Component
public class GoodsStateFactory {
/**
* 待审核状态
*/
@Autowired
private WaitForApproveGoodsState waitForApproveGoodsState;
/**
* 待上架状态
*/
@Autowired
private WaitForPutOnShelvesGoodsState waitForPutOnShelvesGoodsState;
/**
* 审核未通过状态
*/
@Autowired
private ApproveRejectGoodsState approveRejectGoodsState;
/**
* 已上架状态
*/
@Autowired
private PuttedOnShelvesGoodsState puttedOnShelvesGoodsState;
/**
* 默认商品状态
*/
@Autowired
private DefaultGoodsState defaultGoodsState;
/**
* 获取商品对应的状态组件
* @param goods 商品
* @return 状态组件
* @throws Exception
*/
public GoodsState get(GoodsDTO goods) {
if(GoodsStatus.WAIT_FOR_APPROVE.equals(goods.getStatus())) {
return waitForApproveGoodsState;
} else if(GoodsStatus.WAIT_FOR_PUT_ON_SHELVES.equals(goods.getStatus())) {
return waitForPutOnShelvesGoodsState;
} else if(GoodsStatus.APPROVE_REJECT.equals(goods.getStatus())) {
return approveRejectGoodsState;
} else if(GoodsStatus.PUTTED_ON_SHELVES.equals(goods.getStatus())) {
return puttedOnShelvesGoodsState;
} else {
return defaultGoodsState;
}
}
}
最终使用,在最后商品编辑实现类种使用上述的状态模式:
/**
* 商品管理service组件
* @author
*
*/
@Service
@Transactional
public class GoodsServiceImpl implements GoodsService {
/**
* 商品管理DAO组件
*/
@Autowired
private GoodsDAO goodsDAO;
/**
* 商品状态管理器
*/
@Autowired
private GoodsStateManager goodsStateManager;
/**
* 商品图片管理DAO
*/
@Autowired
private GoodsPictureDAO goodsPictureDAO;
/**
* 商品详情管理DAO
*/
@Autowired
private GoodsDetailDAO goodsDetailDAO;
/**
* 商品详情图片管理DAO
*/
@Autowired
private GoodsDetailPictureDAO goodsDetailPictureDAO;
/**
* 商品属性值管理DAO
*/
@Autowired
private GoodsPropertyValueDAO goodsPropertyValueDAO;
/**
* 商品sku管理DAO
*/
@Autowired
private GoodsSkuDAO goodsSkuDAO;
/**
* 商品sku属性值管理DAO
*/
@Autowired
private GoodsSkuSalePropertyValueDAO goodsSkuSalePropertyValueDAO;
/**
* 分页查询商品
* @param query 查询条件
* @return 商品
*/
public List<GoodsDTO> listByPage(GoodsQuery query) throws Exception {
return ObjectUtils.convertList(goodsDAO.listByPage(query), GoodsDTO.class);
}
/**
* 根据id查询商品
* @param id 商品id
* @return 商品
*/
public GoodsDTO getById(Long id) throws Exception {
return goodsDAO.getById(id).clone(GoodsDTO.class);
}
/**
* 新增商品
* @param goods 商品
*/
public Long save(GoodsDTO goods) throws Exception {
Long goodsId = goodsDAO.save(goods.clone(GoodsDO.class));
goodsStateManager.create(goods);
return goodsId;
}
/**
* 更新商品
* @param goods 商品
*/
public Boolean update(GoodsDTO goods) throws Exception {
if(!goodsStateManager.canEdit(goods)) {
return false;
}
goodsDAO.update(goods.clone(GoodsDO.class));
goodsStateManager.edit(goods);
return true;
}
/**
* 审核商品
* @param goods 商品
* @return 处理结果
* @throws Exception
*/
public Boolean approve(GoodsDTO goods, Integer approveResult) throws Exception {
if(!goodsStateManager.canApprove(goods)) {
return false;
}
goodsStateManager.approve(goods, approveResult);
return true;
}
/**
* 执行上架操作
* @param goods
* @return
* @throws Exception
*/
public Boolean putOnShelves(GoodsDTO goods) throws Exception {
if(!goodsStateManager.canPutOnShelves(goods)) {
return false;
}
goodsStateManager.putOnShelves(goods);
return true;
}
/**
* 执行下架操作
* @param goods 商品
* @return
* @throws Exception
*/
public Boolean pullOffShelves(GoodsDTO goods) throws Exception {
if(!goodsStateManager.canPullOffShelves(goods)) {
return false;
}
goodsStateManager.pullOffShelves(goods);
return true;
}
/**
* 执行删除操作
* @param goodsId
* @return
* @throws Exception
*/
public Boolean remove(Long id) throws Exception {
GoodsDTO goods = goodsDAO.getById(id).clone(GoodsDTO.class);
if(!goodsStateManager.canRemove(goods)) {
return false;
}
goodsPictureDAO.removeByGoodsId(id);
GoodsDetailDO goodsDetail = goodsDetailDAO.getByGoodsId(id);
goodsDetailPictureDAO.removeByGoodsDetailId(goodsDetail.getId());
goodsDetailDAO.remove(goodsDetail.getId());
goodsPropertyValueDAO.removeByGoodsId(id);
List<GoodsSkuDO> goodsSkus = goodsSkuDAO.listByGoodsId(id);
for(GoodsSkuDO goodsSku : goodsSkus) {
goodsSkuSalePropertyValueDAO.removeByGoodsSkuId(goodsSku.getId());
}
goodsSkuDAO.removeByGoodsId(id);
return true;
}
}
- 本文链接: https://blog.zoozer.club/archives/-she-ji-mo-shi-gong-cheng-shi-jian--zhuang-tai-mo-shi---shen-he-liu-cheng-guan-li
- 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!