“单例”工厂,好还是坏?

2024-01-09

我有很多(抽象)工厂,它们通常作为单例实现。

通常是为了方便,不必将它们传递给实际上与使用或了解这些工厂无关的层。

大多数时候我只需要在启动时决定哪个工厂实现其余的代码程序,也许通过一些配置

它看起来例如喜欢

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();
   //....
}

有些东西确实闻到了这一点,我只是不确定是什么 - 它可能更像是一个隐藏的全局而不是一个单例。这并不像真的那样have to成为唯一一个创建 ColumnCalculations 的工厂 - 尽管我的程序不需要更多。

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


这实际上取决于您正在做什么以及您的应用程序范围。如果它只是一个相当小的应用程序,并且永远不会超出这个范围,那么您当前的方法很可能没问题。这些事情没有通用的“最佳”实践。虽然我不建议将单例用于无状态叶方法和/或单向调用(例如日志记录)之外的任何内容,但“仅仅因为”它是单例而立即忽略它并不一定是正确的做法。

对于除琐碎代码或原型代码之外的任何内容,我个人喜欢通过构造函数注入显式使用控制反转,因为这意味着所有依赖项都被考虑在内,并且您不会得到任何“惊喜”。编译器不会让你实例化没有 B 的 A 和没有 C 的 B。单例会立即埋葬这些关系——你可以实例化没有 B 的 A 和没有 C 的 B。当从 A 到 B 的调用发生时,你将得到一个空引用例外。

这在测试时尤其烦人,因为您必须通过运行时故障迭代地向后工作。当您测试代码时,您就像其他编码员一样使用 API,因此这表明了这种方法的设计问题。构造函数注入确保这种情况永远不会发生——所有依赖项都已预先声明。构造函数注入的缺点是对象图的配置更加复杂。通过使用 IoC 容器可以缓解这种情况。

我想我想说的是,如果您已经考虑使用某种上下文对象和注册表模式,那么您不妨看看 IoC 容器。当您可以使用像 Autofac 这样成熟的免费产品时,努力推出自己的 mutt 版本可能是浪费时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“单例”工厂,好还是坏? 的相关文章

  • Android 中的静态单例生命周期

    我有一些不清楚的情况 最后一个持有 Activity 的引用被销毁后 静态单例会被垃圾回收吗 因为Application中没有更多对单例实例的引用 那么我可以依赖单身人士吗 由官方提供安卓文档 http developer android
  • 为什么这种双重检查锁定是正确的? (。网)

    我读过很多关于双重检查锁定的危险的文章 我会尽力避免它 但话虽如此 我认为他们读起来非常有趣 我正在阅读 Joe Duffy 的这篇关于使用双重检查锁定实现单例的文章 http www bluebytesoftware com blog P
  • Dagger 2 - 如何创建/提供 EagerSingleton

    我在使用 Dagger 2 依赖注入框架时遇到问题 我想创建一个渴望单例 我假设当我使用 dagger 2 时会创建延迟加载的单例 Singleton注解 我如何创建渴望单例使用 Dagger 2 框架 我通过创建一个解决了这个问题Eage
  • 如何避免c#中windows窗体的多个实例

    如何避免在 C 中出现多个 Windows 窗体实例 我只想运行该表单的一个实例 因为有机会从我的申请的许多页面打开相同的表格 是的 它有单例模式 创建单例对象的代码 public partial class Form2 Form priv
  • 如何避免在 Scala 中使用 asInstanceOf

    目前我的代码需要类转换 val dataWriter BytesDataWriter createDataWriter def createDataWriter p SomeClass p create datawriter asInsta
  • JavaScript 中工厂函数与构造函数的性能比较

    所以 当我们有一个简单的构造函数时 function Vec x y this x x this y y 还有一个工厂类似物 function VecFactory x y return x x y y 性能具有可比性 100000000
  • 单例模式面试

    我最近在一次采访中被问到与java相关的问题 代码如下 因为我对java非常陌生 几乎没有用Java编写代码 所以我真的不知道下面的代码是做什么的 问题是 使用以下代码选择描述最糟糕情况的选项 public class Bolton pri
  • Python 类:通过传递值实现单例还是非单例?

    我有一个 Python 3 类 目前是使用 a 定义的单例 singleton装饰器 但有时需要not成为单身人士 问题 是否可以在从类实例化对象时执行类似于传递参数的操作 并且该参数确定该类是否是单例 我试图找到一种替代方法来复制类并使其
  • 静态库中的单例类

    假设我在静态库中有一个单例类 S 它可以与其他动态库 D1 D2 D3 链接 因此 据我了解 类 S 在每个 D1 D2 和 D3 中都会有一个单独的实例 即使它不是单例 如全局 这也是正确的 有什么办法可以防止S类的多副本吗 我无法将单例
  • EJB 中 @Stateless 相对于 @Singleton 的真正用例是什么

    如果我正确理解EJB Singleton实际上与普通Java中的Singleton相同 也是spring中的单例 gt 一个实例 每个调用同时通过同一个实例 Stateless 声明一个 bean 它可以 但不得 具有多个实例 但限制是一个
  • 确保 Clojure 中只有一个服务实例正在运行/启动/停止的规范方法?

    我正在用 Neo4j 支持的 Clojure 编写一个有状态服务器 它可以服务套接字请求 例如 HTTP 当然 这意味着我需要能够从该服务器内启动和停止套接字服务器 在设计方面 我希望能够在此服务器中声明一个 服务 并启动和停止它 我在 C
  • 关于存储库的领域驱动设计问题

    我正在尝试实现 DDD 因此我创建了以下类 用户 域模型 UserRepository 管理对象的中央工厂 UserMapper UserDbTable 映射应用程序功能并提供 CRUD 实现的映射器 我的第一个问题是 当模型需要与持久层通
  • 在静态类中拥有状态是不好的做法吗?

    我想做这样的事情 public class Foo Probably really a Guid but I m using a string here for simplicity s sake string Id get set int
  • 自定义“出口工厂”

    一个桌面应用程序使用MEF导入许多 服务提供商 每个部分 ServiceProvider 都是一个单独的 DLL 中的类 所有 DLL 都位于桌面应用程序使用的 Plugin 文件夹中 因为我需要我的零件的新实例 ExportFactory
  • @Inject 和 @PostConstruct 不适用于单例模式

    我有一堂课如下 public class UserAuthenticator private static UserAuthenticator authenticator Inject private UserRepository user
  • 每个用户的单例模式 ASP.NET C#

    我正在使用 asp net c 构建一个 Web 应用程序 并且我有一个类 我想在多个页面中使用该类 而无需每次都实例化它 我需要加载其中的数据并且在用户会话期间永远不会丢失它们 我考虑过单例模式 但它在浏览器之间共享类的实例 我该如何解决
  • AngularJS 中的非单例服务

    AngularJS 在其文档中明确指出服务是单例 AngularJS services are singletons 违反直觉的是 module factory还返回一个 Singleton 实例 鉴于非单例服务有很多用例 实现工厂方法以返
  • 如何使 Log4Net 包装类成为单例类?

    我有一个 log4net 包装类 但是每次我从其他类调用它来记录错误时都需要实例化 我需要克服这个问题 最近我遇到了我不熟悉的单例类 因此我需要帮助将我当前的包装类转换为单例类 我正在发布我目前正在使用的 log4net 包装类 using
  • Java EE 6 和单例

    谁能解释一下在 Java EE 6 应用程序中实现 Singleton 的完整过程 我假设我不应该以声明静态变量的典型方式创建单例 而应该使用 Singleton注解 我必须这样做吗 难道只是声明一下的情况 Singleton就是这样 我还
  • 基于 Typeof 的工厂或者是

    下面的代码有什么更优雅的方法 我想根据另一个类的类型返回派生类 if option is Rectangle modelInputs new Foo else if option is Circle modelInputs new Bar

随机推荐