标签:包含 beanutils 工具 对话 获取 bean 快捷 种类 c中
本篇是我对Web开发规范中关于三层架构设计规范的一些浅见。虽然三层架构是比较普通,也比较简单的架构设计模式。但是随着业务的增长,涉及到的对象越来越多,处理的逻辑越来越复杂。这其中难免会出现设计不当,从而导致业务报错或逻辑代码混乱等问题的出现。下面我就来简单的谈一谈我是如何设计的?(注:本篇的见解是在基于当前比较流行的MVC设计模式,不知道什么是MVC设计模式的小伙伴,请自行查找相关资料。)
在三层的架构设计中通常会采用如下设计方案对逻辑进行划分:
在MVC设计模式中使用Controller代表,它的主要作用为:
在编写业务的时候有几个技巧:
1)对于所有更新操作,都把BO对象当成参数来接收,把更新后的对象当返回值
public OrderBO cancel(OrderBO orderBO) { return orderBO; } /** 取消订单. */
public OrderBO finish(OrderBO orderBO) { return orderBO; } /** 完成订单. */
public OrderBO paid(OrderBO orderBO) { return orderBO; } /** 支付订单. */
2)对于查询而言,如果对象不存在,直接返回null或抛出异常均可。当返回为null时,上层调用需要进行判null处理
3) 如果是更新类操作,被操作的对象不存在时,这个时候一定要抛出异常
4)在需要抛出异常的地方使用日志详细的记录
5)如果在Service的方法中涉及到多个更新操作,需要在Service中开启事务。即使该方法的上层调用Service开启了事务,该方法也应该开启。以创建订单为例
@Transactional
public OrderBO save(OrderBO orderBO) {
// .....
OrderMaster orderMaster = new OrderMaster();
BeanUtils.copyProperties(orderBO, orderMaster);
// 存储订单
orderMasterRepository.save(orderMaster);
productInfoService.decrStock(
orderBO.getOrderDetailList().stream()
.map(e-> new StockBO(e.getProductId(),e.getProductQuantity()))
.collect(Collectors.toList())
);
return orderBO;
}
@Transactional //即使上层调用有这个标记,这里最好也加,因为可能会单独调用
public void decrStock(List<StockBO> stockBOList) {
stockBOList.stream().forEach(e -> {
ProductInfo productInfo = this.findOne(e.getProductId());
if (productInfo == null) {
throw new WxbpException(ErrorCodeEnum.PRODUCT_NOT_EXIST);
}
Integer remainStock = productInfo.getProductStock() - e.getProductStock();
if (remainStock < 0) {
throw new WxbpException(ErrorCodeEnum.PRODUCT_STOCK_ERROR);
}
productInfo.setProductStock(remainStock);
repository.save(productInfo);
});
}
除基本的架构外,还会存在很多其他的实体对象,这些对象包括:
对于上述三层架构中涉及的业务和对象,我们可以简化这样理解,假设有这样一个情景。
BOSS把总监(Controller)叫到办公室 ,说:公司经营的状况如何了,给我出个总体报告我看看。总监收到指令后把A部门的经理(Service)叫到了办公室,并说:我需要近一年A部门的总结报告。A部门经理需要收到请求后,开始使用报表工具做事(Repository),当遇到了自己处理不了的地方又会叫其他有关联的经理帮助处理(调用其他的Service),最后完成了整件事。把报告交给了总监,总监看过之后发现没什么问题,又把B部门的经理叫到了办公室,并说了需求(有时候需要给B看A部门的报告的部分或所有结果), B部门的经理收到请求后,也是同A一样的处理办法,把报告交给了总监。此时总监这里已经有了BOSS要的所有数据,然后进行汇总,交给BOSS。而在这个过程中,为保密和方便各方之间的沟通,BOSS和总监之间的对话可以理解成 PO -> BO 的过程,总监和经理的对话可以理解成BO->POJO的过程,当然有些经理对业务理解比较透彻就不需要转换了(直接使用BO,此时BO=POJO)。而这个对话过程反过来就是,进行逐层汇报的时候,应该言简意赅,一语中的,至于你怎么做的,就不要向上层反映了。最后达到BOSS那里只要看到满意的结果就好。
Service分层设计是什么意思呢? 让我们来看一个例子
public interface OrderService{
/** 查询一个订单. */
OrderBO findOne(String orderId);
/** 取消订单. */
void cancel(OrderBO orderBO);
}
在上述的代码中OrderService包含根据orderId获取订单这个操作。那么对于买家而言调用此方法是需要对买家进行安全性验证的,非该用户的订单则不能返回给调用方。为了代码的整洁性我们衍生出来一个BuyerService,这个BuyerService主要处理和买家相关的业务,对买家进行验证后在进行调用相应的Service。
public class BuyerService{
public OrderBO checkOrderOwner(String userId,String orderId){
OrderBO orderBO = orderService.findOne(orderId);
if(!orderBO.getUserID().equals(userId)) { //抛出异常; }
return orderBO;
}
/** 查询用户的订单列表. */
public OrderBO findOrderList(String userId,String orderId){
OrderBo orderBO =checkOrderOwner(userId,orderId);
return orderBO
}
}
这个分层理解起来也和三层架构类似,你当然可以在Controller中直接使用 OrderService 进行操作,就像你也可以直接使用Repository操作一样,只不过是比较麻烦而已。更好的设计有助于提高代码的整洁性,可读性和可维护性。
如上的设计中涉及复杂业务的同时又衍生出了很多不同种类的对象,在开发的过程中会难免会造成代码的可读性,安全性和可维护性降低,下面我们看一些可以提升整体的开发效率的小妙招。
{ "code":"0","msg":"操作成功","data":"需要返回给用户的数据"}
或
{ "code":"错误的状态码","msg":"错误的信息" }
标签:包含 beanutils 工具 对话 获取 bean 快捷 种类 c中
原文地址:https://www.cnblogs.com/u-vitamin/p/11742370.html