获取或创建对象的方法应该起一个好的名字是什么?

93

假设你有一个缓存,并且有一个方法会执行以下操作:

if (wanted Foo is not in cache)
    cache.Add(new Foo())
Return Foo from cache

你会如何命名这个方法? GetFoo(), GetOrCreateFoo() 还是其他更好的方法名?或者应该将其拆分为两个方法?


2
为什么不选择AddFoo或CreateFoo?这个方法将会创建一个新的Foo(除非它已经存在)。 - Antonio Rodríguez
21个回答

59
在大多数情况下,简单的 GetFoo 就足够了,因为调用者不需要知道你正在创建和缓存它。这就是封装的全部意义。
但在某些情况下,创建是一个昂贵的操作,所以知道你可能会按需创建一些东西,并且在某些情况下它会很慢是很有用的。在这种情况下,使用不同的命名约定可以使调用者更清楚地理解。 GetOrCreate()Get(Options.CreateIfMissing) 是对调用者的很好提示。
(当然,应该在文档中注明这种行为,但最好使用一种方法名称,在读取代码时就提醒人们注意副作用,而无需为每个被调用的方法打开并阅读文档)
我发现这种情况最常见的是(例如)在查找树节点(例如在XML文档中),您可能会有 CreateNode(创建节点而不将其添加到树中)和 AddNode(将现有节点添加到树中)。在这种情况下,“如果节点不存在,则添加一个节点”的操作需要使用不同的、具有描述性的名称来区分它并清晰地表达其目的,因此我会使用类似于 EnsureNodeExists 的东西来加以区分。

通常你会使用一个唯一的键来调用 get 方法。但在这种情况下,你可能不是在寻找特定的键,而是要查找某些列的特定值,因此可以使用 getFooByWhatever 方法(当然实际上不会使用 whatever)。 - Martijn
2
我喜欢“CreateIfMissing”这个词。不错! - lindon fox

19

Getsert 如何?从 getinsert ,既然 update 或者 insertUpsert

虽然我还没有看到任何流行的框架使用这个术语,但它符合 @Jason Williams 指出的思想:

  • 对用户来说应该很清楚它不仅仅是一个普通的 get
  • 您不必去文档中查看它的作用
  • 易于学习和直观吗?(我不确定)

2
我认为GetFoo()不够清晰,因为它不告诉调用者如果对象不存在是否会得到一个空结果。所以Getsert会更加清晰明了。 - John K
2
我喜欢混成词的想法,但是“Getsert”让我想到了“get”+“assert”,这有不同的含义。 - c z
我自己也曾经创造过这个词,并一直在积极使用它,“upsert”和“getsert”几乎是完美的。 - j4hangir

18

单词obtainacquire似乎非常适合。特别是obtain

获得;通过努力或请求而得到、获得或取得:获得许可;获得更好的收入。

在您的情况下,可以说该方法的调用者获得了foo。


18

我知道这个问题已经很晚了,但是我能否提议将GrabFoo()作为创建新值并获取现有值的约定,以使其与GetFoo()区分开来?

查看“get”的同义词,我看到了几个适合的动词,有些已经常用作方法动词。例如,Fetch已经暗示着从外部系统中获取一些东西(例如数据库或网络)。

Grab似乎很少使用,并且可能带有一个(虽然弱的)语义:无论如何都要获取或创建它。


9
“Grab”这个词的意思是“获取”,它与“创建”没有任何内涵。 - Johnathan Barclay

8

我的偏好是GetFoo(),因为从调用者的角度来看,该操作是获取数据,并且缓存更多地是实现细节。


6

4

我会称其为GetFoo,因为调用者并不关心它是否会得到一个新的或已经创建的Foo - 它只是想要Get一个Foo


2

对于缓存,我会简单地称其为GetFoo()。缓存旨在充当数据源后面的门面,以便调用者可以轻松访问项目,而不必担心它们如何或不被加载。

我会称其为GetFoo,但文档指出,如果请求的对象不在缓存中,则缓存将加载它(可能会产生所有潜在的性能影响)。


2

Beget

以下是几个似乎适合的定义:

  • 使存在或发生; 生产
  • 引起或创建

这个词也可以分为你问题中的两个想法。

“一个获取或创建对象的好方法名是什么?”

Be = 创建

Get = 获取

此外,它非常简短。


另一种选择是Resolve

我从Autofac那里借用了这个单词,它使用Resolve方法来获取对象的实例,或者在需要时创建对象。


2

我使用Take而不是Get。原因如下:

  • take也有点像make
  • 在给定的上下文中,takeget具有相同的含义
  • take听起来比get更有力量,所以如果我无法get它,我就会直接take

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接