19

我对这两种模式有些混淆:

单例
检查实例是否存在返回它,或者创建一个新的。

注册表
检查实例是否存在返回它,或者创建一个新的并存储它。

它们之间有什么区别?

4

5 回答 5

19

两者都是关于实例控制的。不同之处在于 Singleton 只允许给定类的一个实例,而 Registry 持有 1-1 的键到实例的映射。通常,键是(或表示)一个类,值是该类的一个实例。

例如,Code Igniter 框架拥有一个注册表,其中包含您加载的每个库/模型/控制器/帮助器的实例,并且每次都返回这些相同的实例。

于 2013-05-24T22:24:09.793 回答
3

注册表的不同之处在于它的主要目的是允许您导航到关联的对象。见马丁福勒

于 2013-05-24T22:25:56.683 回答
3

注册表和单例的主要区别在于,单例允许我们一次创建一个类的单个实例,而注册表允许我们创建同一个类的多个实例。

于 2015-04-29T13:30:02.243 回答
2

访问级别和复杂性

我一直喜欢的一个有趣的警告是,注册表模式正在利用单例来存储/检索对象的动态列表。

单例模式

单例模式是一种用于建立单点访问和方法的模式。虽然许多人认为这是一种反模式,但我向你保证,这只是因为他们工作的水平和他们所做的编程类型。

单例模式在较低级别用于管理严格的资源。例如,虽然大多数语言都有包装键盘输入的库,但它实际上是一种单例模式,因为它具有非常严格的输入/输出,并且无论您有多少键盘,都只能存在一个。

测试单例模式

人们认为单例模式是反模式的原因之一是它们在单元测试系统中通常是不可测试的。在大多数语言中甚至无法模拟单例,因为它固定为特定的身份。

出于这个原因,单例应该是最小的,并且用于接口的包装器。

然后,您可以注入包装器,并且可以对其进行模拟以使用假单例模拟。

注册表模式

注册表模式是您建立单一访问点的地方,而不是单一方法。这种注册表访问至少有 3 种方法:放置、查找和删除。这些方法依赖于单例模式来工作。

该地图是可测试的,因为它不是孤立于您的使用,虽然注册表本身实际上不是与使用它的单元相关的单元测试,但您可以利用注册表打算包含的所有内容的模拟。

但是,如果您在使用 IoC 的给定架构中使用它,则可以从容器注册表中注入注册表,从而允许注入模拟注册表。

最后说明

如今,控制反转非常流行,但是其中很大一部分通常没有被学习或忽略。一些框架将其归结为大多数事情的工厂模式,将其余部分抽象出来。

我强烈鼓励大多数人放弃他们对 IoC 的了解。

然后学习SOLID。之后阅读了一本关于 OOD 设计模式的书。(注:如果书上的花样有优劣就好,如果没有正反两面,我会很警惕这本书。)

虽然这些术语是最近才创造出来的,但这些原则是在早期以一种或另一种方式学习的,实际上成为了面向对象设计的基础。

大多数面向对象开发人员成功使用的模式都基于 SOLID 原则。

对 SOLID 的引用,经过布局和总结。 https://www.digitalocean.com/community/conceptual_articles/solid-the-first-five-principles-of-object-oriented-design

作为最后的建议:即使您不是面向对象的开发人员,学习 SOLID 和 OOD 也非常有用,因为在将系统集成在一起时系统架构必须遵循类似的模式。

此外,我不建议您假设一种语言/模式/哲学最适合所有需求。不断学习,保持开放的心态。您知道的越多,您可以提出的解决方案就越好。

于 2021-09-27T20:52:50.163 回答
1

注册表定义:当您想要查找一个对象时,您通常从与其关联的另一个对象开始,并使用该关联导航到它。因此,如果您想查找客户的所有订单,您可以从客户对象开始,并在其上使用方法来获取订单。但是,在某些情况下,您将没有合适的对象开始。您可能知道客户的 ID 号,但没有参考。在这种情况下,您需要某种查找方法 - 查找器 - 但问题仍然存在:您如何找到查找器?

Registry 本质上是一个全局对象,或者至少看起来像一个——即使它不像看起来那样全局

单例定义:有时一个类只有一个实例很重要。例如,在一个系统中应该只有一个窗口管理器(或只有一个文件系统或只有一个打印假脱机程序)。通常单例用于集中管理内部或外部资源,它们提供了一个全局访问

基于这些定义,它们的用法完全不同。

于 2013-05-24T22:32:25.033 回答