【问题标题】:How to name factory like methods?如何命名类似工厂的方法?
【发布时间】:2011-03-23 01:57:21
【问题描述】:

我猜大多数类似工厂的方法都是以create 开头的。但是为什么它们被称为“create”呢?为什么不使用“make”、“produce”、“build”、“generate”或别的什么?仅仅是口味问题吗?大会?还是“创造”有什么特殊含义?

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

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

【问题讨论】:

  • 我曾经参与过一个将工厂方法命名为“get()”的项目。一开始很混乱。
  • 最后一个选项,没有前缀怎么样?由于我们几乎总是在静态上下文中使用工厂,这不是很清楚吗?只是要求激发一些讨论-我个人的偏好是createXyz()
  • @vikingsteve 在我构建的系统中,我使用create 前缀作为惯例,以保证 API 一致性,也因为只需键入字母 @987654330 @ 会使它们全部显示在 IDE 的自动完成中,这将使尝试了解可用内容的人更容易。我本来可以找到Matrix4f.identity()Matrix4f.transpose() 等,但找到Matrix4f.createIdentity()Matrix4f.createTranspose(...) 等会更快。

标签: coding-style naming-conventions methods factory


【解决方案1】:

一些随意的想法:

  • 'Create' 比大多数其他词更适合该功能。我能想到的下一个最好的词是“构造”。过去,'Alloc'(分配)可能在类似情况下使用过,这反映了在 C 等语言中比对象更强调数据块。

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

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

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

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

  • 'Produce'、'Generate'、'Construct' 的键入/读取时间比 'Create' 长。从历史上看,程序员倾向于使用短名称来减少打字/阅读。

【讨论】:

  • 为“创建”点赞
【解决方案2】:

Joshua Bloch in "Effective Java" suggests the following naming conventions

valueOf — 返回一个具有相同值的实例 作为它的参数。这样的静态工厂是有效的 类型转换方法。

ofvalueOf 的简洁替代品,由 EnumSet 推广(第 32 条)。

getInstance — 返回由参数描述的实例 但不能说具有相同的价值。在单例的情况下, getInstance 不带参数并返回唯一的实例。

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

getType — 类似于 getInstance,但在工厂方法位于 不同的班级。 Type 表示返回的对象的类型 工厂方法。

newType — 类似于 newInstance,但在工厂方法位于 不同的班级。 Type 表示返回的对象的类型 工厂方法。

【讨论】:

  • 您如何评价from?例如。假设Id.of("abc") vs Id.from("xyz") ...或者from会建议更多的逻辑发生(即解析输入,从/与其他数据查找/相关,......)?搜索“of vs from”真的很难:D
【解决方案3】:

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

  1. 虽然传统上“工厂”的意思是“创建对象”,但我更愿意将其理解为“返回给我一个行为符合我预期的对象”。我不应该总是知道它是否是一个全新的对象,事实上我可能不在乎。因此,在合适的情况下,您可能会避免使用“创建...”名称,即使您现在就是这样实现的。

  2. Guava 是一个很好的工厂命名思想库。它正在普及一种不错的 DSL 风格。例子:

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

【讨论】:

  • 你说得对,Guava 是一个很棒的库,代码可读性很强。
【解决方案4】:

“Create”和“make”很短,很容易让人联想到,并且与我能想到的其他命名模式无关。我也经常看到它们,并怀疑它们可能是“事实上的标准”。我会选择一个并至少在一个项目中始终如一地使用它。 (看我自己目前的项目,好像用的是“make”,希望我是一致的……)

避免“构建”,因为它更符合 Builder 模式,避免“生产”,因为它唤起了生产者/消费者。

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

【讨论】:

    【解决方案5】:

    我认为它源于“创建一个对象”。然而,在英语中,“创造”一词与“导致形成,作为一种不会自然进化或不是由普通过程制成的独特事物”和“从一个人自己的思想或想象力,作为一件艺术品或一项发明。”因此,“创造”似乎不是适合使用的词。另一方面,“制造”的意思是“通过塑造或改变材料、组合零件等来实现”。例如,你不创造一件衣服,你制作一件衣服(对象)。所以,在我看来,“制造”的意思是“生产”;导致存在或发生; “带来”对于工厂方法来说是一个更好的词。

    【讨论】:

      【解决方案6】:

      部分约定,部分语义。

      工厂方法(由传统的create 表示)应该调用适当的构造函数。如果我看到buildURI,我会假设它涉及到一些计算,或者从零件组装(我不认为有工厂参与)。当我看到generateURI 时,我想到的第一件事就是随机制作一些东西,比如一个新的个性化下载链接。它们并不完全相同,不同的词引起不同的含义;但它们中的大多数都不是常规的。

      【讨论】:

        【解决方案7】:

        我喜欢新的。对我来说

        var foo = newFoo();
        

        比阅读更好

        var foo = createFoo();
        

        翻译成英文我们有 foo 是一个新的 foo 或者 foo 是创建 foo。虽然我不是语法专家,但我很确定后者在语法上是不正确的。

        【讨论】:

        • 它们都有效。 createFoo 是一个函数。正如你所说,foo 不是createFoofoocreateFoo() 的结果。
        【解决方案8】:

        我称之为 UriFactory.Create()

        在哪里,

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

        并且Create() 方法被重载了,因为您的规范中有尽可能多的变体。

        public static class UriFactory
        {
            //Default Creator
            public static UriType Create() 
            {
            }
        
            //An overload for Create()
            public static UriType Create(someArgs) 
            {
            }
        }
        

        【讨论】:

        • 虽然我同意您的命名,但我强烈不同意您使用 Pascal 大小写方法名称的约定。
        • @Leviathlon 它始终取决于编程语言和内部约定。 Pascal Case 完全适用于 C# 等语言。
        • @momo 没错,我想我已经假设所讨论的语言是 Java。
        • @BuğraEkuklu 你抱怨 Pascal 案例真是太有趣了,因为这正是你在 Delphi 中调用普通构造函数(而不是工厂)的方式。它们通常按惯例称为创建。另外,AFAIK 这里的代码可能是有效的 C#。
        【解决方案9】:

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

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

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

        【讨论】:

          【解决方案10】:

          就我个人而言,我喜欢 instantiateinstantiateWith,但这只是因为我的 Unity 和 Objective C 经验。 Unity引擎内部的命名约定似乎围绕着instantiate这个词来通过工厂方法创建一个实例,而Objective C似乎喜欢with来指示参数是什么。这只有在方法位于将要被实例化的类中时才真正有效(并且在允许构造函数重载的语言中,这并不是什么“事情”)。

          只是简单的旧 Objective C 的 initWith 也是一个好'un!

          【讨论】:

            【解决方案11】:

            工厂方法不指定方法名称。您可以在您的工厂中拥有任意数量的方法,前提是它们都返回来自同一个系列的对象。

            更多详情,请访问网址 http://xeon2k.wordpress.com

            【讨论】:

            • 链接没有意义,应该更具体。
            猜你喜欢
            • 2021-04-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多