单一责任和依赖

7 c# oop dependency-injection single-responsibility-principle

如果对象具有单一责任,则可以接受以下内容:

public class Person
{
   public string Name;
   public DateTime DateOfBirth;

   private IStorageService _storageService;

   public Person(IStorageService storageService)
   {
      _storageService = storageService
   }

   public void Save()
   {
        _storageService.Persist(this);
   }
}
Run Code Online (Sandbox Code Playgroud)

即使用提供的协作者(这也有助于阻止领域模型贫血).

或者应该是:

public class Person
{
   public string Name;
   public DateTime DateOfBirth;

   public Person()
   {
   }


}
public class StorageService
{
    public void Persist(Person p)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

Mer*_*ham 10

可以接受以下内容吗?

class Person {
Person(IStorageService){} ...
void Save(){} ...
}

这种依赖没有意义.

虽然它没有强烈耦合PersonStorage,因为它没有将它们绑定到特定的存储实现,我认为任何这样的依赖都没有意义.

作为动词的方法

将类上的方法视为将由该类型执行的动词.您告诉该类型的实例"做某事",就其本地域而言.

当我作为一个人时,这意味着什么Save

  • 我改变了我的保险提供商并将我的成本降低了15%?
  • 我是一个救赎神?
  • 我把自己的灵魂下载到自动机中?

存储服务可以而且应该Save.人们不能,也不Save应该宣传他们可以.

试着穿上它的角

SaveTo可能更有意义 - 即public void SaveTo(IStorageService storage).

但后来你说一个人有责任知道如何将自己保存到存储中.在我看来,这违反了SRP.它还显示了一个缺少的域分析.

a的域名Person不包含有关保存,存储等的任何内容.它将包含人员之间的交互,以及该域级别的其他内容.数据持久性领域是方法的更好地方Save.

如果Person是在问题域(在该抽象级别),则Storage在解决方案域中.

你应该如何区分你的逻辑

这里有三条逻辑:

  1. Person - 了解"人物"
  2. Storage - 了解特定类型的存储以及如何访问它
  3. Storage of Person - 了解一个人应该如何致力于存储

按照我上面的建议,我会Person独自站立.但是,您可以为Storage和分隔逻辑Storage of Person,或者可以将它们组合在一起.

ORM采用的方法是将所有三个概念分开."对象关系映射"中的"映射"是封装"人员存储"的地方.

这种方法允许您的Storage逻辑专注于读取存储配置,连接到存储,确保存储快速,选择备用存储方法等可能复杂的工作.它还消除了对主域模型的任何依赖,因此存储代码可以是由任何其他域模型重用.