Is it OK for a factory method to return null?

前端 未结 4 1025
余生分开走
余生分开走 2021-02-12 03:39

I\'m wondering about best practice here. Is it good practice for a factory method to return null if it can\'t create anything? Here\'s an example:

ICommand comma         


        
相关标签:
4条回答
  • 2021-02-12 03:55

    It only makes sense to return Null if there's a reason why you would want the user to have to check for null every time he calls Create. Normally you'd consider the following a perfectly valid use pattern:

    var obj = MyFactory.CreateThing();
    obj.DoSomething();
    

    But what you're proposing is to force the following usage pattern:

    var obj = MyFactory.CreateThing();
    if (obj == Null) {
        // Handle null condition
    } else {
        obj.DoSomething();
    }
    

    Normally the Null scenario would mean some sort of failure, in which case an Exception would probably make the most sense. But ultimately you're the music maker here and have to decide what is sensible in the world you're building.

    0 讨论(0)
  • 2021-02-12 04:01

    I agree with Jon Skeet. CreateCommand clearly implies construction.

    If you won't throw an Exception, then in that scenario I would personally go with the NullCommand implementation, to avoid conditional statements in all consumers and possible NullReferenceException errors.

    0 讨论(0)
  • 2021-02-12 04:02

    I think it's potentially reasonable for a factory method to return null in some situations, but not if it's a method called CreateCommand. If it were GetCommand or FetchCommand, that might be okay... but a Create method should throw an exception on failure, I would suggest.

    Whether you really want it to return null in this situation depends on the bigger picture, of course. (Is there a reasonable null object implementation you could return instead, for example?)

    0 讨论(0)
  • 2021-02-12 04:09

    Returning null in this case will make your method harder to use; clients have to be aware of an implicit failure condition. Instead, throw an exception, and you can also provide a separate method for clients to test for this condition:

    if (CommandFactory.CanCreate(args)) {
      ICommand command = CommandFactory.Create(args);
      command.Execute();
    }
    

    Or make the factory instantiatable; which would be better if you need to pre-process args:

    CommandFactory factory = new CommandFactory(args);
    if (factory.IsValid()) {
      ICommand command = factory.Create();
      command.Execute();
    }
    

    The interface of the factory now makes it clear and explicit that creation might fail, but it still requires the client to use the checking method. Another option is this:

    ICommand command;
    if (CommandFactory.TryCreate(args, out command)) {
      // creation succeeded ...
    }
    
    0 讨论(0)
提交回复
热议问题