当建模类时,首选的初始化方式是什么:

构造函数,或者 工厂方法

使用它们的考虑是什么?

在某些情况下,我更喜欢有一个工厂方法,如果对象不能被构造,它就返回null。这使得代码整洁。在采取替代操作之前,我可以简单地检查返回值是否不为空,而不是从构造函数抛出异常。(我个人不喜欢例外)

比如说,我在一个类上有一个构造函数,它需要一个id值。构造函数使用这个值从数据库填充类。如果指定id的记录不存在,构造函数抛出RecordNotFoundException异常。在这种情况下,我将不得不在一个try. catch块中包含所有此类类的构造。

与此相反,我可以在那些类上有一个静态工厂方法,如果没有找到记录将返回null。

在这种情况下,哪种方法更好,构造函数方法还是工厂方法?


当前回答

摘自Gamma、Helm、Johnson和Vlissides的《设计模式:可重用面向对象软件的元素》第108页。

使用工厂方法模式时

类不能预测它必须创建的对象的类 类希望它的子类指定它创建的对象 类将责任委托给几个助手子类中的一个,并且您希望本地化关于哪个助手子类是委托的知识

其他回答

除了“有效的java”(在另一个答案中提到),另一本经典书也建议:

首选静态工厂方法(具有描述参数的名称)而不是重载构造函数。

如。不要写

Complex complex = new Complex(23.0);

而是写

Complex complex = Complex.fromRealNumber(23.0);

这本书甚至建议将Complex(float)构造函数设为私有,以强制用户调用静态工厂方法。

只有在需要对对象创建进行额外控制时才使用工厂,这是构造函数无法做到的。

例如,工厂有缓存的可能性。

使用工厂的另一种方法是在不知道要构造的类型的情况下。你经常会在插件工厂场景中看到这种用法,每个插件都必须从一个基类派生出来,或者实现某种接口。工厂创建派生自基类或实现接口的类实例。

摘自《有效Java》第2版,第1项:考虑静态工厂方法而不是构造函数,第5页:

请注意,静态工厂方法与工厂方法模式是不同的 摘自设计模式[Gamma95, p. 107]。中描述的静态工厂方法 这个项目在设计模式中没有直接的对等物。”

比如说,我在一个类上有一个构造函数,它需要一个id值。构造函数使用这个值从数据库填充类。

这个过程肯定应该在构造函数之外。

构造函数不能访问数据库。 构造函数的任务和原因是初始化数据成员,并使用传递给构造函数的值建立类不变量。 对于其他事情,更好的方法是使用静态工厂方法,或者在更复杂的情况下使用单独的工厂或构建器类。

微软的一些构造函数指南:

在构造函数中做最少的工作。构造函数除了捕获构造函数参数之外不应该做太多工作。任何其他处理的费用应推迟到需要时。

And

如果所需操作的语义不能直接映射到新实例的构造,请考虑使用静态工厂方法而不是构造函数。

摘自Gamma、Helm、Johnson和Vlissides的《设计模式:可重用面向对象软件的元素》第108页。

使用工厂方法模式时

类不能预测它必须创建的对象的类 类希望它的子类指定它创建的对象 类将责任委托给几个助手子类中的一个,并且您希望本地化关于哪个助手子类是委托的知识