OOAD设计问题
我有两个表: tblCustomer
, tblProduct
:
tblCustomer: Id: Integer, auto-increament Name: Varchar(30) .... tblProduct Id: Integer, auto-increament Name: Varchar(50) customerId: Integer ....
还有两个类: Customer
, Product
:
public class Product { private int id; private int name; /* Other stuffs */ } public class Customer { private int id; private String name; private String phoneNumber; /* get-set and others stuffs */ public static boolean add(Customer cus) { /* This is for insert a customer to tblCustomer */ } public boolean addProduct(Product pd) { /* This is for insert a product to tblProduct with current customer Id */ } }
当客户注册帐户时,它会致电:
Customer cus = new Customer(/* ... */); Customer.add(cus);
当顾客购买产品时:
Product pd = new Product(/* ... */); currentCustomer.addProduct(pd);
但我的老师说OOAD(甚至是OOP)不正确,因为Customer.addProduct
在tblProduct
表上运行,是不是? 这种情况的优秀设计是什么?
**更新:**产品尚未预先定义,当客户购买产品时,商店会将其交付给客户,因此两个相同的产品很少发生,那么tblCustomerProduct
需要吗?
添加一个DAO层,它将包含方法的逻辑部分save
, delete
, update
等。
我通常这样做:
-
basepackage.domain
:包含您的所有实体( 仅限数据,没有逻辑部分 – 在您的情况下是Product
和Customer
) -
basepackage.dao
:包含你所有的DAO, 只用于访问数据 ,基本上每个实体一个,每个实体包含findAll() : List
,findOne(K id) : E
,save(E e) : void
等 -
basepackage.service
:包含您的所有服务, 即应用程序的逻辑部分 。 这些服务是唯一调用DAO的服务。 -
basepackage.presentation
(或webapp的basepackage.web
):包含HMI / web services / …实现。
您的老师可能意味着您需要第三个表,名为“CustomerProduct”。 此表包含客户与他们购买的产品之间的链接。
tblCustomerProduct: Id: Integer, auto-increament CustomerId: Varchar(30) ProductId: Varchar(30)
因此,当客户购买产品时,您将此数据添加到表CustomerProduct。 这将删除冗余数据,并使删除更容易
你的老师是对的。 这不是好设计,因为你创建的类应该具有凝聚力。 因此它应该负责做它能做的事情。 在您的产品类中,您添加了客户ID,这实际上是一种不好的做法,因为客户可能会购买多种产品。 在这种情况下,这种设计将失败。 此外,Product类不需要了解客户的任何信息。 所有它必须知道的本身。
客户与产品之间的关系是一种关联,可以表示为“客户购买产品”。 所以客户ID不应该在产品表中。
关于currentCustomer.addProduct(pd);
方法,它不太适合,因为它更适合产品类而不是客户类。
解决问题的简单方法是创建一个可以将产品与客户联系起来的新类。
例如
CustomerProduct customerid productid
在这个类中,你可以添加像“AddProductForCustomer”这样的方法,并且可以编写你的数据库逻辑来保持一致性。
希望这能清除你的怀疑。
在表格中,客户被分配到产品,但在方法中,您为客户提供并添加产品。
所以我会选择方法pd.setCustomer(currentCustomer)而不是currentCustomer.addProduct(pd)
或者将product表中的customer字段更改为customer表中的products字段。