¿Cómo puede saber si debe utilizar un Patrón compuesto o una Estructura de árbol, o una tercera implementación?

14

Tengo dos tipos de clientes, un tipo " Observador " y un tipo " Asunto ". Ambos están asociados con una jerarquía de grupos .

El observador recibirá datos (calendario) de los grupos a los que está asociado a través de las diferentes jerarquías. Estos datos se calculan combinando los datos de los grupos "principales" del grupo que intenta recopilar datos (cada grupo puede tener solo un principal ).

El sujeto podrá crear los datos (que recibirán los observadores) en los grupos a los que están asociados. Cuando los datos se crean en un grupo, todos los "hijos" del grupo también tendrán los datos, y podrán hacer su propia versión de un área específica de los datos , pero seguirán vinculados. a los datos originales creados (en mi implementación específica, los datos originales contendrán los períodos de tiempo y el titular, mientras que los subgrupos especifican el resto de los datos de los receptores directamente vinculados a sus respectivos grupos).

Sin embargo, cuando el sujeto crea datos, debe verificar si todos los observadores afectados tienen algún datos que entren en conflicto con esto, lo que significa una gran función recursiva, hasta donde puedo entender.

Así que creo que esto se puede resumir en el hecho de que necesito poder tener una jerarquía en la que puedes subir y bajar , y en algunos lugares ser capaz de tratarlos como un todo (recursión, básicamente).

Además, no solo apunto a una solución que funcione. Espero encontrar una solución que sea relativamente fácil de entender (al menos en cuanto a arquitectura) y que sea lo suficientemente flexible como para poder recibir fácilmente una funcionalidad adicional en el futuro.

¿Existe un patrón de diseño o una buena práctica para resolver este problema o problemas de jerarquía similares?

EDIT :

Aquí está el diseño que tengo: Diagramadeclaseconmétodosincluidos.Laclase"Grupo" es la jerarquía

La clase "Phoenix" se llama así porque todavía no pensé en un nombre apropiado.

Pero además de esto, tengo que poder ocultar actividades específicas para observadores específicos , aunque estén vinculados a ellos a través de los grupos.

Un poco fuera de tema :

Personalmente, creo que debería ser capaz de cortar este problema a problemas más pequeños, pero se me escapa cómo. Creo que es porque involucra múltiples funcionalidades recursivas que no están asociadas entre sí y diferentes tipos de clientes que necesitan obtener información de diferentes maneras. Realmente no puedo envolver mi cabeza alrededor de eso. Si alguien me puede guiar en la dirección de cómo mejorar la forma de encapsular los problemas de jerarquía, también me encantaría recibir eso.

    
pregunta Aske B. 15.08.2012 - 17:53

3 respuestas

1

Aquí hay una implementación simple de "Grupo" que te permite navegar a la raíz y navegar por el árbol de esa raíz como una colección.

public class Group
{
  public Group Parent
  public List<Group> Children

  public IEnumerable<Group> Parents()
  {
    Group result = this;
    while (result.Parent != null)
    {
      result = result.Parent;
      yield return result;
    }
  }
  public Group Root()
  {
    return Parents.LastOrDefault() ?? this;
  }


  public IEnumerable<Group> WalkTreeBreadthFirst(
  {
    //http://en.wikipedia.org/wiki/Breadth-first_search
    HashSet<Group> seenIt = new HashSet<Group>()
    Queue<Group> toVisit = new Queue<Group>();
    toVisit.Enqueue(this);

    while (toVisit.Any())
    {
      Group item = toVisit.Dequeue();
      if (!seenIt.Contains(item))
      {
        seenIt.Add(item);
        foreach (Group child in item.Children)
        {
          toVisit.Enqueue(child);
        }
        yield return item;
      }
    }
  }

  public static IEnumerable<Group> WalkTreeDepthFirst()
  {
    // http://en.wikipedia.org/wiki/Depth-first_search
    HashSet<Group> seenIt = new HashSet<Group>();
    Stack<Group> toVisit = new Stack<Group>();

    toVisit.Push(this);

    while (toVisit.Any())
    {
      Group item = toVisit.Pop();
      if (!seenIt.Contains(item))
      {
        seenIt.Add(item);
        foreach (Group child in item.Children.Reverse())
        {
          toVisit.Push(child);
        }
        yield return item;
      }
    }
  }
}

Entonces, dado un grupo, puedes caminar el árbol de ese Grupo:

Group myGroup = GetGroup();
Group root = myGroup.Root;
foreach(Group inTree in root.WalkTreeBreadthFirst())
{
  //do something with inTree Group.
}

Mi esperanza al publicar esto, es que al mostrar cómo navegar un árbol (y disipar su complejidad), puede visualizar las operaciones que desea realizar en el árbol y luego volver a visitar los patrones en su poseer para ver lo que mejor se aplica.

    
respondido por el Amy B 17.08.2012 - 19:34
0

Con la visión limitada que tenemos del uso o los requisitos de implementación de su sistema, es difícil ser demasiado específico. Por ejemplo, las cosas que entrarían en consideración podrían ser:

  • ¿el sistema es altamente concurrente (muchos usuarios)?
  • ¿cuál es la proporción de lectura / escritura del acceso a los datos? (lectura alta, escritura baja es común)

En cuanto a los patrones, etc., me preocuparía menos sobre qué patrones exactos surgen en su solución, y más sobre el diseño de la solución real. Creo que el conocimiento de los patrones de diseño es útil, pero no lo es todo: para usar una analogía de escritor, los patrones de diseño son más como un diccionario de frases comúnmente vistas, en lugar de un diccionario de oraciones, debe escribir un libro completo. desde.

Tu diagrama se ve generalmente bien para mí.

Hay un mecanismo que no has mencionado y es tener algún tipo de caché en tu jerarquía. Obviamente, debe implementar esto con gran cuidado, pero podría mejorar significativamente el rendimiento de su sistema. Aquí hay una simple toma de él (caveat emptor):

Para cada nodo en su jerarquía, almacene los datos heredados con el nodo. Haz esto perezosamente o proactivamente, eso depende de ti. Cuando se realiza una actualización de la jerarquía, puede volver a generar los datos de la memoria caché para todos los nodos afectados allí y, a continuación, o establecer banderas "sucias" en los lugares apropiados y hacer que los datos afectados se vuelvan a generar perezosamente. cuando sea necesario.

No tengo idea de lo apropiado que es esto en su sistema, pero vale la pena considerarlo.

También, esta pregunta en S.O. puede ser relevante:

enlace

    
respondido por el occulus 31.08.2012 - 15:54
0

Sé que esto es algo obvio, pero lo voy a decir de todos modos, Creo que deberías echarle un vistazo al Observer Pattern que mencionaste que tienes un tipo de observador y lo que tienes me parece un patrón de observador.

par de enlaces:

DoFactory

oodesign

echa un vistazo a esos.  de lo contrario, simplemente codificaría lo que tienes en tu diagrama y luego usaré el patrón de diseño para simplificarlo si es necesario. usted ya sabe lo que debe suceder y cómo se supone que funciona el programa. Escriba un código y vea si aún encaja.

    
respondido por el Malachi 04.10.2012 - 17:16

Lea otras preguntas en las etiquetas