业务抽象——必要属性和可选属性一个例子

 今天在看系统源码时,遇到了一个可选属性的例子,比较有代表性。

业务描述如下:

一个仓库管理系统,管理若干仓库(warehouse),每个仓库和若干货主(owner)发生业务。货主在仓库中存放若干种货物(item),货物包括名称(name)、编号(id)等属性。

那么,怎么设计DB呢?

第一反映是应该有这几张张表:Warehouse,Owner,Item,Owner_Warehouse_Relationship,Owner_Warehouse_Item_Relationship,其中Item表包含(ItemId,ItemName,...),Owner_Warehouse_Relationship表包含(OwnerId,WarehouseId),记录哪些货主可以和那些仓库发生关系;Owner_Warehouse_Item_Relationship表包含(Owner_Warehouse_Relationship_Id,ItemId),记录每对发生关系的货主和仓库间可以处理哪些货物。

然后去看数据库实现,和我的想法完全不同。数据库现有以下几张表:Warehouse,Owner,Item,Owner_warehouse_Relationship。相比之下,没有单独的Owner_Warehouse_Item_Relationship表,而Item表为(ItemId,ItemName,OwnerId),多了一个OwnerId字段,并且Item表的主键为ItemId+OwnerId而非上一种的ItemId。

向BA咨询这块的业务。BA解释说,实际业务中,每个货主有自己的一套编码体系,可以让不同货主为不同的货物选择相同的编码,保证每个货主内部ItemId唯一即可。听完后我想,这样的要求在第一种设计中也是可以实现的。那么这两种设计到底区别何在呢?

第一种设计,Item独立于OwnerId而存在,Domain中的Item对象没有指向Owner的引用;第二种设计,Item依赖于Owner存在,Domain中的Item对象包含一个指向Owner的非空引用。所以,区分这两种设计哪一个正确,等价于问:存在不依赖于Owner的Item吗

对于这个问题,我的直觉是Y,正如这世界上有长虹电视机和熊猫电视机,电视机可以脱离生产厂家而存在。然而,和BA深入讨论后发觉,恰恰是直觉欺骗了我。在目前的业务逻辑中,Item无法脱离Owner而存在。这里业务中的Item,指的是“长虹24"彩电”一类的东西,没有长虹(Owner)的彩电(Item)正如没有24"(尺寸)的彩电一样没有意义。

举数据库设计范式中教师表——课程表——授课表的例子,课程可以脱离教师而存在,这说明不考虑教师的课程仍然具有可比性。学生A修了数学,学生B也修了数学,我们就可以

 

Class a_math = studentA.getClasses().getMath();
Class b_math
= studentB.getClasses().getMath();
a_math.Equals(b_math)

至于这两门课是否是由一个老师上的并不重要。

Class类的Equals方法大概可以写成

 

public  bool Equals(Object o) {
       
// instanceof and some thing
       if (this.name.Equals(o.name)
           
return true;
       
//...
}

 

而对于ColorTV这个类,Equals想必要这样写

public   bool  Equals(Object o) {
    
if (this.shellColor.Equals(o.shellColor)
       
&& this.size==o.size
        
&& this.owner,Equals(o.owner))  // Dose owner property exist?
   
return true;
}

两个彩电相等,光外壳、颜色相等不够,总得是同一个厂家的吧?你要说32寸黑色夏普和32寸黑色TCL能互换的话,专柜老板第一个就不答应。

按照第一种设计,Item中根本就没有Owner,要实现以上的操作很麻烦,所以还是第二种设计好。

总结一下,抽象业务对象的过程中,一定要深入了解业务,不能凭自己的经验行事。决定对象构成时要注意区分必要属性和可选属性。对于某个对象在某个属性设置为null后是否还有意义,一定要考虑清楚,防止出现这种看似有理的设计。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值