Entonces tengo una fábrica que crea objetos de diferentes clases. Las posibles clases se derivan de un antepasado abstracto. La fábrica tiene un archivo de configuración (sintaxis JSON) y decide qué clase crear, según la configuración del usuario.
Para lograr esto, la fábrica utiliza boost :: property_tree para el análisis JSON. Camina por la calle y decide qué objeto concreto crear.
Sin embargo, los objetos del producto tienen muchos campos (atributos). Dependiendo de la clase concreta, el objeto tiene unos 5-10 atributos, en el futuro tal vez incluso más.
Así que no estoy seguro de cómo debería ser el constructor de los objetos. Se me ocurren dos soluciones:
1) El constructor del producto espera cada atributo como parámetro, por lo tanto, el constructor terminará con más de 10 parámetros. Esto será feo y dará lugar a líneas de código largas e ilegibles. Sin embargo, la ventaja es que la fábrica puede analizar el JSON e invocar al constructor con los parámetros correctos. La clase de producto no necesita saber que se ha creado debido a la configuración de JSON. No necesita saber que hay JSON o configuración involucrada en absoluto.
2) El constructor del producto solo espera un argumento, el objeto property_tree. Entonces puede analizar la información necesaria. Si falta información de la configuración o está fuera de los límites, cada clase de producto puede reaccionar correctamente. La fábrica no necesita saber qué argumentos necesitan los diversos productos. La fábrica tampoco necesita saber cómo reaccionar en caso de una configuración incorrecta. Y la interfaz del constructor es unificada y pequeña. Pero, como desventaja, el producto necesita extraer la información necesaria del JSON, por lo tanto, sabe cómo se construye.
Tiendo a preferir la solución 2). Sin embargo, no estoy seguro de si este es un buen patrón de fábrica. De alguna manera se siente mal dejar que el producto sepa que está creado con la configuración JSON. Por otro lado, se pueden introducir nuevos productos de forma muy sencilla.
¿Alguna opinión sobre eso?
Respuestas:
No haría la opción 2, porque entonces has enredado para siempre la construcción de tu objeto con el análisis del árbol de propiedades de impulso. Si se siente cómodo con una clase que necesita tantos parámetros, debería sentirse cómodo con un constructor que necesita tantos parámetros, ¡así es la vida!
Si su principal preocupación es la legibilidad del código, puede usar el patrón de construcción, es básicamente el c ++ / java stopgap por falta de argumentos con nombre. Terminas con cosas que se ven así:
Así que ahora MyObject tendrá un constructor privado, que se llama en Builder :: build. Lo bueno es que ese será el único lugar donde tendrá que llamar a un constructor con 10 parámetros. La fábrica de árbol de propiedades de impulso usará el constructor y, posteriormente, si desea construir un MyObject directamente o desde una fuente diferente, pasará por el constructor. Y el generador básicamente le permite nombrar claramente cada parámetro a medida que lo pasa, por lo que es más legible. Obviamente, esto agrega algo de repetitivo, por lo que tendrá que decidir si vale la pena en comparación con solo llamar al constructor desordenado o agrupar algunos de sus parámetros existentes en estructuras, etc. Simplemente arrojando otra opción sobre la mesa.
https://en.wikipedia.org/wiki/Builder_pattern#C.2B.2B_Example
fuente
NO use el segundo enfoque.
Definitivamente no es la solución y solo conduciría a crear instancias de clases en la lógica de su negocio, en lugar de la parte de su aplicación donde están las fábricas.
Ya sea:
A menos que el objeto que está creando sea en realidad una clase responsable de mantener los datos, debe intentar refactorizar el código y dividir la clase grande en otras más pequeñas.
fuente
new
o construir objetos dentro de su lógica comercial, no es un diseño muy bueno. Marque la charla No buscar cosas de Miško Hevery , quien explica con más profundidad por qué el enfoque de fábrica que usted insinuó es malo tanto desde el punto de vista de la prueba como de la lectura. Además, su clase parece ser un objeto de datos, y para aquellos generalmente está bien tener más parámetros que la clase de servicio regular. No me molestaría demasiado.La opción 2 es casi correcta.
Una opción mejorada 2
Cree una clase "frontal" cuyo trabajo es tomar ese objeto de estructura JSON y seleccionar los bits y llamar a los constructores de fábrica. Toma lo que hace la fábrica y se lo da al cliente.
Básicamente, el "front-end" está diciendo a los 2 Bobs: "¡Trato con los clientes redactados para que los ingenieros no tengan que hacerlo! ¡Tengo habilidades con la gente!" Pobre Tom. Si solo hubiera dicho "desacople al cliente de la construcción. Este resultado es una fábrica altamente cohesionada"; él podría haber mantenido su trabajo.
¿Demasiados argumentos?
No es para el cliente: comunicación frontal.
Front end - fábrica? Si no hay 10 parámetros, lo mejor que puede hacer es posponer el desempaquetado, si no es lo JSON original, algo de DTO. ¿Es esto mejor que pasar el JSON a la fábrica? La misma diferencia que digo.
Consideraría fuertemente pasar parámetros individuales. Apéguese al objetivo de una fábrica limpia y cohesiva. Evite las preocupaciones de la respuesta de @DavidPacker.
Mitigar "demasiados argumentos"
Constructores de fábrica o clase
Agrupación de argumentos frontales
fuente