代码之家  ›  专栏  ›  技术社区  ›  remi bourgarel

关于OOP的基本问题

  •  3
  • remi bourgarel  · 技术社区  · 16 年前

    当我必须为一个Web应用程序设计我的类时,我经常遇到同样的问题。要求如下: -可维护(例如无复制粘贴) -完全分离的层(业务层不必知道使用哪种数据层方法) -高性能:不加载无用数据。

    首先,我有一张表,上面列出了我所有的客户及其地址: 代码:

    Customer
    --Id
    --Name
    --Address
    ----City
    ----ZC
    ----Street
    

    现在我想要一张桌子(在另一页),上面有我所有的顾客和他们买的书,我有几个可能性:

    1/i创建新类:

    代码:

    CustomerWithBooks
    --Id 
    --Name
    --Books[]
    ----ID
    ----name
    

    pro:我只加载有用的数据 缺点:我在我的UI之后构建我的类,并且有复制粘贴。

    2/我在头等舱加书。 专家:所有东西都在同一个类中,可以维护。 缺点:我免费加载地址。如果我不加载地址,我可以:懒惰加载,但我真的不喜欢它,或者当我使用我的类时,我必须知道我调用了DAL的哪种方法,我不喜欢它。

    3/我使用继承: 代码:

    ClientBase
    --ID
    --Name
    
    ClientWithBooks : ClientBase
    --Books[]
    
    ClientWithAdress : ClientBase
    --Address
    

    pro:真的是维护性的,我不会白白加载数据。 缺点:如果在一个用户界面中我想显示图书和地址,我该怎么做?

    4??我希望有一个完美的解决方案

    5 回复  |  直到 16 年前
        1
  •  3
  •   Patrick Karcher    16 年前

    如果我理解的正确的话,你的选项1接近于好的。一个顾客和一本书是两个完全不同的东西。您希望将该数据/功能分开,并且不应继承自任何公共基类(您已经创建的)。

    正如“骗子”所说: 我在我的UI之后构建我的类,并且有复制粘贴 .

    • a. 如果您在确定设计和代码类之前模拟了一些UI来帮助澄清需求,那就是 好的 不错。
    • B. 良好的域对象排列有助于消除复制/粘贴,而不是导致复制/粘贴。如果您的有序类(通常是数据访问代码)中有一些看似重复的典型代码,不要担心。您可以使用良好的数据访问层/工具、良好的共享日志资源等来解决问题。类中重复的代码只意味着您需要做更多的设计改进, 不 对于所有领域的实际情况都有单独的类是不好的。

    在需要处理客户和书籍的页面上,您将使用 顾客 对象和 书 对象,可能是 书 集合对象。根据DB/对象模型的设置方式,您可能需要处理其他对象,以便从客户那里得到他们购买的书籍。例如,客户可能同时购买一本或多本书,这些书与 秩序 对象,它具有对客户的引用。所以,你可能会从

    1. 顾客 对
    2. 命令 包含所有客户向个人订购的集合
    3. 秩序 从那里到相应的
    4. 书 包含所有
    5. 书 与该顺序对象相关的对象。

    这些都不需要互相继承。现在,让我们假设让客户购买所有的书是你做了很多事情,并且你想要简化。然后,您希望有一个直接来自客户的图书集合,它提供了这一点,尽管用于获取这些图书的SQL查询仍然通过数据库中的订单进行。你 必须 从对象模型(以及幕后的表)开始 准确反映现实 . 即使这给了你很多课程 更简单 最后。你可能会得到一些遗产,但你可能不会。

        2
  •  1
  •   Mike Mooney    16 年前

    我会避免2和3,因为它将你锁定在一个限制性的层次结构中,而这个层次结构并不能真正满足你的需求。正如您所指出的,可能有任何您想要的东西的组合,例如客户和他们的书,也许他们的地址,也许他们的订购历史。或者你可能会想要一本有顾客名单的书。由于您的基础业务信息不是真正的层次结构,所以您应该尽量避免使对象模型具有不必要的层次结构。否则,你会建立一些限制,在以后会引起很多头痛,因为你现在不能想到所有的场景。

    我觉得你和1的关系是对的。我要说为客户和书籍创建一些基本类,然后创建一个包含客户和书籍实例的CustomerBook关联类。然后,您可以让您的方法担心如何将给定场景的数据加载到该列表中。

        3
  •  0
  •   chelmertz user1604064    16 年前

    我会把地址写进去 Customer ,并且有一个单独的书籍集。

    Bookshelf
    --Books[]
    

    这样,A 顾客 没有,但可以有,一本或多本与他相关的书。下面是PHP代码示例:

    class BookshelfFactory {
      public static function getBookshelf(Customer $customer) {
         // perform some fetching here
         return $bookshelf;
      }
    }
    
        4
  •  0
  •   shadit    16 年前

    从面向对象设计(OOA&D)的角度来看,您是在向后设计。在持久性(通常是关系数据库)层使用数据驱动设计是正常的。但在OOA&D中,考虑对象将发送和接收的消息更为正常(建模对象的方法而不是其成员)。我会这样想:

    Customer
    +getBooks():List<Book>
    +getAddress():Address
    
        5
  •  0
  •   Wim    16 年前

    我认为您的问题是实现数据映射层的一个问题。

    您可以使用连接进行高性能的查询,从而返回客户及其书籍。

    映射层将此映射到适当的唯一对象中,并负责为对象创建正确的多个聚合。

    此外,还可以满足浅加载、显示属性保存不必要的数据量,以便在每个对象只需要几个属性的情况下进行传输。