工厂方法返回null是否可以?

时间:2012-06-20 17:03:56

标签: c# oop design-patterns factory-method

我想知道这里的最佳做法。如果工厂方法无法创建任何内容,那么返回null是一种好习惯吗?这是一个例子:

ICommand command = CommandFactory.CreateCommand(args);
if (command != null)
    command.Execute();
else
    // do something else if there is no command

另一种选择是返回NullCommand或其他东西,我猜,但最佳做法是什么?

4 个答案:

答案 0 :(得分:31)

我认为工厂方法在某些情况下返回null是合理的,但不是,如果它是一个名为CreateCommand的方法。如果它是GetCommandFetchCommand,那可能没问题......但我建议,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 场景意味着某种失败,在这种情况下,异常可能最有意义。但最终你是这里的音乐制作者,必须决定你正在构建的世界中哪些是明智的。