Dan*_*ein 47 constructor design-patterns coding-style
在两者都可用的语言中,您更愿意看到实例构造函数或返回实例的静态方法吗?
例如,如果您要创建String
一个char[]
:
String.FromCharacters(chars);
new String(chars);
Jon*_*eet 55
在Effective Java,第2版中,Joshua Bloch肯定会推荐前者.我记得有几个原因,无疑我不能:
缺点:
Rob*_*ney 22
我在创建实例时没有副作用编写构造函数,即构造函数正在做的唯一事情就是初始化属性.我编写一个静态方法(并使构造函数成为私有),如果创建实例做了一些你通常不希望构造函数做的事情.
例如:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
因为我坚持这个惯例,如果我看到
Foo f = Foo.CreateFoo();
Bar b = new Bar();
Run Code Online (Sandbox Code Playgroud)
在阅读我的代码时,我对这两行中的每一行都有着截然不同的期望.那段代码并没有告诉我创建一个Foo与创建一个Bar有什么不同,但它告诉我我需要看一下.
MB.*_*MB. 10
我最近一直在研究一个公共API,我一直在为静态工厂方法与构造函数的选择而苦恼.静态工厂方法在某些情况下肯定是有意义的,但在其他情况下它并不是那么清楚,我不确定与API其余部分的一致性是否足以将它们包含在构造函数中.
无论如何,我从Bill-Venners采访Josh Bloch时得到了一个引用,我发现它很有用:
当你编写一个类时,你可以在我的书中列出静态工厂优于公共构造函数的优点.如果您发现在您的案例中实际应用了大量优势,那么您应该选择静态工厂.否则你应该去构造函数.
有些人对我的书中的建议感到失望.他们阅读并说:"你们对公共静态工厂如此强烈争论,我们应该默认使用它们." 我认为这样做的唯一真正缺点是,对于习惯使用构造函数创建对象的人来说,这有点令人不安.而且我认为它在程序中提供了一点点视觉提示.(您没有看到new关键字.)此外,在文档中找到静态工厂要困难得多,因为Javadoc将所有构造函数组合在一起.但我会说每个人都应该一直考虑静态工厂,并在适当的时候使用它们.
阅读了那篇引文,以及Uri提到的研究*,除非有令人信服的理由,否则我倾向于偏向于建设者.我认为没有正当理由的静态工厂方法可能只是不必要的复杂性和过度工程.虽然明天我可能会再次改变主意...
*不幸的是,这项研究更少关注静态工厂方法,而更多关注工厂模式(存在单独的工厂对象以创建新实例),因此我不确定是否可以得出静态工厂方法使许多程序员感到困惑的结论.虽然这项研究确实给我的印象是他们经常这样做.
ICSE'07的论文研究了构造函数与工厂模式的可用性.虽然我更喜欢工厂模式,但研究表明开发人员在寻找正确的工厂方法方面较慢.
http://www.cs.cmu.edu/~NatProg/papers/Ellis2007FactoryUsability.pdf