Recientemente estuve considerando que a veces varios objetos dependen unos de otros (por ejemplo, si contienen referencias cíclicas) y, por lo tanto, sería útil crearlos como parte de una operación atómica que asegure que, después de la construcción, los nuevos objetos cumplan alguna restricción colectiva .
Para hacer esto, uno podría tener constructores que puedan crear más de un objeto. El programador entonces pondría en un solo constructor todo el código asegurando que, una vez que los objetos o 1 , ..., o n hayan sido creados, satisfagan todas las restricciones requeridas (por ejemplo, todos los enlaces entre los nuevos objetos ya están en su lugar). He inventado el término constructores colectivos porque nunca he oído hablar de tal característica, pero bien podría existir un nombre aceptado para este concepto.
Entonces, ¿hay algún lenguaje de programación que soporte este tipo de constructores? Si no, ¿ya se ha probado la idea?
factory
patrón.A with B
composición de tipo de estilo compatible , cuyo constructor resultante esencialmente construiría el nuevo tipo compuesto por los dos rasgos.Respuestas:
Esto me suena como el Patrón de construcción , que es una forma más compleja de Fábrica. Un ejemplo de Java es un StringBuilder , que se usa para construir un String, luego se llama
builder.toString()
cuando se desea el resultado inmutable. Sin embargo, puede usar el patrón generador para construir colecciones de objetos no homogéneas más complejas. Puede usar lafriend
semántica en un generador para obtener acceso a variables privadas que se considerarían inmutables después de crear el objeto de resultado.Los lenguajes funcionales pueden proporcionar algo de inspiración. Scala, por ejemplo, tiene un ListBuffer mutable que puede usarse para la etapa de construcción y luego convertirse en una Lista inmutable .
Otro concepto posiblemente relevante es Freezable Objects , por el cual un objeto se considera mutable hasta
Freeze()
que se llama a un método. Un constructor podría usar los objetos no congelados y luego congelarlos antes de regresar.fuente
Ruby, Smalltalk, Self, Newspeak, etc. no tienen constructores, solo tienen una convención de nomenclatura para los métodos de fábrica (por ejemplo,
new
en Ruby). Como son simplemente métodos estándar como cualquier otro método, pueden hacer lo que quieran, incluso asignar e inicializar tantos objetos como quieran. El principal problema es que dichos métodos de fábrica devuelven, por convención, un único objeto que es una instancia de la clase a la que se llamó el método de fábrica. Es decir, cuando se llamaFoo.new
, se espera que recupere un solo objeto que es una instancia deFoo
. Pero, con suficiente documentación, podría devolver alguna estructura (por ejemplo, unaArray
) de múltiples objetos nuevos.Ejemplo:
En ECMAScript, los constructores son solo procedimientos regulares, o más bien, cualquier procedimiento puede usarse como un constructor simplemente pegando la
new
palabra clave frente a ella. Nuevamente, dado que son solo procedimientos regulares, pueden hacer lo que quieran.fuente
¿Dependencias cíclicas entre los objetos? Entonces la respuesta es "no use (solo) un constructor", porque las llamadas a métodos cíclicos no tienen ningún sentido. En cambio, este es un escenario clásico para algunos métodos Factory .
Aquí hay un ejemplo (en PHP) que es un poco tonto pero ilustra la idea general: no se puede crear un
Sprocket
sin un asociadoWidget
, y viceversa. Cada objeto tiene una referencia al otro cuando está disponible.Si tuviera que hacer esto en PHP 5.2 en la vida real, simplemente dejaría a los constructores públicos y le diría a la gente que no los use . En cambio, tendría una
makeWidgetWithSprocket()
función. Si el lenguaje fuera Java, usaría sus controles de visibilidad a nivel de paquete para evitar más errores.Lectura adicional:
create()
, considere el patrón Builder .fuente