2012-06-20 27 views
26

Me pregunto acerca de las mejores prácticas aquí. ¿Es una buena práctica que un método de fábrica devuelva nulo si no puede crear nada? He aquí un ejemplo:¿Está bien que un método de fábrica devuelva nulo?

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

Una alternativa sería la de devolver un NullCommand algo o, supongo, pero ¿cuál es la mejor práctica?

Respuesta

31

Creo que es potencialmente razonable que un método de fábrica devuelva nulo en algunas situaciones, pero no si es un método llamado CreateCommand. Si fuera GetCommand o FetchCommand, podría estar bien ... pero un método Create arrojaría una excepción en caso de falla, sugeriría.

Si realmente lo quiere devolver null en esta situación, depende de la imagen más grande, por supuesto. (¿Hay alguna implementación de objeto nulo razonable que podría devolver, por ejemplo?)

+0

De acuerdo con @Jon Skeet. Crear implica constructor, y no espera un nulo de uno de ellos, por lo que es poco probable que verifique si eso fue lo que hizo. –

+0

@TonyHopkinson: Por otro lado, tampoco esperarías una Excepción de un constructor. –

+6

@TimSchmelter: ¿Por qué no? Me gustaría * absolutamente * esperar una excepción de los constructores en ciertas situaciones - 'FileStream' es un ejemplo clásico ...o cualquier cosa con parámetros que pueden ser inválidos en cualquier forma, p. dando una referencia nula a algo que espera una referencia no nula. –

1

Estoy de acuerdo con Jon Skeet. CreateCommand claramente implica construcción.

Si no va a lanzar un Exception, entonces en ese caso yo personalmente iría con la implementación NullCommand, para evitar declaraciones condicionales en todos los consumidores y posibles errores NullReferenceException.

3

De vuelta null en este caso hará que su método sea más difícil de usar; los clientes deben conocer una condición de falla implícita. En su lugar, una excepción, y también se puede proporcionar un método separado para los clientes a probar esta situación:

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

o hacer que la instantiatable fábrica; ¿Qué sería mejor si necesita pre-proceso de args:

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

La interfaz de la fábrica hace que ahora sea clara y explícita que la creación puede fallar, pero todavía requiere que el cliente utilice el método de comprobación. Otra opción es la siguiente:

ICommand command; 
if (CommandFactory.TryCreate(args, out command)) { 
    // creation succeeded ... 
} 
+0

_ "posiblemente fallará si no comprueban null" _ Dado que C# no admite excepciones comprobadas (a diferencia de java), los clientes también pueden fallar si no manejan esa excepción, por lo que ese no es un argumento fuerte (imho) . –

+1

@TimSchmelter: Revisé mi redacción sobre esa frase ... Espero que mi punto de vista sea más claro ahora. –

0

que sólo tiene sentido para devolver null si no hay una razón por la que usted desee al usuario a tener que comprobar la nula cada vez que llama a crear. Lo normal sería en cuenta lo siguiente un patrón de uso perfectamente válido:

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

Pero lo que estás proponiendo es forzar el siguiente patrón de uso:

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

Normalmente el nulo escenario significaría alguna tipo de falla, en cuyo caso una Excepción probablemente tendría más sentido. Pero finalmente eres el creador de la música aquí y tienes que decidir qué es sensato en el mundo que estás construyendo.

Cuestiones relacionadas