静态工厂方法与实例(正常)构造函数?[英] Static factory methods vs Instance (normal) constructors?

本文是小编为大家收集整理的关于静态工厂方法与实例(正常)构造函数?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在两者都有的语言中,您是否希望查看返回实例的实例构造函数或静态方法?

例如,如果您是从char[]创建String:

  1. String.FromCharacters(chars);

  2. new String(chars);

推荐答案

in 有效Java,第二版,约书亚·布洛赫(Joshua Bloch)当然建议前者.我记得有几个原因,毫无疑问,我不能记住:

  • 您可以给该方法一个有意义的名称.如果您有两种构造实例的方法,则使用了INT,但对该INT具有不同的含义,使用普通方法使调用代码更加可读.
  • 第一个推论 - 您可以使用具有相同参数列表的不同工厂方法
  • 您可以将null返回为"潜在的预期故障"案例,而构造函数将 emanse 返回值或投掷异常
  • 您可以返回已声明的类型(例如,返回派生类)
  • 您可以将其用作工厂,可能几次返回对同一对象的引用

缺点:

  • 目前不是愚蠢的 - 开发人员更习惯了"新"
  • 如果您看到"新"您知道您将获得一个新实例(Modulo https://stackoverflow.com/questions/questions/194484/whats-the-phats-ywhats-the-strangest - 我最近提到的奇数)
  • 您需要使适当的构造函数可用于子类
  • 在C#3中,构造函数调用能够以对象初始化器表达式以紧凑的方式设置字段/属性;该功能不适用于静态方法调用

其他推荐答案

i创建实例没有副作用时编写构造函数,即构造函数唯一做的是初始化属性.如果创建实例可以做一些您通常不会期望构造函数做的事情,我会编写静态方法(并使构造函数私有).

例如:

public class Foo
{
   private Foo() { }

   private static List<Foo> FooList = new List<Foo>();
   public static Foo CreateFoo()
   {
      Foo f = new Foo();
      FooList.Add(f);
      return f;
   }
}

,因为我遵守了这个约定,如果我看到

Foo f = Foo.CreateFoo();
Bar b = new Bar();

在阅读我的代码时,我对这两条行的每一行有一系列不同的期望.该代码并没有告诉我是什么使创建与创建栏不同,但它告诉我我需要看.

其他推荐答案

我最近一直在开发公共API,并且对静态工厂方法与构造函数的选择感到痛苦.静态工厂方法在某些情况下肯定是有意义的,但是在另一些情况下,这并不清楚,我不确定与其他API一致是否足以将它们包括在构造函数上.

无论如何,我遇到了一个在Bill-Venners采访Josh Bloch 中引用了报价我发现很有帮助:

当您写课时,您可以 删除我的书清单 静态工厂的优势 公共建筑商.如果您发现 其中大量 实际上适用于您的优点 案例,你应该去 静态工厂.否则你应该 使用构造函数.

有些人很失望地找到 我的书中的建议.他们读了 并说:"你争论得如此强烈 对于我们的公共静态工厂 默认情况下应该只使用它们. 认为唯一真正的劣势 这样做有点 与被使用的人感到不安 使用构造函数来创建他们的 对象.我想它提供了 少于视觉提示 程序. (您看不到新的 关键字.)还有更多 很难在 文档,因为Javadoc 将所有构造函数分组在一起. 但是我会说每个人都应该 考虑所有的静态工厂 时间,并在它们时使用它们 适当.

阅读了该报价和 uri提到的研究 *,除非有令人信服的理由去做,否则我倾向于犯错方面的构建器.我认为没有充分理由的静态工厂方法可能只是不必要的复杂性和过度工程.虽然我可能会在明天之前再次改变主意...

*不幸的是,这项研究的重点减少了静态工厂方法,而更多地关注工厂模式(存在单独的工厂对象来创建新实例),因此我不确定一个人能真正得出结论,即静态出厂方法使许多人感到困惑程序员.尽管这项研究确实给了我他们经常会的印象.

本文地址:https://www.itbaoku.cn/post/627582.html

问题描述

In a language where both are available, would you prefer to see an instance constructor or a static method that returns an instance?

For example, if you're creating a String from a char[]:

  1. String.FromCharacters(chars);

  2. new String(chars);

推荐答案

In Effective Java, 2nd edition, Joshua Bloch certainly recommends the former. There are a few reasons I can remember, and doubtless some I can't:

  • You can give the method a meaningful name. If you've got two ways of constructing an instance both of which take an int, but have different meanings for that int, using a normal method makes the calling code much more readable.
  • A corollary of the first - you can have different factory methods with the same parameter list
  • You can return null for "potentially expected failure" cases whereas a constructor will always either return a value or throw an exception
  • You can return a type other than the declared (e.g. return a derived class)
  • You can use it as a factory, to potentially return a reference to the same object several times

The downsides:

  • It's not as idiomatic, currently - developers are more used to seeing "new"
  • If you see "new" you know you're getting a new instance (modulo the oddity I mentioned recently)
  • You need to make appropriate constructors available for subclasses
  • In C# 3, constructor calls are able to set fields/properties in a compact manner with object initializer expressions; the feature doesn't apply to static method calls

其他推荐答案

I write a constructor when creating the instance has no side effects, i.e. when the only thing the constructor is doing is initializing properties. I write a static method (and make the constructor private) if creating the instance does something that you wouldn't ordinarily expect a constructor to do.

For example:

public class Foo
{
   private Foo() { }

   private static List<Foo> FooList = new List<Foo>();
   public static Foo CreateFoo()
   {
      Foo f = new Foo();
      FooList.Add(f);
      return f;
   }
}

Because I adhere to this convention, if I see

Foo f = Foo.CreateFoo();
Bar b = new Bar();

while reading my code, I have a very different set of expectations about what each of those two lines is doing. That code isn't telling me what it is that makes creating a Foo different from creating a Bar, but it's telling me that I need to look.

其他推荐答案

I've been working on a public API recently, and I've been agonizing over the choice of static factory methods versus constructor. Static factory methods definitely make sense in some instances, but in others it's not so clear and I'm uncertain whether consistency with the rest of the API is reason enough to include them over constructors.

Anyway, I came across a quote from a Bill-Venners interview with Josh Bloch that I found helpful:

When you are writing a class, you can run down the my book's list of the advantages of static factories over public constructors. If you find that a significant number of those advantages actually apply in your case, then you should go with the static factories. Otherwise you should go with the constructors.

Some people were disappointed to find that advice in my book. They read it and said, "You've argued so strongly for public static factories that we should just use them by default." I think the only real disadvantage in doing so is that it's a bit disconcerting to people who are used to using constructors to create their objects. And I suppose it provides a little less of a visual cue in the program. (You don't see the new keyword.) Also it's a little more difficult to find static factories in the documentation, because Javadoc groups all the constructors together. But I would say that everyone should consider static factories all the time, and use them when they are appropriate.

Having read that quote, and the study that Uri mentioned*, I'm feeling inclined to err in favour of constructors unless there are compelling reasons to do otherwise. I think a static factory method without good cause is probably just unnecessary complexity and over-engineering. Though I might well change my mind again by tomorrow...

*Unfortunately this study focused less on static factory methods and more on the factory pattern (where a separate factory object exists to create new instances), so I'm not sure one can really draw the conclusion that static factory methods confuse many programmers. Although the study did give me the impression that they often would.