Me he encontrado pensando en esto hace bastante poco tiempo (de ahí la búsqueda de esta pregunta) y aunque no tengo una respuesta pensé en compartir mis pensamientos.
- constructores idealmente 'sólo debe establecer el estado del objeto, es decir: unos pocos:
this.member = member;
En mi opinión, esto juega muy bien con la COI, la herencia, la prueba y solo huele bien.
elevación pesada Sin embargo a veces es necesario así que lo que he estado tratando de hacer es:
- pase en el trabajo pesado.
Eso significa abstraer ese código de inicialización a otra clase y pasarlo. Esto suele ser posible si el trabajo pesado no es realmente responsabilidad de los objetos, por lo que esto realmente refactores a un código más agradable.
Si esto no es posible y necesita inicializar el estado de su clase antes del uso, agregue un método de inicialización.Esto le añade la dependencia temporal en el código, pero esto no es necesariamente algo malo, especialmente cuando se utilizan contenedores IoC:
Say CarEngine
requiere un DrivingAssistComputer
, y los DrivingAssistComputer
tiene que hacer la inicialización pesada, es decir, cargar todos los parámetros, los controles de la condición atmosférica, etc. Otra cosa a tener en cuenta es que CarEngine
no interactúa directamente con el DrivingAssistComputer
, solo necesita que esté presente, haciendo lo suyo en el costado. De hecho, es posible que el motor no funcione correctamente sin DrivingAssistComputer
haciendo lo suyo en el fondo (cambiando algún estado en algún lugar). Si estamos utilizando IoC entonces tenemos:
// Without initialise (i.e. initialisation done in computer constructor)
public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) {
this.injectors = injectors;
// No need to reference computer as we dont really interact with it.
}
...
Así que lo que tenemos aquí es un argumento del constructor marca computer
como una dependencia, pero en realidad no lo utilice. Así que esto es feo, pero vamos a añadir un método de iniciación:
public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) {
this.injectors = injectors;
// This ofcourse could also be moved to CarEngine.Initialse
computer.Initialise();
}
...
Aún no es una clase de cohesión, pero al menos sabemos que dependemos de ordenador, incluso cuando no estamos interactuando directamente con él fuera del constructor.
Otra opción por supuesto es tener un CarEngineFactory que hace:
CarEngine CreateEngine(FuelInjectors injectors) {
new DrivingAssistComputer().Initialise();
return new CarEngine(injectors);
}
...
Sin embargo, me parece fábricas y la COI acaba de confundir la matriz por lo que me gustaría ir por la segunda opción.
Me encantaría escuchar algunas ideas sobre esto.
Editar 1: Otra opción que omití anteriormente es tener el método Initialise pero mover esta invocación al módulo de inicialización de IoC. Entonces, la creación y la inicialización todavía están un tanto encapsuladas.
Bien puesto. En el pasado, también me he inclinado hacia el uso de los métodos 'initialize()' sobre los constructores cuando no se instanciaba directamente el objeto, como usar un patrón de fábrica. ¿Crees que esta es una consideración relevante? – Ray