caching - 避免单例和全局变量——但是缓存、提供者、 Controller ……呢?

标签 caching controller tdd singleton global-variables

我目前正在通过阅读 books 来“更新”我的开发知识,尤其是 TDD 原则方面的知识。 ,网络上的文章和观看videos 。到处都会弹出警告,不要使用全局状态变量,因为它们会使系统脆弱且不易测试,并且由于单例并没有更好或相同,所以也不要使用它们。

现在我想知道:我真的可以在这一点上保持一致吗?

  • 应用程序使用缓存怎么样,这样它就不必一次又一次查找常用的数据库对象?我需要传递该缓存的单个实例,否则还有什么意义?
  • 另一个例子是 DAO,或者我们称之为提供商。它们除了为我们提供 JPA 数据库访问之外什么也不做,但除此之外没有任何状态。那么为什么不让它们成为单例呢?
  • 网络前端的 Controller 呢?他们所做的只是对请求使用react——同样没有内部状态。

一次又一次实例化后两者岂不是会浪费大量性能吗?我确信还有更多适用于此的示例。

也许使用单例就可以了,只要它们除了final之外没有任何成员变量?

即使它们有成员变量,但所有的成员变量都被注入(inject)到它们中,也应该保存使用它们,因为任何对象,无论是否是单例,都可以修改注入(inject)的对象,所以它实际上没有任何区别。

我对整个“避免单例”业务有点困惑,我什至不确定我是否完全理解所涉及的风险。但最重要的是,我想听听对上述示例的想法,因为这些是我们应用程序中最常见使用单例的地方。

谢谢!

顺便说一句:我们正在使用 springs 依赖注入(inject),所以如何去做不是我的问题,而是为什么要避免它以及哪里可以。

最佳答案

单例的问题不在于单例设计模式本身,而在于它们作为有状态的全局上帝对象在应用程序中被过度使用。

这种使用方式有两个主要缺点:

  • 对单例的依赖是隐藏的依赖,对象与它们紧密耦合,这阻碍了代码的可发现性、可维护性和可测试性。

  • 对象依赖于单例,它们不知道它们处于哪种状态。这里和那里使用单例行为的顺序开始变得重要,并且您开始看到“MySingleton.Initialize( )"到处都是,这是危险的,并且违背了拥有单个实例的全部目的。

在我看来,只有克服这些陷阱的单例才值得考虑——这意味着无状态、不可变的对象以某种方式注入(inject)到它们的消费者中,并且可以被具有相同合约的其他实例替换。

除此之外,单例化通常是对错误对象应用的过早优化。

这篇博文几乎总结了这一点:http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx

关于caching - 避免单例和全局变量——但是缓存、提供者、 Controller ……呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9308034/

相关文章:

postgresql - 如何使用 MongoDB 作为 Postgresql 的缓存?

ruby-on-rails - 不确定在哪里(模型或 Controller )定义我的查找方法

使用 jasmine 在 angularJS 中注入(inject)服务测试 Controller

c# - 调用模拟方法时是否可以使用 Moq 调用异步回调?

javascript - 了解 AngularJS Controller 中的依赖注入(inject)

java - 我用什么代替 Mockito 2.2 中的 Whitebox 来设置字段?

ios - 如何在webview上缓存图像?

java - 如何使用多个过期策略配置 Apache Ignite 缓存

javascript - ExpressJs 在为每个路由发送响应后执行回调

ember.js - EmberJS,轮询,更新路由模型,重新渲染组件