¿Existe un patrón de diseño para gestionar relaciones profundas de muchos a muchos?

10

Tengo problemas para definir este patrón de datos que he encontrado trabajando en varias aplicaciones.

Consiste en:

  1. Un tipo de objeto que se compone de muchos objetos.
  2. Un segundo tipo de objeto, donde cada instancia 'tiene muchos' del primer objeto
  3. Y, cada uno de los subobjetos del primer objeto es modificable por cada asociación al segundo tipo de objeto.

Un ejemplo simple podría ser:

  1. Un curso de programación que consta de un conjunto de lecciones.
  2. Las lecciones se componen de un conjunto de tareas.
  3. Se puede asignar un curso a un estudiante.
  4. Sin embargo, una vez que se asigna un curso a un alumno, cada lección y / o tarea se puede personalizar para ese alumno, con eliminaciones y adiciones, hasta el punto en que el curso original puede ser irreconocible.

En mis soluciones, esto resulta en:

Al asignar un curso a un estudiante, el curso se carga en la memoria. Luego, para cada subobjeto, se genera un objeto de relación estudiante / subobjeto con los metadatos apropiados. Básicamente, estoy usando el objeto original como plantilla para generar los objetos personalizables necesarios.

Esto da como resultado una gran cantidad de datos a medida que los subobjetos se vuelven más complejos y numerados. Me pregunto si hay alguna optimización o patrón para reducir la cantidad de lógica / complejidad requerida para manipular este patrón de datos.

Nicholas Pickering
fuente
2
¿Estás seguro de que deseas "reducir la cantidad de datos"? ¿Está buscando formas de "reducir la cantidad de código y lógica no triviales" que deben escribirse para implementar el comportamiento requerido? (Noto que la gestión continua de los datos requiere una estructura de datos relacionales, similar a una base de datos)
Rwong
@rwong Sí, mi objetivo final es "reducir la cantidad de código y lógica no triviales". Para mí, eso significa reducir la complejidad de los datos de alguna manera, pero eso no es necesariamente un requisito. Se ha convertido en un patrón de datos tan común que me pregunto si hay alguna forma más sencilla de administrarlo.
Nicholas Pickering
1
En principio, esta es una versión mejorada de una relación m: n. ¿Qué pasa con un título como "Cómo gestionar relaciones complejas de objetos"?
Thomas Junk
1
Una gran cantidad de datos no es lo mismo que un gran nivel de complejidad en los datos. La dificultad para administrar lo que está construyendo probablemente aumentará con la complejidad más que con el volumen.
Walter Mitty
1
Interesante. He trabajado en varias aplicaciones que tienen este patrón, pero nunca antes lo vi, es un patrón. También me encantaría ver formas más simples de administrar este tipo de datos.
Jules

Respuestas:

6

Veo algunas opciones dependiendo de lo que necesite: (1) si hay muchas instancias únicas que siguen un algoritmo común, (2) si hay muchos objetos similares o generará objetos en tiempo de ejecución, y (3) si desea modificar dinámicamente el comportamiento del objeto mientras se ejecuta. Nota: puede combinar todos los patrones que menciono aquí, si es necesario.

  1. Si cada "segundo tipo de objeto" es único pero sigue un patrón de comportamiento similar, puede usar el Patrón de plantilla . Parece que puedes estar haciendo esto. Pero para hacerlo explícito, su clase abstracta y base tiene un algoritmo general programado; ciertos pasos de este algoritmo se implementan en las clases derivadas.

  2. Si va a crear muchos objetos o si crear objetos en tiempo de ejecución es importante para usted, puede usar el Patrón de fábrica .

  3. Y si desea cambiar dinámicamente el comportamiento, Stategy Pattern podría funcionar. Por ejemplo, si un estudiante en un plan de estudios regular se decide que tiene necesidades especiales o que va a un programa acelerado. Esto funciona al componer el "alumno" de un objeto que representaría una clase base del plan de estudios. El plan de estudios se asignaría a un plan de estudios derivado en la construcción del estudiante (eso suena extraño) y podría reasignarse a otro plan de estudios derivado más adelante.

(Solo para su información, si usa (3) Patrón de estrategia con C ++, tendrá que hacer Rvalues ​​para la composición).

Para almacenar sus objetos y segundos objetos, puede valer la pena considerar Iterator Pattern (para recorrerlos, agregarlos, eliminarlos, ordenarlos, etc.).

Una buena referencia es Head First Design Patterns , que cubre los patrones que menciono y su implementación. Trabajan en Java.

audrow
fuente
0

Me resulta difícil creer, bajo la presencia de un almacén de datos o persistencia, que necesitaría tener objetos con este tipo de profundidad en cualquier punto dado en un tiempo de ejecución. ¿Es esto para CRUD GUI? Si es así, sugeriría cambiar su enfoque desde el principio. ES DECIR:

Identifique la subestructura necesaria para que el Alumno la muestre y almacene con estado su índice de origen nuevamente en la base de datos, y actualícela sin estado , yendo hacia o desde la vista y la base de datos db.

John P. Feltz
fuente
No estoy seguro de entender tu sugerencia. ¿Debería generar un subobjeto vacío y luego forzar al usuario a otra forma que le permita modificar el subobjeto?
Nicholas Pickering
Estoy sugiriendo que los objetos en sí mismos no logran mucho, si todo lo que está haciendo es una transacción sin estado entre su contenido y una base de datos de fondo. Si este es el caso, elimínelos y simplemente realice la transacción para los datos específicos de lo que enfrenta el cliente.
John P. Feltz
Editar: Esto también puede significar crear objetos para capturar esa información particular que se está transaccionando, si está sesgado a ORM debido a su conveniencia a ese respecto.
John P. Feltz
A menos que esté malinterpretando el, no creo que nada sobre el proceso pueda hacerse apátrida. Todo depende del contexto de la acción del usuario. Cuando un usuario crea un objeto primario, espera que la subestructura esté disponible para modificar de inmediato.
Nicholas Pickering
-1

Un curso personalizado para cada estudiante hasta el punto en que el curso original sea irreconocible sugiere que el curso original es simplemente una referencia "predeterminada". Lo que haría es crear una clase llamada CustomizedCourse (o una lista de ellos) y tener eso (o una lista de eso) como propiedad de un estudiante. El CustomizedCourse puede tener una referencia al curso original para el uso "referencial", pero el trabajo principal y los datos estarían en el CustomizedCourse.

frezq
fuente
downvoter cuidado de comentar?
Frezq
No voté en contra (soy el OP), pero parece que estás tratando de describir la Plantilla o el Patrón de Estrategia que ya se describieron en otra respuesta.
Nicholas Pickering