"Singleton"指的是"Singleton".工厂,好还是坏? [英] "Singleton" factories, ok or bad?

查看:63
本文介绍了"Singleton"指的是"Singleton".工厂,好还是坏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多(抽象的)工厂,它们通常以单例形式实现.

I've a lot of (abstract) factories and they're usually implemented as singletons.

通常为方便起见,不必将它们传递给与使用或了解这些工厂完全没有关系的层.

Usually for the convenience of not having to pass them through layers who really have no business with using or knowing these factories.

在大多数情况下,我只需要在启动时决定其余的代码程序是在哪个工厂实现上进行即可,就可以通过

Most of the times I only need to make a decision at startup of which factory implementation the rest of the code program, maybe through some configuration

例如喜欢

abstract class ColumnCalculationFactory { 
  private static ColumnCalculationFactory factory;

 public static void SetFactory(ColumnCalculationFactory f) {
         factory = f;
  }

  public static void Factory() {
         return factory;
  }

 public IPercentCalculation CreatePercentCalculation();
 public IAverageCalculation CreateAverageCalculation();
    ....

}

有些人闻到了,我不确定是什么-它可能是一个单调的全球性人物.并不是真的真的只有一个工厂曾经创建过ColumnCalculations-尽管我的程序不需要更多.

Someting do smell about this, I'm just not sure what - it's maybe more a disuised global than a singleton. It's not like there really really have to be only one factory ever creating ColumnCalculations - although my programs don't need more.

这被认为是最佳实践吗?我是否应该将这些填充在某些(半)全局AppContext类中?还有什么(我还没有准备好切换到更大的IoC容器,或者还没有spring.net,顺便说一句)?

Is this considered best practuce ? Should I rather stuff these in some (semi) global AppContext class ? Something else(I'm not quite ready to switch to some larger IoC container, or spring.net quite yet btw) ?

推荐答案

这实际上取决于您在做什么以及应用程序的范围.如果它只是一个很小的应用程序,并且永远不会超出此范围,那么您当前的方法可能很好.对于这些事情,没有通用的最佳"实践.尽管我不建议将单例用于无状态叶子方法和/或单向调用(例如,日志记录)之外的其他任何事情,但仅因为"它是单例而将其一发不可收拾,所以不一定正确.

It really depends on what you're doing and the scope of your application. If it's just a fairly small app and it's never going to grow beyond this, then your current approach may well be fine. There is no universal "best" practice for these things. While I wouldn't recommend using singletons for anything other than stateless leaf methods and/or one-way calls (e.g. logging), dismissing it out of hand 'just because' it's a singleton isn't necessarily the right thing to do.

对于平凡的代码或原型代码以外的其他任何事情,我个人都希望显式地使用带有构造函数注入的控制反转,因为这意味着所有依赖性都得到考虑,并且您不会得到任何意外".编译器不允许您实例化没有B的B和没有C的B.单例会立即掩埋这些关系-您可以在没有B的情况下实例化A和没有C的情况下B.当从A到B的调用发生时,您将获得空引用例外.

For anything other than trivial or prototype code, I personally like to explicitly use inversion of control with constructor injection, as it means all dependencies are accounted for and you don't get any 'surprises'. The compiler won't let you instantiate A without B and B without C. Singletons immediately bury these relationships -- you can instantiate A without B and B without C. When the call from A to B happens, you'll get a null reference exception.

这在测试时特别令人讨厌,因为您必须通过运行时故障来迭代地反向工作.在测试代​​码时,您就像在使用编码器一样使用API​​,因此它表明了这种方法的设计问题.构造函数注入可确保这种情况永远不会发生-所有依赖项都已预先声明.构造函数注入的不利之处在于对象图的配置更加复杂.通过使用IoC容器可以缓解这种情况.

This is especially annoying when testing, as you have to iteratively work backwards via runtime failures. When you test code, you're using the API just as a fellow coder would do, so it is indicative of the design problems with this approach. Constructor injection ensures this can never happen -- all of the dependencies are stated up front. The downside with constructor injection is that the configuration of your object graph is more complicated. This is mitigated through the use of an IoC container.

我想我想说的是,如果到了考虑使用某种上下文对象和注册表模式的地步,那么您不妨看看IoC容器.当您可以使用成熟的免费产品(例如Autofac)时,努力推出自己的Mutt版本可能会浪费时间.

I guess what I'm trying to say is that if you've got to the point where you're considering using some kind of context object and a registry pattern, you may as well have a look at IoC containers. Going to the effort of rolling your own mutt version is probably a waste of time when you can use an established, free product like Autofac.

这篇关于"Singleton"指的是"Singleton".工厂,好还是坏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆