如何命名工厂之类的方法?


145

我猜想大多数类似工厂的方法都是以开头的create。但是为什么将它们称为“ 创建 ”?为什么不“ 制作 ”,“ 产生 ”,“ 建立 ”,“ 产生 ”或其他?只是口味问题吗?约定?还是“创建”中有特殊含义?

createURI(...) 
makeURI(...)
produceURI(...)
buildURI(...)
generateURI(...)

您一般会选择哪一个,为什么?


4
我曾经从事过一个将工厂方法命名为“ get()”的项目。起初非常令人困惑。
Muxecoid 2012年

4
最后一个选项,没有前缀怎么办?由于我们几乎总是在静态上下文中使用工厂,所以不是很清楚吗?只是想引起一些讨论-我个人的喜好是createXyz()
vikingsteve,2013年

@vikingsteve在我构建的系统中,create出于API 一致性的考虑,我将前缀用作惯例,还因为仅键入字母c会导致所有字母都显示在IDE的自动完成功能中,这将使其更容易对于试图了解可用内容的人。我可能已经有Matrix4f.identity()Matrix4f.transpose()等,但他们会更快地找到如Matrix4f.createIdentity()Matrix4f.createTranspose(...)
code_dredd

Answers:


117

一些随机的想法:

  • “创建”比大多数其他词更适合该功能。我能想到的第二个最好的词是“构造”。过去,“ Alloc”(分配)可能已在类似情况下使用,反映出比C之类的对象更强调数据块。

  • “创建”是一个简短的简单单词,具有明显的直观含义。在大多数情况下,人们可能只是希望将其作为想要创建某些东西时想到的第一个最明显的词。这是一种通用的命名约定,“对象创建”是描述...创建对象的过程的一种通用方式。

  • 'Construct'很接近,但是通常用于描述创建对象过程中的特定阶段(分配/新建,构造,初始化...)

  • “ Build”和“ Make”是与编译代码相关的过程的常用术语,因此对程序员而言具有不同的含义,这意味着该过程包含许多步骤,并且可能包含大量磁盘活动。但是,工厂“构建”某物的想法是一个明智的想法-尤其是在构建复杂的数据结构或以某种方式组合许多单独的信息的情况下。

  • “生成”对我来说意味着一种计算,该计算用于从输入生成值,例如生成哈希码或随机数。

  • “生产”,“生成”,“构造”的键入/读取时间比“创建”更长。从历史上看,程序员倾向于使用短名称来减少打字/阅读。


5
竖起大拇指“创建”
pimbrouwers

103

Joshua Bloch在“有效的Java”中提出了以下命名约定

valueOf —返回一个实例,从广义上讲,该实例与其参数具有相同的值。这种静态工厂是有效的类型转换方法。

of —的一种简洁替代方法valueOf,由EnumSet(Item 32)推广。

getInstance —返回一个实例,该实例由参数描述,但不能说具有相同的值。如果是单例, getInstance则不接受任何参数,并返回唯一的实例。

newInstance —类似getInstance,除了newInstance保证返回的每个实例都与其他实例不同。

get Type —类似getInstance,但在工厂方法位于其他类中时使用。类型表示工厂方法返回的对象的类型。

new Type —类似newInstance,但在工厂方法位于其他类中时使用。类型表示工厂方法返回的对象的类型。


您如何评价from?例如获取假设Id.of("abc")VS Id.from("xyz")...或将from暗示更多的逻辑发生(即输入的,查找/关系/与其他数据的解析,......)?搜索“ of vs from”真的很困难:D
knittl

22

想要补充我在其他答案中看不到的几点。

  1. 尽管从传统上讲,“工厂”的意思是“创建对象”,但我更喜欢将其更广泛地理解为“为我返回一个行为符合预期的对象”。我不必总是知道它是否是一个全新的对象,实际上我可能不在乎。因此,在合适的情况下,您可能会避免使用“创建...”名称,即使这是您现在正在实施的方式。

  2. 番石榴是工厂命名思想的良好仓库。它正在推广一种不错的DSL风格。例子:

    Lists.newArrayListWithCapacity(100);
    ImmutableList.of("Hello", "World");
    

1
没错,Guava是一个很棒的库,具有非常易读的代码。
迪蒙

11

“创建”和“制造”简短,合理,令人联想到我能想到的其他命名方式。我也经常看到它们,并且怀疑它们可能是“事实上的标准”。我会选择一个并且至少在项目中始终使用它。(看我自己当前的项目,我似乎使用了“ make”。我希望我能保持一致...)

避免使用“构建”,因为它更适合构建器模式,而避免使用“生产”,因为它会引起生产者/消费者。

为了真正延续模式的“工厂”名称的隐喻,我会被“制造”所吸引,但这句话太长了。


3

我认为这源于“ 创建对象”。但是,在英语中,“创造”一词与以下概念相关联:“使之成为事物,因为它不会自然地进化或不是由普通的过程所产生的,是一种独特的事物”,而“是根据自己的思想或想象力,作为艺术品或发明。” 因此,似乎“创建” 不是合适的词。另一方面,“制造”是指“通过对材料进行成形或更改,组合零件等来实现。” 例如,你不创造一件衣服,你一件衣服(对象)。因此,我认为,“制造”是指“生产;存在或发生的原因;“带来”一词对于工厂方法来说是一个更好的词。


3

我喜欢新的。对我来说

var foo = newFoo();

阅读比

var foo = createFoo();

翻译成英文,我们有foo是新foo或foo是create foo。虽然我不是语法专家,但我可以肯定后者在语法上是不正确的。


他们俩都工作。createFoo是一个功能。foo不是createFoo,正如您所说。foo是的结果createFoo()
克尔兹斯托夫·切尔兹尼亚克

2

部分约定,部分语义。

工厂方法(由传统方法表示create)应调用适当的构造函数。如果看到的话buildURI,我会认为它涉及到一些计算或零件的组装(而且我认为不会涉及工厂)。我看到的第一件事generateURI是随机进行一些操作,例如新的个性化下载链接。它们并不完全相同,不同的词具有不同的含义。但大多数都不是常规的。


1

我会称呼它 UriFactory.Create()

哪里,

UriFactory是类类型的名称,它提供创建Uri实例的方法。

Create()方法重载很多,你在你的规格有差异。

public static class UriFactory
{
    //Default Creator
    public static UriType Create() 
    {
    }

    //An overload for Create()
    public static UriType Create(someArgs) 
    {
    }
}

1
尽管我同意您的命名,但我非常不同意您使用Pascal大小写的方法名的约定。
Chatatata

2
@Leviathlon它始终取决于编程语言和内部约定。Pascal Case非常适合C#等语言。
momo

@momo确实,我认为我曾经假设要谈论的语言是Java。
Chatatata '19

0

我要指出的是,我已经看过所有动词,但在某些库或其他库中使用了产生动词,因此我不会将create称为通用约定。

现在,create听起来对我来说更好,唤起了动作的确切含义。

是的,这是(文学)品味的问题。


0

我个人喜欢instantiateinstantiateWith,但这只是因为我的Unity和Objective C经验。Unity引擎内部的命名约定似乎围绕单词instantiate来通过工厂方法创建实例,而目标C似乎希望with表明参数是什么。如果该方法位于将要实例化的类中,那么这才真的很好用(在允许构造函数重载的语言中,这并不是什么大问题)。

只是普通的旧目标C initWith也是一个好消息!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.