Existe um padrão de design para gerenciar relacionamentos profundos muitos para muitos?

10

Estou tendo problemas para definir esse padrão de dados que me deparei trabalhando em vários aplicativos.

Isso consiste de:

  1. Um tipo de objeto que é composto por muitos objetos em si
  2. Um segundo tipo de objeto, em que cada instância 'possui muitos' do primeiro objeto
  3. E cada um dos subobjetos do primeiro objeto é modificável por cada associação ao segundo tipo de objeto.

Um exemplo simples pode ser:

  1. Um curso de programação que consiste em um conjunto de lições
  2. As lições são compostas de um conjunto de atribuições.
  3. Um curso pode ser atribuído a um aluno.
  4. No entanto, uma vez que um curso é atribuído a um aluno, cada lição e / ou tarefa pode ser personalizada para ele, com remoções e acréscimos, até o ponto em que o curso original pode ser irreconhecível.

Nas minhas soluções, o que isso resulta é:

Na atribuição de um curso a um aluno, o curso é carregado na memória. Em seguida, para cada subobjeto, um objeto de relacionamento aluno / subobjeto é gerado com os metadados apropriados. Basicamente, estou usando o objeto original como modelo para gerar os objetos personalizáveis ​​necessários.

Isso resulta em uma enorme quantidade de dados à medida que os subobjetos se tornam mais complexos e numerados. Gostaria de saber se existe alguma otimização ou padrão para reduzir a quantidade de lógica / complexidade necessária para manipular esse padrão de dados.

Nicholas Pickering
fonte
2
Tem certeza de que deseja "reduzir a quantidade de dados"? Você está procurando maneiras de "reduzir a quantidade de código e lógica não triviais" que precisam ser gravados para implementar o comportamento necessário? (I perceber que o gerenciamento contínuo dos dados exige estrutura de dados relacional, semelhante a um banco de dados.)
rwong
@rwong Sim, "reduzir a quantidade de código e lógica não triviais" é meu objetivo final. Para mim, isso significa reduzir a complexidade dos dados de alguma forma, mas isso não é necessariamente um requisito. Tornou-se um padrão de dados tão comum que me pergunto se existe alguma maneira mais simples de gerenciá-lo.
Nicholas Pickering
1
Em princípio, esta é uma versão aprimorada de um relacionamento m: n. Que tal um título como »Como gerenciar relacionamentos complexos de objetos«?
Thomas Junk
1
Uma quantidade enorme de dados não é o mesmo que um nível enorme de complexidade nos dados. A dificuldade em gerenciar o que você está construindo provavelmente aumentará mais com a complexidade do que com o volume.
22615 Walter Mitty
1
Interessante. Eu trabalhei em vários aplicativos que têm esse padrão, mas nunca vi antes que seja um padrão. Também gostaria de ver maneiras mais simples de gerenciar esse tipo de dados.
Jules

Respostas:

6

Vejo algumas opções, dependendo do que você precisa: (1) se houver muitas instâncias únicas que seguem um algoritmo comum, (2) se houver muitos objetos semelhantes ou você irá gerar objetos em tempo de execução e (3) se você deseja modificar dinamicamente o comportamento do objeto durante a execução. Nota: você pode combinar todos os padrões mencionados aqui, se necessário.

  1. Se cada "segundo tipo de objeto" for único, mas seguir um padrão semelhante de comportamento, você poderá usar o Modelo Padrão . Parece que você pode estar fazendo isso. Mas, para torná-lo explícito, sua classe base abstrata tem um algoritmo geral programado; certas etapas desse algoritmo são implementadas nas classes derivadas.

  2. Se você criar muitos objetos ou se for importante criar objetos em tempo de execução, você poderá usar o Padrão de Fábrica .

  3. E se você deseja mudar dinamicamente o comportamento, o Stategy Pattern pode funcionar. Por exemplo, se um aluno em um currículo regular for decidido por necessidades especiais ou entrar em um programa acelerado. Isso funciona compondo o "aluno" de um objeto que representaria uma classe base do currículo. O currículo seria atribuído a um currículo derivado na construção do aluno (que soa estranho) e poderia ser transferido para outro currículo derivado posteriormente.

(Apenas para sua informação, se estiver usando (3) Strategy Pattern com C ++, você precisará fazer Rvalues ​​para composição.)

Para armazenar seus objetos e segundos objetos, pode valer a pena considerar o Padrão do Iterador (para percorrê-los, adicionar, excluir, classificar etc.).

Uma boa referência é o Head First Design Patterns , que abrange os padrões mencionados e sua implementação. Eles trabalham em Java.

audrow
fonte
0

Estou achando difícil acreditar, sob a presença de um armazenamento de dados ou persistência, que você precisaria ter objetos com esse tipo de profundidade a qualquer momento do tempo de execução. Isso é para CRUD GUI's? Nesse caso, sugiro alterar sua abordagem desde o início. IE:

Identificar a subestrutura necessária para que o aluno show, e statefully armazenar seu índice origem de volta para o db, e statelessly atualizar que, indo para ou a partir da vista eo db backend.

John P. Feltz
fonte
Não sei se entendi sua sugestão. Eu deveria gerar um subobjeto vazio e forçar o usuário a outro formulário que permita modificar o subobjeto?
Nicholas Pickering
Estou sugerindo que os objetos em si não realizam muito, se tudo o que você está fazendo é uma transação sem estado entre o conteúdo deles e um banco de dados back-end. Se for esse o caso, remova-os e apenas execute a transação para dados específicos do que o cliente enfrenta.
John P. Feltz
Editar: isso também pode significar criar objetos para capturar esses dados específicos que estão sendo transacionados - se você for influenciado pelo ORM devido à sua conveniência a esse respeito.
John P. Feltz
A menos que eu esteja entendendo errado, não acho que nada sobre o processo possa se tornar apátrida. Tudo depende do contexto da ação do usuário. Quando um usuário cria um objeto primário, ele espera que a subestrutura esteja disponível para modificação imediata.
Nicholas Pickering
-1

Um curso personalizado para cada aluno até o ponto em que o curso original é irreconhecível sugere que o curso original é simplesmente uma referência "padrão". O que eu faria é criar uma classe chamada CustomizedCourse (ou uma lista deles) e ter essa (ou uma lista disso) como propriedade de um aluno. O CustomizedCourse pode ter uma referência ao curso original para uso "referencial", mas o trabalho e os dados principais estariam no próprio CustomizedCourse.

frezq
fonte
downvoter gostaria de comentar?
frezq
Não diminuí a votação (eu sou o OP), mas parece que você está tentando descrever o modelo ou o padrão de estratégia que já foram descritos em outra resposta.
Nicholas Pickering