我想知道这里的最佳做法。如果工厂方法无法创建任何内容,那么返回null是一种好习惯吗?这是一个例子:
ICommand command = CommandFactory.CreateCommand(args);
if (command != null)
command.Execute();
else
// do something else if there is no command
另一种选择是返回NullCommand
或其他东西,我猜,但最佳做法是什么?
答案 0 :(得分:31)
我认为工厂方法在某些情况下返回null是合理的,但不是,如果它是一个名为CreateCommand
的方法。如果它是GetCommand
或FetchCommand
,那可能没问题......但我建议,Create
方法应该在失败时抛出异常。
在这种情况下,真的是否希望它返回null
取决于更大的图景。 (例如,您是否可以返回合理的空对象实现?)
答案 1 :(得分:3)
在这种情况下返回null
将使您的方法更难使用;客户必须意识到隐含的失败情况。相反,抛出异常,您还可以为客户端提供单独的方法来测试这种情况:
if (CommandFactory.CanCreate(args)) {
ICommand command = CommandFactory.Create(args);
command.Execute();
}
或使工厂可以实例化;如果您需要预处理args
,那会更好:
CommandFactory factory = new CommandFactory(args);
if (factory.IsValid()) {
ICommand command = factory.Create();
command.Execute();
}
工厂的界面现在清楚明确地表明创建可能会失败,但仍然需要客户端使用检查方法。另一种选择是:
ICommand command;
if (CommandFactory.TryCreate(args, out command)) {
// creation succeeded ...
}
答案 2 :(得分:1)
我同意Jon Skeet。 CreateCommand
显然意味着建构。
如果你不抛出Exception
,那么在那种情况下我会亲自使用NullCommand
实现,以避免所有消费者的条件语句和可能的NullReferenceException
错误。< / p>
答案 3 :(得分:0)
如果有理由为希望用户每次调用Create时都必须检查null,那么返回Null才有意义。通常,您会认为以下是完全有效的使用模式:
var obj = MyFactory.CreateThing();
obj.DoSomething();
但你提议的是强制使用以下使用模式:
var obj = MyFactory.CreateThing();
if (obj == Null) {
// Handle null condition
} else {
obj.DoSomething();
}
通常, Null 场景意味着某种失败,在这种情况下,异常可能最有意义。但最终你是这里的音乐制作者,必须决定你正在构建的世界中哪些是明智的。