如果一个对象有一个 Single Responsibility , 以下是否可以接受:
public class Person
{
public string Name;
public DateTime DateOfBirth;
private IStorageService _storageService;
public Person(IStorageService storageService)
{
_storageService = storageService
}
public void Save()
{
_storageService.Persist(this);
}
}
即使用提供的合作者(这也有助于阻止域模型贫血)。
或者应该是:
public class Person
{
public string Name;
public DateTime DateOfBirth;
public Person()
{
}
}
public class StorageService
{
public void Persist(Person p)
{
}
}
最佳答案
can the following be acceptable?
class Person {
Person(IStorageService) { } ...
void Save() { } ...
}
这种依赖没有意义。
虽然它没有将 Person
强耦合到 Storage
,因为它没有将它们绑定(bind)到特定存储实现,我认为任何此类依赖都是没有意义的。
作为动词的方法
将类上的方法视为将由该类型执行的动词。您是在告诉该类型的实例相对于其本地域“做某事”。
作为一个人,Save
是什么意思?
- 我更换了我的保险公司并将我的费用降低了多达 15%?
- 我是救赎之神?
- 我已将我的灵魂下载到一个自动机中?
存储服务可以而且应该Save
。人们不能保存
,也不应该宣传他们可以。
试着用鞋拔它
SaveTo
可能更有意义 - 即 public void SaveTo(IStorageService storage)
。
但是你是说一个人有责任知道如何将自己保存到存储中。在我看来,这是a violation of SRP .它还显示a missing piece of Domain Analysis .
Person
的域不包含任何关于保存、存储等的内容。它将包含人与人之间的交互,以及该域级别的其他事物。数据持久性域更适合使用 Save
方法。
如果 Person
在问题域中(在那个抽象级别),那么 Storage
在解决方案域中。
你应该如何分离你的逻辑
这里有三个逻辑:
Person
- 了解“person things”存储
- 了解特定类型的存储以及如何访问它Storage of Person
- 了解一个人应该如何致力于存储
按照我上面的建议,我会让 Person
独立存在。但是,您可以将 Storage
和 Storage of Person
的逻辑分开,也可以将它们结合起来。
The approach that ORMs take就是把这三个概念分开。 “对象关系映射”中的“映射”是对“人的存储”的封装。
这种方法允许您的 Storage
逻辑专注于读取存储配置、连接到存储、确保存储速度快、选择备用存储方法等潜在的复杂工作。它还消除了对您的主域模型,因此存储代码可以被任何其他域模型重用。
关于c# - 单一职责和依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8100009/