10

目前正在对从另一个团队接管的东西进行一些代码审查,并且对应用 SRP 及其与贫乏或丰富的域模型(由 Martin Fowler 定义)的关系存在疑问。富域模型概念是拥有智能对象,不仅可以设置/获取其属性,还可以执行一些更复杂的业务逻辑。我想知道它如何适合 SRP?

假设我的模型类具有一些属性,这些属性可以公开这些道具并对其属性提供一些简单的计算。下一个要求是有可能将此对象数据存储在一些不受我控制的存储对象中,如下所示:

class MyObject {
    // get set
    // parse sth
    
}

存储中的存储方法

   storage.store(key, object);

如果 MyObject 有这样的存储方法,它不会违反 SRP

public void store(Storage storage) {
    storage.store('keyOne', fieldOne);
    storage.store('keyTwo', fieldTwo);
}

从这个对象的 pov 来看,能够存储它的状态是一个很好的想法。其他方法可能是在这里引入某种服务并这样做:

public StorageService {
    private Storage;
    // constructor here
    ....
    public void store(MyObject myobj);
}

您能指出我可以阅读有关此问题的任何链接吗?我在这里找到了一个关于 SO 的线程,但它并没有完全回答我的问题。

在 DDD 中是如何解决的?DDD 中的模型根据定义是丰富的,并且可以被视为具有太多的职责。

4

3 回答 3

7

富域模型 ( RDM ) 意味着控制模型行为的逻辑属于模型内部,而不是将模型视为具有 getter/setter 的数据。这并不意味着包括持久性、安全性、如何在 GUI 中显示模型等所有内容都需要在模型中。

RDM 和 SRP 齐头并进,它们不会相互冲突。

违反 SRP/RDM:

Car {
   // possibly violates SRP
   storeInDatabase();  
   // smells like anemic domain model
   getEngineState();   
}

遵循 SRP/RDM:

// usings aspects to remove cross-cutting concerns from the model and follow SRP
@DatabaseSerializable 
Car {
   // rich domain model encapsulates engine state and exposes behavior
   drive();            
}
于 2012-01-10T19:22:02.867 回答
4

“DDD 中的模型根据定义是丰富的,并且可以被视为具有太多责任”是对 DDD 的简单解释。始终取决于您的模型有多好。您可以使用 DDD 创建不良模型(例如创建具有太多责任的对象或创建贫血模型)。DDD 和 SRP 也是遵循的两种良好实践,与重构、TDD 等等一样多,但您应该用您(或其他人)的经验和判断来补充它们的使用。任何事物都有其优点和缺点,不要教条地应用任何实践。

于 2012-01-10T19:03:10.050 回答
3

@加勒特大厅

我有点不同意你的说法“RDM 和 SRP 齐头并进,它们并不相互冲突。” 根据我的经验,当过分强调 SRP 时,会导致领域模型贫乏。“不,我们不能做,甚至不能帮助支持任何持久性,不,我们不能做 21-CFR11,不,我们甚至不知道 GUI 是什么......”你的班级最终什么都不做,只是有一个贫血域模型。

如果 RDM 被过分强调(这是我倾向于陷入的方向/错误),那么 SRP 就完全被搁置了,你最终会注意到你的类有 100 种方法,而且显然做得太多了。

您需要找到一个平衡点,即 RDM 和 SRP 都发生的快乐媒介。找到这种平衡是很困难的,而且往往涉及到团队内部更多的直觉和政治,而不是技术知识或规则。

“认识你自己”。如果您像我一样,并且倾向于过于复杂的课程,请注意。当你看到别人的课程对你来说也太复杂了,这是一个很大的危险信号。同样,如果您知道自己对 SRP 非常铁杆,并且您看到即使按照您的标准看起来也很乏味的课程,那是主要的代码气味。

现在,在某种程度上回答了 OP 关于存储的问题,我认为很大程度上取决于存储的稳定性、标准和抽象程度。如果存储是一些标准的 XML、CSV 或 RDB 抽象,我对知道如何存储自己的对象完全没有问题。

于 2012-01-10T20:58:55.623 回答