快速提问:将我的领域驱动设计风格存储库实现为单例是个好主意还是坏主意?为什么?
或者我应该使用依赖注入器容器来管理我的存储库并确定它们是否是单例?
我仍在快速阅读 DDD,并希望看到一些好的存储库示例。
快速提问:将我的领域驱动设计风格存储库实现为单例是个好主意还是坏主意?为什么?
或者我应该使用依赖注入器容器来管理我的存储库并确定它们是否是单例?
我仍在快速阅读 DDD,并希望看到一些好的存储库示例。
使用您的依赖注入容器来决定如何以及在哪里创建存储库。
通过使用
UserRepository.Instance.Find(userId);
您正在为测试设置障碍。
如果您的存储库使用构造函数注入传递到服务中,那么您也可以轻松地将它们替换为模拟。
我已经看到了几种方法来做到这一点。
最常见的方法是使用依赖注入将存储库注入到使用它们的对象中。通常这些是演示者或控制器类,但在某些情况下,模型会调用存储库。通常最好避免这种情况。如果您可以使用 di-container 来做到这一点,那就去吧。
您还可以使存储库实现单例模式。我会尽量避免这种情况,因为单例通常使用静态方法。这会使测试调用单例的代码变得更加困难。如果您必须以这种方式做事,那么请确保您分离出调用单例的代码并使用“手动”依赖注入将单例注入到调用它们的类中。这消除了一些您原本会得到的紧密耦合。
我见过一些从未调用存储库的示例。当有人在模型中导航对象图并请求一个未加载的对象时,模型只会引发一个事件,并且存储库会对此事件做出反应。这样就没有对存储库的调用,并且它与模型完全分离。我自己没有使用过这种架构,但它看起来很干净。
我不确定这一点,我也有同样的问题。我认为当经常使用它所使用的对象时,您应该将存储库设为单例。并且如果您使用很少使用的对象,则不应将其设置为单例,因为存储库会占用大量内存来存储对象,并且在应用程序使用期间它可能只会被调用一次并且永远不会再次调用。正如我所说,这可能不是正确的想法。
可以说我有一个非常大的项目,我想添加新服务可以说它是我系统中的一些硬件代表。我希望可以通过许多类访问此服务,我想确保只有一个服务实例或控制对服务的访问的层。通过我的所有系统(200 多个类)注入此服务将是很多工作。对我来说,“单例”或某些“服务定位器”非常适合这项任务。
据我了解,该域仅包含一个存储库接口,这意味着单个接口可以有许多存储库实现。所以存储库当然不能是静态类,因为你不能在接口中定义静态方法。(注意:在某些语言中,您可以在接口中定义静态方法,但这对我来说没有多大意义。)
存储库通常用于将实体与数据库、文件等同步。因此它们具有不稳定的依赖关系。这意味着它们不能是单例,只能具有环境依赖项。这是一篇关于它的文章。有趣的部分甚至作者都告诉你,你可以在你的域中使用单例。
据我了解,创建一个确保您只有一个实体而不是多个实体的存储库要干净得多。如果您希望您的代码满足单一责任原则,那是存储库的责任,而不是实体的责任。