在java開發規範當中,從前端接收需要進行插入操作的數據是用InsertVO,接收用於更新操作的數據則是UpdateVO,這兩個VO一般來說都是繼承了同一個實體類,各自又因爲不同的需求有着不同的屬性字段。
我遇到的情況是這樣的
@Data
public class CycleCountOrderInsertVO extends CycleCountOrder {
@NotNull(message = "{msg.cycle.count.order.status-null}")
private CycleCountStatusEnum cycleCountStatus;
@NotNull(message = "{msg.cycle.count.order.skuList-null}")
private List<CycleCountOrderSkuInsertVO> skuList;
}
@Data
public class CycleCountOrderUpdateVO extends CycleCountOrder{
@NotNull(message = "{msg.cycle.count.order.id-null}")
private Long id;
@NotNull(message = "{msg.cycle.count.order.status-null}")
private CycleCountStatusEnum cycleCountStatus;
@NotNull(message = "{msg.cycle.count.order.skuList-null}")
private List<CycleCountOrderSkuUpdateVO> skuList;
}
是不是很容易看出,上面這兩個的結構很相似呢?
這是因爲程序中需要對這兩個VO中的skuList中的sku進行計算操作,高相似性的字段構成能夠提高方法的複用性,比如我把UpdateVO輸入到方法中後,可以使用CycleCountOrderSku這個列表中VO的共同父類來遍歷列表。這樣我就不用專門爲插入數據寫一個計算方法再專門給更新數據寫一個計算方法了。
當然,這只是我這麼想而已,實際上你會發現這甚至不是不順利的問題……
這個思路最大的阻礙就是List<CycleCountOrderSkuUpdateVO>和List<CycleCountOrderSku>並沒有父子關係,那麼函數的輸入方式就出現了問題,就算你構建一個InsertVO和UpdateVO的共同父類,父類的skuList的類型應當是什麼呢?
是List<CycleCountOrderSku>嗎?肯定不能。
當然我們可以選擇使用BeanUtils進行類型轉換,但要是要對一個列表的數據都進行類型轉換,這也太麻瓜了。
其實java對這種具有相似結構的近親對象是有應對方式的,泛型就可以很好的解決這個問題。
下面是我構建的一個抽象類,將sku的InsertVO和UpdateVO抽象成了泛型<E extends CycleCountOrderSku>
@Data
public class CycleCountOrderAbstractVO<E extends CycleCountOrderSku> extends CycleCountOrder {
private CycleCountStatusEnum cycleCountStatus;
private List<E> skuList;
}
配套的,在方法裏也需要使用到泛型
private <E extends CycleCountOrderSku> void calculateUnitCostAndValueDifference(CycleCountOrderAbstractVO<E> cycleCountOrderAbstractVO) {
//省略的計算細節……
for (E sku : cycleCountOrderAbstractVO.getSkuList()) {
sku.setValueDifference(sku.getUnitCost().multiply(
new BigDecimal(sku.getCycleCount() - sku.getStock())
));
}
//省略的計算細節……
}
活用泛型,可以有效提高代碼的複用率,隨之而來的,則是開發測試與維護的安全與便捷。