这是对单身人士如此糟糕的一些评论的回应
有人建议可以使用代理模式代替单例来缓存DB数据.但我看不出优势,事实上单身人士似乎更"可控".
让我详细说明这个问题.假设你有一个数据库,有大量的数据,从不改变,所以它可以被认为是只读的,为什么代理模式比单例更好地建模这个数据缓存呢?
(PS:如果你要说"因为它更''可测试'!" - 请详细说明,我仍然习惯这些概念)
谢谢你的帮助!
免责声明:我在这里用java术语发言
singleton现在被认为是反模式,因为它们最近被滥用了很多,因为它们是一种快速方便的方式在应用程序之间共享数据 - 这有点过分了设计模式,更适合为共享资源提供访问控制.
考虑一个程序标准输出:该资源的访问需要通过单点访问来保护以允许写入的同步,这就是为什么你将例如System.out作为java中的静态实例的原因.
问题是,当你开始使用单身人士时,你需要知道你正在做的事情的每一个细节,因为你在你的单身人士课上做了很多严格的假设,最重要的是它将是唯一一个系统中的类.然后你开始使用它,假设它总是一个单一的资源入口点,然后出现讨厌的bug,因为你的类现在已部署在一个ejb服务器上,每个ejb上下文都有它自己的单例,还有一个单独的从服务器重新加载的每个jsp,以及每次单例序列化和反序列化时的一个单例(因为你可能忘记覆盖readResolve()方法).
所以这就是为什么单身必须经常使用的原因,现在它们被认为是反模式,尽管它们对于它们的预期用途是完全有用的.
在数据库缓存的情况下,使用这个"缓存"资源的代理来让每个类需要缓存是更好的方法,因此您可以添加逻辑以代替代理本身"查找资源"将逻辑与高速缓存单例的检索联系起来,取决于环境,高速缓存单例可能有效,也可能不起作用.
因此,使用单例作为对资源进行共享访问的手段很少,因为您正在硬编码查找资源的方法(并忽略单例陷阱),而单独控制资源以实现同步目的是完全可以接受的.
想到信号量,只有当你能够获得相同的信号量时才能使用它们.在后一种情况下,可能存在的问题是从您需要访问该信号量的任何地方访问单例:在这里,您需要一些类来包装单例并提供对信号量本身生命周期的更精细控制.
代理旨在涵盖"在整个系统中提供资源"的角色,无论是单个应用程序,客户端服务器系统,同一系统的不同组件等等,还有一个额外的好处是使用èrpxy检索资源是不透明的.你可能让他们为你提供一个包含缓存值的hashmap的单例,你可以让他们访问网络上的memcached somwhere,你可以让他们在测试期间读取csv,所有这些都不会改变你从应用程序中调用它们的方式.