【问题标题】:OOAD Design issueOOAD 设计问题
【发布时间】:2013-05-03 09:51:07
【问题描述】:

我有两张桌子:tblCustomertblProduct

tblCustomer:
    Id: Integer, auto-increament
    Name: Varchar(30)
    ....

tblProduct
    Id: Integer, auto-increament
    Name: Varchar(50)
    customerId: Integer
    ....

还有两个类:CustomerProduct

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需要吗?

【问题讨论】:

    标签: java oop ooad


    【解决方案1】:

    您的老师可能的意思是您需要第三张表,命名为“CustomerProduct”。此表包含客户之间的链接以及他们购买的产品。

    tblCustomerProduct:
        Id: Integer, auto-increament
        CustomerId: Varchar(30)
        ProductId: Varchar(30)
    

    因此,当客户购买产品时,您将此数据添加到表 CustomerProduct。这将删除冗余数据,也使删除更容易

    【讨论】:

    • 我没注意到Product不是预定义的,当客户购买产品时,商店会制作并交付给客户
    • 产品应该存储在系统中,否则客户会在没有看到哪些产品可用的情况下购买产品?每次客户购买产品时,您当前的解决方案都会在 tblProducts 中创建一个新行。这将使这些行变得多余。你的老师希望你做的是创建第三张表,正如我所描述的那样。
    • 另请注意,您的老师说过引用:But my teacher said it not correct in OOAD (and even OOP) because Customer.addProduct is operate on tblProduct。您的老师的意思是让 Customer.addProduct 对表 Product 进行操作是不正确的,您将需要在其中“操作”的第三个表。
    【解决方案2】:

    你的老师是对的。这不是好的设计,因为您创建的类应该是有凝聚力的。所以它应该负责做它可以做的事情。在您的产品类别中,您添加了客户 ID,这本质上是一种不好的做法,因为客户可能会购买多种产品。在这种情况下,这种设计将失败。而且 Product 类也不需要了解客户的任何信息。它只需要知道它自己。

    客户与产品之间的关系是一种关联,可以表示为“客户购买产品”。所以客户 ID 不应该出现在产品表中。

    currentCustomer.addProduct(pd); 方法不太适合,因为它更适合产品类而不是客户类。

    解决您的问题的简单方法是创建一个可以关联产品和客户的新类。

    例如

    CustomerProduct
    
    customerid
    productid
    

    在这个类中你可以添加像“AddProductForCustomer”这样的方法,并且可以编写你的数据库逻辑来保持一致性。

    希望这能消除您的疑虑。

    【讨论】:

    • 我没注意到 Product 不是预定义的,当客户购买产品时,商店会制作并交付给客户,所以需要CustomerProduct 吗?
    • @BìnhNguyên :客户如何在没有看到产品的情况下购买产品?它必须存在于系统中的某个地方。那么只有他会买。即使您想让它正常工作,也要先在数据库中插入产品。获取插入产品的 id 并在 CustomerProduct 表中创建条目。
    【解决方案3】:

    添加一个 DAO 层,该层将包含 savedeleteupdate 等方法的逻辑部分。

    这是我通常的做法:

    • basepackage.domain:包含您的所有实体(仅数据,无逻辑部分 - 在您的情况下为 ProductCustomer
    • basepackage.dao:包含你所有的DAO,仅用于访问数据,基本上每个实体一个,每个包含findAll() : List<E>findOne(K id) : Esave(E e) : void等方法。李>
    • basepackage.service:包含您的所有服务,应用程序的逻辑部分。这些服务是唯一调用 DAO 的服务。
    • basepackage.presentation(或 basepackage.web 用于 Web 应用):包含 HMI/Web 服务/... 实现。

    【讨论】:

    • 服务是否等于控制层(在三层模型中)?
    • 等于模型(如果你是引用MVC的话)
    • @BìnhNguyên 是的,它有几个名称:业务层、控制层、服务层、逻辑层……
    • @JohnSnow 实际上,MVC 参与了 n 层架构的表示层。更多信息here.
    【解决方案4】:

    在表格中,客户被分配到一个产品,但在您给客户并添加产品的方法中。

    所以我会选择方法 pd.setCustomer(currentCustomer) 而不是 currentCustomer.addProduct(pd)

    或者将product表中的customer字段改为customer表中的products字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      • 2011-11-09
      • 2011-01-16
      • 2011-03-21
      相关资源
      最近更新 更多