【问题标题】:Does an object capapble to save itself into DataBase spoils the Cohesion of the class?能够将自身保存到数据库中的对象是否会破坏类的凝聚力?
【发布时间】:2011-05-21 15:45:08
【问题描述】:

在面向对象的设计方面,你认为给一个对象提供一个将自身保存到数据库中的功能会破坏类的凝聚力吗?

想象一下:

Product p = new Product() 
          {
           Name = "Joy Rider", 
           Price = 100, 
           Currency = "USD"
          };

您认为将这个产品p保存到DataBase中这样做更好吗:

 p.Save();

或以类似的方式:

 ProductServices.SaveProduct(p);

你怎么看?

【问题讨论】:

    标签: c# .net oop service cohesion


    【解决方案1】:

    可以将自己保存到数据库的对象将违反SRP(单一责任原则)。

    持久性本身就是一种责任,应该由专门的类来处理。

    这将是除了具有 LOW 内聚性之外 - 与持久性有关的成员与那些不涉及并且不会在不处理持久性的类的方法中使用的成员没有关系。

    【讨论】:

    • OP 没有进一步描述p.Save() 中将存在哪些代码或逻辑。所以p.Save() 可能只是类似于void Save(){ if (IsValid() && XXsomeOtherLogic()) _productService.SaveProduct(this); },其中_productService 可能是IProductService,只是在构造过程中注入Product 的接口。请参阅 Martin Fowler 关于 OP 问题的讨论,题为“AnemicDomainModel”martinfowler.com/bliki/AnemicDomainModel.html:换句话说,我同意@phillip 的回答。
    【解决方案2】:

    它确实干扰了单一责任原则。您的示例中 Product 类的目的是表示产品和对该产品的操作。与数据库交互不是该类职责的核心部分。

    拥有 ProductServices 类可提高代码的可维护性。假设在数据库中保存对象的逻辑是改变(它可以改变)你想改变你系统中的每个实体类吗?

    【讨论】:

      【解决方案3】:

      面向对象设计而言,只有将 Save 方法作为 Product 的一部分才没有任何问题。它实际上是面向对象设计世界中的首选方法。从纯 OO 的角度来看,您不希望它被分解,因为它比对象更具功能性。

      然而,如果你相信依赖倒置原则,即高层模块不应该依赖于低层模块;那么 Save 方法将是合适的,但它应该将抽象 Connection 类型作为参数。这将为您提供一个不错的对象模型,其中包含一个 Save 方法,但它不知道连接的类型。

      【讨论】:

      • burak - 你想知道 Product 中是否应该有 Save 方法吗?或者您想知道是否应该将其移至另一个类 ProductServices?
      • 如果您询问 Save 在 Product 中所做的实际处理,那么 Oded 是正确的,并使用 SRP 将其保持干燥。但是,如果您询问是否应该将该方法移至 ProductServices,那么这不是一个正确的说法,应该更好地讨论一下。
      • 同意@phillip 并喜欢 Phillip 解释实体需要采用抽象连接类型,因此不将域实体与连接耦合:Martin Fowler 在他的文章中写过这个确切的问题题为“贫血领域模型”:martinfowler.com/bliki/AnemicDomainModel.html
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2013-06-09
      • 2011-07-14
      • 1970-01-01
      相关资源
      最近更新 更多