Interfacce segreganti / preoccupazioni per un albero

3

Quando lavori con un singolo oggetto ci sono molti modi per separare le interfacce ad esso.

  • Spezzandolo in componenti più piccoli che possono essere trattati indipendentemente.
  • Trasformandolo in interfacce più semplici.

Entrambi questi sembrano difficili da fare con un albero. Penso che sarebbe bello poter fare quanto segue.

class Node : INodeData, INodePresentation { ... }

class Program
{
    static void Main()
    {
        var node = new Node();
        ManipulateNode(node);
        PresentNode(node);
    }

    void ManipulateNode(INodeData nodeData)
    {
        foreach (INodeData child in nodeData.GetChildren())
             nodeData.AddVertices(...);
        nodeData.Rotate(...);
    }

    void PresentNode(INodePresentation nodePresentation)
    {
        nodePresentation.Color = Color.Blue;
        nodePresentation.Size = 15;
        nodePresentation.Paint();
        foreach (INodePresentation child in nodePresentation.GetChildren())
            PresentNode(child);
    }
}

In questo modo, diverse parti del programma potrebbero utilizzare il nodo in base a un'interfaccia concisa. Ma ogni interfaccia che aggiungo richiederà più metodi nella classe Node che potrebbero essere non mantenibili. Sembra che la presentazione e i dati debbano essere definiti in classi separate, ma non riesco a pensare a un buon modo per farlo mantenendo la capacità di attraversare l'albero. Qualche suggerimento?

    
posta TrevorM 03.04.2014 - 19:03
fonte

2 risposte

2

Probabilmente il modo più comune è creare un Node<T> con solo le strutture e passarlo in altre funzioni che possono usare un T per fare le presentazioni.

Se hai difficoltà a invertire il controllo quando esegui un attraversamento ricorsivo, prova a passare una funzione in un metodo di attraversamento, qualcosa di simile (perdona la sintassi perché non conosco C #):

void DepthFirstTraversal(Node<T> node, Function func)
{
    func(node);
    foreach (Node<T> child in node.GetChildren())
        DepthFirstTraversal(child, func);
}

Un altro metodo utile per aggiungere funzionalità a una classe, ma un po 'meno familiare a seconda delle lingue che conosci, utilizza un mixin . Potrebbe o potrebbe non essere utile nel tuo caso.

Puoi implementare i mixin in C # 3.0 usando i metodi di estensione , e credo che ci siano librerie di terze parti per aiutare. I mixin ti permettono fondamentalmente di aggiungere funzionalità a una classe senza che sia necessario implementare un'interfaccia. L'implementazione è mescolata con l'implementazione esistente della classe.

    
risposta data 03.04.2014 - 21:06
fonte
1

It seems like the presentation and data should be defined in separate classes, but I can't think of a good way to do this while maintaining the ability to traverse the tree. Any suggestions?

Il problema delle interfacce è che devi conoscerle tutte in anticipo. Se si desidera aggiungere nuove interfacce, è necessario utilizzare il modello Decoratore . Ma penso che dovresti rivalutare il tuo approccio. Hai davvero bisogno di un'interfaccia per ogni nuova manipolazione del nodo? Puoi semplicemente aggiungere una funzione / metodo statico che prende l'albero come argomento e fa qualsiasi manipolazione tu abbia bisogno.

    
risposta data 03.04.2014 - 19:22
fonte

Leggi altre domande sui tag