实体也可以做加减?

09-06-11 willem
业务:一笔订单,有种商品,且该笔订单已发货。如果顾客不满意,可退货。而且业务上允许对一笔订单进行多次退货。假设该订单有十种商品,每种数量为“1”,那么就可以退十次。

数据库设计:销售订单和退货订单存一起,退货订单有一字段指向原订单。

如果顾客要退货,原订单的行项目要跟它已经产生的退货单的行项目进行"减"操作。才能知道此时还有哪些商品可退。

“订单”是个实体,不是“值对象”。但好像有这种要求:

可退货行项目 = 原单行项目 - 所以已退货行项目

[该贴被admin于2009-07-21 16:21修改过]

willem
2009-06-11 11:25
模型应该是:

可退货订单 = 原单 - 退货单

这三个都是同一个实体

freebox
2009-06-11 15:08
个人认为好像是指对特定的订单项的退货作业。

class Order{

Set<Item> items;

}

class Item{

boolean back;

}

这样应该能够计数并列举出哪些可以退货哪些不能了,如果需求还有要求生成退货单的,也可以由这些item重组生成。

[该贴被freebox于2009-06-11 15:09修改过]

willem
2009-06-11 23:08
boolean back;

不能解决问题,如果该行项目的数量是10,我只要退2两个,

back就成了尴尬的属性。

willem
2009-06-11 23:10
我提到过,一笔订单的退货单是有记录的,退货单跟其它订单都在一张,结构一样的。

freebox
2009-06-12 08:45
我没有区分是订货单还是退货单,这些都得到保存,最后发货的时候是按订货单和退货单的统计计算的。

像订货单order1{item1{count:10,back:false}}

退货单order2{item1{count:2,back:true}}

根据这些单就可以统计计算。

或者把退货单的item count规定为负值,放弃back属性,最后也能统计。

对item的操作就像很多金融系统一样,不能直接加减,只能记录每一笔资料,最后统计,也可以在每一笔记录之后生成瞬时状态,下次直接以这个状态为基础进行操作,操作后的新状态变成新的瞬时状态,但在最后发货前仍要重新统计以确保瞬时状态是有效态。

下面用正负值标记的item,简要写个方法。

class Order{
  Long id;
  String number;
  <Set>Item items;
  public Order add(Order order){
    if(!order.number.equals(this.number)){
       throw new OrderException("not same order operation");
    }
    Order momentOrder=new Order(new HashSet<Item>());
    for(Item item:this.items){
        for(Item orderItem:order.items){
            if(item.product.equals(orderItem.product)){
              if(item.count+orderItem.count<0){throw new OrderException("count error");}
              momentOrder.items.add(new Item(item.product,item.count+orderItem.count));
            }
        }
    }
    return momentOrder;
  }
}
class Item{
  int count;
  //equals hashcode
}
<p>

banq
2009-06-12 08:46
可退加减是一个业务计算,没有必须做一个可退货订单,可退货订单是结果,结果不能做为实体,因为你是数据库思维,在数据表里,输入和输出都并行躺在那里,所以,你从数据表反推到对象实体,以为有一个可退货订单是对象实体。

你可以做一个Specification,用来进行可退加减规则计算就可以。

ACoder
2009-06-12 14:00
对,退货是一种操作,而不是一种属性,对于商品的属性没有改变,而只是决定了某个承载该对象的容器数量的变化,以及产生相关的后果(生成退货单)。

willem
2009-06-13 10:32
确实,退货是一个业务操作,专门有个获取可退货的订单明细的方法,该方法逻辑:把所有该笔订单的退货单汇总,然后然后循环原订单的明细跟汇总后的明显进行比较。得出可退货的订单明细。

但我觉得这样做不是很好。而且如果明细里有特殊的东西,处理就复杂了。比如说运费也是一个订单里的明细,该明细的数量永远都是1.

运费也是可以部分退的,虽然代码已经实现,感觉不是很优雅,也不好扩展。

freebox
2009-06-13 14:42
用spec的话就声明一个退回接口,退订单项和退运费和退其它分别实现,需要考查订单项、运费、其它项之间有没有业务上的必然联系,是不是退一个其它的也必须跟着改变等。不了解更详细的业务,先分析这点。

ACoder
2009-06-15 11:02
首先你要分析你的订单里面有什么,货物能够等同于运费么??运费是否是根据货物的多少计算出来的?他们是订单项,具备显示的方法,但是对于一个订单,应当包含题头,户名,时间、明细、合计等一些列的订单项,但是这些订单项是不一样的。难道能用一种方法搞定么??

猜你喜欢