获取或创建对象的方法有什么好名字?

时间:2010-07-06 07:09:30

标签: naming-conventions

假设您有一个缓存,以及一个可以执行以下操作的方法:

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

你会怎么称呼这种方法? GetFoo()GetOrCreateFoo()或其他(还有更好的)?或者这应该分为两种方法吗?

19 个答案:

答案 0 :(得分:28)

在大多数情况下,简单的GetFoo就足够了,因为调用者不需要知道您正在创建和缓存它。这就是封装的全部内容。

但是,在某些情况下,创建是一项昂贵的操作,因此了解您可能正在按需创建某些内容并在某些情况下会很慢。在这种情况下,不同的命名约定使调用者更清楚。在这种情况下,GetOrCreate()或Get(Options.CreateIfMissing)是调用者的一个很好的提示。

(当然应该在文档中注明这种行为,但是最好使用一个方法名称来提醒人们在阅读代码时会产生副作用,而不必为每个方法调出和阅读文档。被称为)

我发现这种情况最常见的情况是(例如)在找到树节点时(例如在Xml文档中),您可能有“CreateNode”(创建节点而不将其添加到树中)和“AddNode”(将现有节点添加到树中)。在这种情况下,“添加节点(如果它尚不存在)”需要具有不同的描述性名称,因此我将使用类似“EnsureNodeExists”的内容来区分它并使目的明确。

答案 1 :(得分:17)

我知道我在这个问题上已经很晚了,但是我可以提出GrabFoo()作为get-or-create-if-missing的约定,以区别于GetFoo()吗?

查看synonyms of Get,我看到了几个合适的动词,其中一些已经常用作方法动词。例如,Fetch已经意味着从外部系统中获取内容。 (例如数据库或网络)

Grab似乎很少使用,可能带有I want you to get-or-create it, no matter what.

的语义(尽管很弱)

答案 2 :(得分:7)

Getsert怎么样?来自getinsert,因为updateinsertUpsert

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

  • 用户应该清楚它不会只是做正常的获取
  • 您不必去文档查看它的作用
  • 易于拾取和直观? (我不确定)

答案 3 :(得分:5)

我的偏好是GetFoo(),因为从调用者的角度来看,操作正在进行,而缓存更像是一个实现细节。

答案 4 :(得分:3)

我称之为GetFoo,理由是来电者并不关心是否会给予新的或已经创建的Foo - 它只想Get一个Foo

答案 5 :(得分:2)

对于缓存,我只需将其称为GetFoo()。缓存旨在充当数据源背后的外观,以便调用者可以轻松访问项目,而无需担心它们是如何加载或未加载。

我称之为GetFoo,但请记录如果请求的对象不在缓存中,缓存将加载它(以及可能产生的所有潜在性能影响)。

答案 6 :(得分:2)

如果您是参照透明或对象是单身,那么另一个选项是有意义的。

有时lazyGet调用实际上是懒惰的初始化。因此,您希望创建一个对象,如果已创建它,则返回对它的引用。在这种情况下,我会调用方法MyObject lazyGet() { } ,该方法也用于其他库,如javaslang's lazy

SELECT item_no, item_no1, item_no2, item_no3, item_no4, item_no5, item_no6,
       item_no7, item_no8, item_no9, style, vendor_code, pgc, buyer, brand,
       product_name, sheet_ID, revision, id
FROM product_sheets
WHERE item_no LIKE '$value' or item_no1 LIKE '$value' or
      item_no2 LIKE '$value' or item_no3 LIKE '$value' or
      item_no4 LIKE '$value' or item_no5 LIKE '$value' or 
      item_no6 LIKE '$value' or item_no7 LIKE '$value' or
      item_no8 LIKE '$value' or item_no9 LIKE '$value' AND
      revision IN (SELECT MAX(revision)
                   FROM product_sheets
                   GROUP BY sheet_ID
                  );

这在呼叫网站上有一个好处。如果您的呼叫在创建上下文中很昂贵,那么您的被叫方就会知道,可以使用急切初始化将呼叫费用转移到您计划的非关键部分。

P.S。:这也用于memoization,这是一种优化技术,您可以返回不可变数据结构的缓存对象。

答案 7 :(得分:2)

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

  

拥有;获得,获得或获得,通过   努力或要求:获得许可;获得更好的   收入。

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

答案 8 :(得分:1)

我只会像大多数人在这里提到的那样GetFoo()

原因是 - 该方法负责返回对象实例。这是它的主要责任。如果未创建对象,则创建将其放入缓存中的对象,然后将其返回。外部调用者,无需担心内部返回对象的方法,调用者只需在需要时调用GetFoo()。方法GetFoo()封装并隐藏了创建和缓存对象的复杂性。因此GetFoo()

答案 9 :(得分:1)

我知道这个话题有6年了。但是......我认为最好的名字是

getInstanceFoo()

getFooInstance()

就像单身人士一样。

答案 10 :(得分:1)

我使用Take代替Get。原因:

  • take听起来有点像make
  • take与给定上下文中的get含义相同
  • take听起来比get更有力,所以如果我不能get它,我只会take

答案 11 :(得分:1)

<强>招致

一些似乎合适的定义:

  • 导致存在或发生;产生
  • 创建或创建

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

  

获取创建的方法的名称是什么?   对象?“

Be =创建

Get = gets

加上它真的很短。

另一种选择是解决

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

答案 12 :(得分:1)

我建议使用 download(downloadUrl: string) { console.log(downloadUrl); this.fileTransfer.download(downloadUrl,this.file.dataDirectory +'test.pdf').then((entry) => { console.log('download complete: ' + entry.toURL()); }, (error) => { }); } 。我们已经在我们的团队中制定了这个惯例,我们对此感到很自在。

根据 Cambridge 定义:

<块引用>

获得:获得某物,尤其是通过索取、购买、为之工作或从其他事物中生产出来。

这正是我们所需要的。

答案 13 :(得分:0)

取决于对用户有意义的对象类型。

如果创建对用户不重要,那就是GetFoo;否则,称之为createOrGetFoo。

如果需要区分概念,您可能会使用GetFoo,CreateFoo和createOrGetFoo等方法。

我更喜欢根据您提供的信息将其命名为GetFoo。

答案 14 :(得分:0)

假设这个方法在cacheManager上,那么fetch(想要)[或得到(想要)取决于你的个人pref]就足够了 - 用API文档指示如果项目不存在则创建该项目。

通缉应该相应输入 - 因此方法名称中不需要Foo。

答案 15 :(得分:0)

我也称它为“getFoo()”,并在你的注释中添加如果Foo不存在时该函数的功能。

答案 16 :(得分:0)

类似于upsert(更新和插入),getsert与获取或插入并返回一样。

或发挥创意:

  • greate,如在获取或创建中一样

  • gadd,如获取或添加

答案 17 :(得分:0)

1.查找同义词(不好)

您可以尝试查找“get”的同义词。但是,您可能认为不使用“get”的 getter 可能意味着其他含义,但您并不确切知道它的作用。我会避免使用这种方法,因为最终它永远无法理解它的作用。

2.使用副词作为后缀(不好)

您可以通过确保您执行某事来添加指定 get-Method 的副词。像“getCreated”、“getSafe”、“getAssured”、“getEnsured”、“getInit”、“getInitialized”。这样就很容易理解它的吸气剂,但也会告诉你,它会发生其他事情。但是,您可能不知道名称是属性的一部分还是 get 的一部分。像“getSecureUrl”。所以我会避免为 get 使用后缀。

3.使用副词作为前缀(不好)

您也可以添加动词作为前缀,以说明您在做什么。像“secureGet”、“safeGet”、“initGet”……虽然这不会干扰属性,但你不知道它是一个 getter 还是其他什么东西在 getter 之前做了一些事情而没有实际得到一些东西。所以返回值可能是意外的。我也会避免这种方法。

4.使用描述您实际工作的词(也许)

与其说这是一个 get-Method,您还可以说我有一个初始化值的方法。它还返回一个值是对它的一个好处。类似的东西:

function initNameid($name) { ... }

这样你就知道你可以初始化一些东西,而不仅仅是得到一些东西。这样你就可以让你的 getter 保持干净和简单,而无需混合。但是,如果您正在搜索更标准的东西,您必须考虑一下,如果人们正在搜索 getter,他们可能找不到它。所以它可能也不是最好的。

5.用附加属性增强吸气剂(好)

你可以添加额外的属性,告诉用户 getter 做了更多的事情:

function getName($id, $create = false) { ... }

这样你就可以向 get 函数提供信息,如果布尔值为真,它应该尝试强制它的值。如果您使用合适的 IDE,它还会向您显示该争论的关键是“强制”、“创建”或类似的东西,因此您将始终知道它的作用。在预期方面,它可能是最干净的方法。

6.将初始化和 getter 结合起来,而不将它们组合起来(好)

问问自己,你为什么要结合它呢?当然,这是一条线,但是……你需要吗?一个接一个简单地做怎么样:

initName($name);
getNameId($name);

有时最好不要因为只有一行而混合某些东西。

7.你真的创造了一些东西还是简单地存储它?(好)

如果你只是存储一些类似的东西:

public static $name;
public static getName() {
if (!self::$name) $name = ...
  return self::$name;
}

如果一个 getter 也只是缓存了一些东西,就没有必要改变它的名字。它来了,完全没有问题。所以你不需要解决一个不存在的问题。

8.为什么你需要在一个动词中结合两种不同的含义?(好)

如果你用一个函数来获取或创建一些东西......这样命名它真的不好吗? “getCreate”或“getOrCreate”等并不像听起来那么糟糕。它的作用很明显。当然,它不是一个单一的动词,但你先做 A 或 B,然后是 A。那么,如果你能留在 AB 并且每个人都知道它的意思,你为什么要试图找到 C?问有没有东西也不错,但这是两个不同的东西,没有必要创造性和想新词。

答案 18 :(得分:-1)

如果此设计在您的应用程序中具有逻辑意义,那么我认为GetOrCreateFoo是一个合适的名称。

明确表达其目的的另一种方法是

GetFoo(bool createIfNotExists)

当然,如果我们真的在谈论缓存,那么实施方可能并不关心该项目是否刚刚创建。以上情况适用于调用者确实需要了解Foo的可能创建及其含义的情况(例如从文件系统或数据库中检索时,可能?)