单一职责原则与贫乏/丰富领域模型有何关系?
目前正在对从另一个团队接管的东西进行一些代码审查,并对应用 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);
}
您能给我指出任何我可以阅读的有关此问题的链接吗?我在这里找到了一个线程,但它并没有完全回答我的问题。
DDD中是如何解决的? DDD 中的模型根据定义是丰富的,并且可以被视为具有太多的职责。
Currently in doing some code review of stuff taken over from another team and have one doubt about applying SRP and its relation to anemic or rich domain model (as defined by Martin Fowler).
Rich domain model concept is to have intelligent object that can not only set/get their properties but also can perform some more complicated business logic. I wonder how it fits into SRP?
Say I have my model class having some properties that can expose those props and provide some simple calculations on its properies. Next requirement is to have possibility to store this object data in some storage object that is not under my control, like this:
class MyObject {
// get set
// parse sth
}
Store method in storage
storage.store(key, object);
Doesn't it violate SRP if MyObject has store method like this
public void store(Storage storage) {
storage.store('keyOne', fieldOne);
storage.store('keyTwo', fieldTwo);
}
From this object's pov it is a good think to be able to store its state.
Other way could be to introduce sort of service here and do this like that:
public StorageService {
private Storage;
// constructor here
....
public void store(MyObject myobj);
}
Can you point me any links I can read about this problem? I've found one thread on SO here but it doesn't answer my question completely.
How is it resolved in DDD? Models in DDD are by definition rich and can be seen as having too many responsibilities.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
富域模型 (RDM) 意味着控制模型行为的逻辑属于模型内部,而不是将模型视为数据getter/setter。这并不意味着包括持久性、安全性、如何在 GUI 中显示模型等在内的所有内容都需要位于模型内。
RDM 和SRP 齐头并进,并不冲突。
违反 SRP/RDM:
遵循 SRP/RDM:
A rich domain model (RDM) means that the logic governing the model's behavior belongs within the model, as opposed to treating the model like data with getters/setters. This does not mean everything including persistence, security, how to display the model in the GUI, etc. needs to be within the model.
RDM and SRP go hand-in-hand, they do not conflict with each other.
Violating SRP/RDM:
Following SRP/RDM:
“DDD 中的模型根据定义是丰富的,并且可以被视为具有太多的责任”是对 DDD 的简单化解释。这始终取决于您的模型有多好。您可能会使用 DDD 创建糟糕的模型(例如创建具有太多职责的对象或创建贫乏的模型)。 DDD 和 SRP 是两个值得遵循的良好实践,就像重构、TDD 等等一样,但您应该用您的经验和判断(或其他人的)来补充它们的使用。任何事物都有其优点和缺点,不要教条地应用任何实践。
"Models in DDD are by definition rich and can be seen as having too many responsibilities" is a simplistic interpretation of DDD. Always it depends in how good are your models. You could create bad models using DDD (for example creating objects with too many responsabilities or creating anemic models). DDD and SRP are two good practices too follow, as much as refactoring, TDD and many more, but you should complement their use with your experience and judgement (or someone else's). Everything has its pros and cons, don't be dogmatic about applying any practice.
@Garrett Hall
我有点不同意你的说法“RDM 和 SRP 齐头并进,它们并不相互冲突。”根据我的经验,当过分强调 SRP 时,就会导致领域模型贫乏。 “不,我们不能做,甚至不能帮助支持任何持久性,不,我们不能做 21-CFR11,不,我们甚至不知道 GUI 是什么......”并且你的班级最终会做什么都没有,只有一个贫血领域模型。
如果过分强调 RDM(这就是我容易陷入的方向/错误),那么 SRP 就会完全被抛在一边,您最终会注意到您的类有 100 个方法,并且显然做得太多了。
您需要找到一个平衡点,即 RDM 和 SRP 都能实现的折衷方案。找到这种平衡是很困难的,而且通常需要团队内部更多的直觉和政治,而不是技术头脑或规则。
“认识你自己”。如果您像我一样,倾向于过于复杂的课程,请注意。当你看到别人的类甚至对你来说也看起来太复杂时,那就是一个很大的危险信号。同样,如果您知道自己对 SRP 非常狂热,并且看到一个类即使按照您的标准看起来也很贫乏,那么这就是主要的代码味道。
现在,在某种程度上回答OP关于存储的问题,我认为很大程度上取决于存储的稳定性、标准和抽象程度。如果存储是某种标准的 XML、CSV 或 RDB 抽象,那么我对知道如何存储自身的对象绝对没有问题。
@Garrett Hall
I somewhat disagree with your statement "RDM and SRP go hand-in-hand, they do not conflict with each other." In my experience, when SRP is overemphasized, it leads to an anemic domain model. "No, we can't do or even help support any persistance, no, we can't do 21-CFR11, no, we can't even know what a GUI is..." and your class ends up doing nothing and just have an Anemic Domain Model.
And if RDM is overemphasized (that's the direction/error I tend to fall into) then SRP completely falls by the wayside and you eventually notice that your class has 100s of methods and is clearly doing too much.
You need to find a balance, the happy medium where both RDM and SRP are happening. And finding that balance is hard and often involves more gut-feelings and politics within your team than technical savvy or rules.
"Know thyself". If you are like me, and tend towards overly complex classes, be aware. And when you see somebody else's class that looks too complex even to you, that a big red flag. Likewise, if you know that you are pretty hardcore about SRP, and you see a class that looks anemic even by your standards, that's a major code smell.
Now, somewhat answering the OP's question about Storage, I think a lot depends on how stable, standard, and abstract Storage is. If Storage were some standard XML, CSV, or RDB abstraction, I have absolutely no problem with objects knowing how to store themselves.