2011-04-04 47 views
1

对于每个具体类我有一个经理类。这个类有像GetAll()GetById()Save可以使用经理类作为单身人士吗?

我做了这些管理类一个Singleton,因为我总是需要一个实例方法,而且我有能力缓存结果。例如,当我打电话给GetAll(),并且下一次我再次需要这个方法时,管理员不必去数据库,它可以返回缓存的结果。

这是一个很好的方法吗?还是有更好的替代方法?

+0

我不知道这里有足够的信息来具体回答这个问题。我也不确定是否有具体的答案。在某些情况下,能够缓存结果将是一个好主意。如果数据是动态的或数据集很大,缓存它可能不是一个好主意(你会得到过时的数据,或者增加不必要的内存压力)。我认为这是非常情景化的。 – pstrjds 2011-04-04 12:39:52

回答

1

为什么不将它们作为具体类的一部分包含进来,而是静态的?节省了两个独立课程的需求。

+0

因为这会违反SRP原则。 – Martijn 2011-04-04 12:39:00

3

你叫什么管理类真的是“仓库”

库,只应在总根级别的工作,而不是每一个类库。例如。如果我有一个有OrderItem集合的Order类,那么Order存储库就会有Get/GetAll方法 - 因为Order在这种情况下是agg根。

所有存储库类通常都是单例类,您通常可以通过IOC容器强制执行此操作。总的来说,我认为你的每个实体的一个“存储库”的方法是错误的,而不是每个聚合根存储在一个存储库中。

+0

我不认为我曾经作为一个单例实现一个仓库。我当然使用DI,但通常每次都注入一个新实例。我应该补充一点,我通常使用“一次每请求”模式(网络)并将一个实例注入处理它的控制器中。因人而异。 – tvanfosson 2011-04-04 12:48:15

+0

@bstack:thnx。还有一个问题。我如何使用IOC容器执行此操作?你能提供一些(样本)代码吗? – Martijn 2011-04-04 13:02:16

+0

@tvanfosson:我看不出如何在我的情况下使用DI。你能解释一点吗? – Martijn 2011-04-04 13:03:02

1

这听起来像你接近实施Repository模式,但并不完全一样。我建议看看它。我不会让他们成为单身人士 - 它让你很难在单元测试中嘲笑他们,所以你最终会增加后门来击败单身人士进行测试。缓存是一个很好的Singleton对象,但为什么不简单地用这种方式共享缓存而不是乘以Singleton呢?

+0

+1。我正在写我的答案,但我不能告诉别的东西:) – Haplo 2011-04-04 12:47:32

+0

你是什么意思'为什么不简单地共享缓存这种方式,而不是乘以单身人士'。我如何共享缓存?你的意思是,将它作为参数传递给你? – Martijn 2011-04-04 13:04:11

+0

@Martijn - 你想要引用一个实例,所以要么使用Singleton缓存,要么使用配置为通过构造函数注入单个实例的DI框架。为了支持单元测试,我有时为单例创建了一个接口并注入了接口的一个实例。这可以让你模拟测试。在构造函数中,我检查参数是否为null(生产代码就是这种情况),如果是,则默认为Singleton实例。 – tvanfosson 2011-04-04 13:30:50

0

为了测试/嘲笑的目的,我建议不要使用经理/存储库单身人士。

如果你确实想缓存结果,那么我会建议委托给一个专用的Cache类。任何静态魔术都可以包含在Cache类中,并且Manager/Repository的语义可以保持清洁。

从单一职责原则的角度来看,我应该能够理解Manager/Repository如何工作,而无需了解您的缓存方案。