Tengo un algoritmo que crea una colección de objetos. Estos objetos son mutables durante la creación, ya que comienzan con muy poco, pero luego se rellenan con datos en diferentes lugares dentro del algoritmo.
Una vez que se completa el algoritmo, los objetos nunca deben cambiarse; sin embargo, otras partes del software los consumen.
En estos escenarios, ¿se considera una buena práctica tener dos versiones de la clase, como se describe a continuación?
- El mutable es creado por el algoritmo, luego
- Al completar el algoritmo, los datos se copian en objetos inmutables que se devuelven.
Respuestas:
Quizás pueda usar el patrón de construcción . Utiliza un objeto 'constructor' separado con el propósito de recopilar los datos necesarios, y cuando se recopilan todos los datos, crea el objeto real. El objeto creado puede ser inmutable.
fuente
Una manera simple de lograr esto sería tener una interfaz que le permita a uno leer las propiedades y llamar solo a métodos de solo lectura y una clase que implemente esa interfaz que también le permite escribir esa clase.
Su método que lo crea, trata con el primero y luego devuelve el último proporcionando solo una interfaz de solo lectura para interactuar. Esto no requeriría copia y le permite ajustar fácilmente los comportamientos que desea que estén disponibles para la persona que llama en lugar del creador.
Toma este ejemplo:
La única desventaja de este enfoque es que uno simplemente podría lanzarlo a la clase implementadora. Si se tratara de una cuestión de seguridad, simplemente usar este enfoque es insuficiente. Una solución para esto es que puede crear una clase de fachada para ajustar la clase mutable, que simplemente presenta una interfaz con la que trabaja la persona que llama y no puede tener acceso al objeto interno.
De esta manera, ni siquiera el casting te ayudará. Ambos pueden derivar de la misma interfaz de solo lectura, pero la conversión del objeto devuelto solo le dará la clase Facade, que es inmutable ya que no cambia el estado subyacente de la clase mutable envuelta.
Vale la pena mencionar que esto no sigue la tendencia típica en la que un objeto inmutable se construye de una vez por todas a través de su constructor. Es comprensible que tenga que lidiar con muchos parámetros, pero debe preguntarse si todos estos parámetros deben definirse por adelantado o si algunos pueden introducirse más adelante. En ese caso, se debe usar un constructor simple con solo los parámetros requeridos. En otras palabras, no use este patrón si está ocultando otro problema en su programa.
fuente
Puede usar el patrón Builder como dice @JacquesB o, alternativamente, pensar por qué estos objetos tuyos tienen que ser mutables durante la creación.
En otras palabras, ¿por qué el proceso de crearlos tiene que extenderse en el tiempo, en lugar de pasar todos los valores requeridos al constructor y crear instancias de una vez?
Porque el generador podría ser una buena solución para el problema incorrecto.
Si el problema es que terminas con un constructor que tiene como 10 parámetros de largo, y deseas mitigarlo construyendo el objeto poco a poco, podría indicar que el diseño está en mal estado, y estos 10 valores deberían ser " ensacado "/ agrupado en unos pocos objetos ... o el objeto principal dividido en unos pocos más pequeños ...
En cuyo caso, mantén la inmutabilidad hasta el final, solo mejora el diseño.
fuente