tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
503
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    gott_ad gott_ad ist offline Mitglied
    Registriert seit
    Jul 2004
    Ort
    Rostock (MV)
    Beiträge
    16
    Hi Forumfreunde,

    mein Problem ist folgendes (ich mach mal ein einfacheres Beispeil daraus):
    Stellt euch vor ich habe ein Programm mit dem ich einen Baum aufbaue (ein Wurzelknoten, mehrere Kindknoten die Blätter oder Knoten sein können... ihr kennt das ja). Dieser Baum (er ist eine Instanz der Klasse "Baum") soll jetzt traversiert (durchwandert) werden. Da gibt es ja zum Beispiel 3 klassische Möglichkeiten (ich glaub die waren so): Postorder (erst rechts langgehen) Inorder (erst die mitte entlang) oder Preorder (erst links langgehen).
    Wie auch immer, ich will der Baumklasse jetzt ein Traversierungselement zuweisen (wahrscheinlich ne Unterklasse der Klasse "Traverse") und dann sagen "los, durchwandere meinen baum" und je nachdem welchen ich mit der Baumklasse verknüft habe, wird Pre-/Post-/Inorder ausgeführt.

    Meiner Meinung nach schreit das ja förmlich nach dem Besucher Muster (bin jetzt bei den Patterns nicht ganz so bewandert), oder? Es soll mit dem besucher-Pattern aber auch möglich sein, dass sich Besucher zur Laufzeit ändern oder neue hinzukommen. Hat da jemand ne Idee?
    Wäre ja cool wenn ich ein Traversierungselement mitzuliefere und später einfach ne weitere DLL in einen unterordner zu kopiere und er fragt mich dann, welche Traversierungsart ich nehmen will.

    Gruß gott_ad
     

  2. #2
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    Wie wär's denn, wenn du die Traversierungstrategie dynamisch zur Laufzeit per Reflection setzt? Weiterhin könntest du auch eine Art Callback-Modus (vielleicht per Delegates) implementieren, über den dann die Aktion, welche für jeden Besuchten Knoten ausgeführt wird enthält.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    
      using System;
      using System.Reflection;
      
      namespace De.Tutorials
      {
        /// <summary>
        /// Zusammendfassende Beschreibung für Class1.
        /// </summary>
        class TreeWalkExample
        {
            /// <summary>
            /// Der Haupteinstiegspunkt für die Anwendung.
            /// </summary>
            [STAThread]
            static void Main(string[] args)
            {
                //Siehe:
                //http://en.wikipedia.org/wiki/Post-order_traversal
                TreeNode Root = new TreeNode(2);
                Root.LeftChild = new TreeNode(7);
                Root.LeftChild.LeftChild = new TreeNode(2);
                Root.LeftChild.RightChild = new TreeNode(6);
                Root.LeftChild.RightChild.LeftChild = new TreeNode(5);
                Root.LeftChild.RightChild.RightChild = new TreeNode(11);
      
                Root.RightChild = new TreeNode(5);
                Root.RightChild.RightChild = new TreeNode(9);
                Root.RightChild.RightChild.LeftChild = new TreeNode(4);
      
                Console.WriteLine("PreOrderTraversal");
             ITraversalStrategy traversalStrategy = (ITraversalStrategy)Activator.CreateInstance(Type.GetType("De.Tutorials.PreOrderTraversalStrategy"));
                traversalStrategy.Traverse(Root);
      
                Console.WriteLine("InOrderTraversal");
             traversalStrategy = (ITraversalStrategy)Activator.CreateInstance(Type.GetType("De.Tutorials.InOrderTraversalStrategy"));
                traversalStrategy.Traverse(Root);
      
                Console.WriteLine("PostOrderTraversal");
             traversalStrategy = (ITraversalStrategy)Activator.CreateInstance(Type.GetType("De.Tutorials.PostOrderTraversalStrategy"));
                traversalStrategy.Traverse(Root);
      
            }
        }
        
        class TreeNode
        {
            public object Data;
            public TreeNode LeftChild;
            public TreeNode RightChild;
                
            public TreeNode(object Data)
            {
                this.Data = Data;
            }
        }
      
        interface ITraversalStrategy
        {
            void Traverse(TreeNode Node);
        }
      
        class PreOrderTraversalStrategy:ITraversalStrategy
        {
            public void Traverse(TreeNode Node)
            {
                Console.WriteLine(Node.Data);
                if(Node.LeftChild != null)
                {
                    Traverse(Node.LeftChild);
                }
                if(Node.RightChild != null)
                {
                    Traverse(Node.RightChild);
                }
            }
        }
      
        class InOrderTraversalStrategy:ITraversalStrategy
        {
            public void Traverse(TreeNode Node)
            {
                if(Node.LeftChild != null)
                {
                    Traverse(Node.LeftChild);
                }
                Console.WriteLine(Node.Data);
                if(Node.RightChild != null)
                {
                    Traverse(Node.RightChild);
                }
            }
        }
      
        class PostOrderTraversalStrategy:ITraversalStrategy
        {
            public void Traverse(TreeNode Node)
            {
                if(Node.LeftChild != null)
                {
                    Traverse(Node.LeftChild);
                }
                if(Node.RightChild != null)
                {
                    Traverse(Node.RightChild);
                }
                Console.WriteLine(Node.Data);
            }
        }
      }

    Gruss Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  3. #3
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    Weiterhin könntest du auch eine Art Callback-Modus (vielleicht per Delegates) implementieren, über den dann die Aktion, welche für jeden Besuchten Knoten ausgeführt wird enthält.
    Das meinte ich übrigens ungefähr so:

    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    
      using System;
       using System.Reflection;
       
       namespace De.Tutorials
       {
        /// <summary>
        /// Zusammendfassende Beschreibung für Class1.
        /// </summary>
        class TreeWalkExample
        {
            /// <summary>
            /// Der Haupteinstiegspunkt für die Anwendung.
            /// </summary>
            [STAThread]
            static void Main(string[] args)
            {
                //Siehe:
                //http://en.wikipedia.org/wiki/Post-order_traversal
                TreeNode root = new TreeNode(2);
                root.leftChild = new TreeNode(7);
                root.leftChild.leftChild = new TreeNode(2);
                root.leftChild.rightChild = new TreeNode(6);
                root.leftChild.rightChild.leftChild = new TreeNode(5);
                root.leftChild.rightChild.rightChild = new TreeNode(11);
       
                root.rightChild = new TreeNode(5);
                root.rightChild.rightChild = new TreeNode(9);
                root.rightChild.rightChild.leftChild = new TreeNode(4);
       
                MethodInfo methodInfo = typeof(TreeWalkExample).GetMethod("PrintDataForCurrentNode",new Type[]{typeof(TreeNode)});
             AbstractTraversalStrategy.ActionForCurrentNode actionForCurrentNode = (AbstractTraversalStrategy.ActionForCurrentNode)
     System.Delegate.CreateDelegate(typeof(AbstractTraversalStrategy.ActionForCurrentNode),methodInfo);
       
                Console.WriteLine("PreOrderTraversal");
             AbstractTraversalStrategy traversalStrategy = (AbstractTraversalStrategy)Type.GetType("De.Tutorials.PreOrderTraversalStrategy").GetConstructor(new Type[]{typeof(AbstractTraversalStrategy.ActionForCurrentNode)}).Invoke(new Object[]{actionForCurrentNode});
                traversalStrategy.Traverse(root);
       
                Console.WriteLine("InOrderTraversal");
             traversalStrategy = (AbstractTraversalStrategy)Type.GetType("De.Tutorials.InOrderTraversalStrategy").GetConstructor(new Type[]{typeof(AbstractTraversalStrategy.ActionForCurrentNode)}).Invoke(new Object[]{actionForCurrentNode});
                traversalStrategy.Traverse(root);
       
                Console.WriteLine("PostOrderTraversal");
             traversalStrategy = (AbstractTraversalStrategy)Type.GetType("De.Tutorials.PostOrderTraversalStrategy").GetConstructor(new Type[]{typeof(AbstractTraversalStrategy.ActionForCurrentNode)}).Invoke(new Object[]{actionForCurrentNode});
                traversalStrategy.Traverse(root);
       
                Console.ReadLine();
       
            }
       
            public static void PrintDataForCurrentNode(TreeNode node)
            {
                Console.WriteLine(node.data);
            }
        }
        
        class TreeNode
        {
            public object data;
            public TreeNode leftChild;
            public TreeNode rightChild;
                
            public TreeNode(object data)
            {
                this.data = data;
            }
        }
       
        abstract class AbstractTraversalStrategy
        {   
            public delegate void ActionForCurrentNode(TreeNode node);
            public ActionForCurrentNode doActionForCurrentNode;
       
            public AbstractTraversalStrategy(ActionForCurrentNode action)
            {
                this.doActionForCurrentNode = action;
            }
       
            public abstract void Traverse(TreeNode node);
        }
       
       
       
        class PreOrderTraversalStrategy:AbstractTraversalStrategy
        {
            
            public PreOrderTraversalStrategy(ActionForCurrentNode action):base(action)
            {
       
            }
       
            public override void Traverse(TreeNode node)
            {
                doActionForCurrentNode(node);
                if(node.leftChild != null)
                {
                    Traverse(node.leftChild);
                }
                if(node.rightChild != null)
                {
                    Traverse(node.rightChild);
                }
            }
        }
       
        class InOrderTraversalStrategy:AbstractTraversalStrategy
        {
       
            public     InOrderTraversalStrategy(ActionForCurrentNode action):base(action)
            {
       
            }
       
            public override void Traverse(TreeNode node)
            {
                if(node.leftChild != null)
                {
                    Traverse(node.leftChild);
                }
                doActionForCurrentNode(node);
                if(node.rightChild != null)
                {
                    Traverse(node.rightChild);
                }
            }
        }
       
        class PostOrderTraversalStrategy:AbstractTraversalStrategy
        {
       
            public PostOrderTraversalStrategy(ActionForCurrentNode action):base(action)
            {
            }
       
            public override void Traverse(TreeNode node)
            {
                if(node.leftChild != null)
                {
                    Traverse(node.leftChild);
                }
                if(node.rightChild != null)
                {
                    Traverse(node.rightChild);
                }
                doActionForCurrentNode(node);
            }
        }
       }

    Gruss Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  4. #4
    gott_ad gott_ad ist offline Mitglied
    Registriert seit
    Jul 2004
    Ort
    Rostock (MV)
    Beiträge
    16
    Als erstes riesen Dank für deine super ausführliche Antwort mit den hervorragenden Beispielen

    Mit Delegates kenn ich mich wenig aus, aber auch mal sehr schön eine Reflection Variante davon zu sehen. Es ist natürlich praktisch die Funktion zum Auswerten nur einmal zu schreiben und alle nutzen diese. Da die Verarbeitungsfunktionen aber wahrscheinlich auch unterschiedliche sachen machen können sollen, werde ich wohl die erste Variante benutzen

    Im grunde brauch ich mich mit dem BeuscherPattern nicht rumzuschlagen, wenn ich einfach ein Interface und Reflection nutze! Dann kann ich auch zur Laufzeit neue Funktionalitäten einpflegen.

    Danke!
    gott_ad
     

  5. #5
    Avatar von Norbert Eder
    Norbert Eder Norbert Eder ist offline Mitglied Diamant
    Registriert seit
    Feb 2004
    Ort
    Österreich / Graz
    Beiträge
    5.137
    Blog-Einträge
    51
    Zu Delegates vielleicht ein kleiner Link:
    http://www.codersource.net/csharp_delegates_events.html
     

  6. #6
    gott_ad gott_ad ist offline Mitglied
    Registriert seit
    Jul 2004
    Ort
    Rostock (MV)
    Beiträge
    16
    Danke, sehr schönes Beispiel!
     

Ähnliche Themen

  1. JSON neue Objekte während der Laufzeit hinzufügen
    Von yeronimo im Forum Javascript & Ajax
    Antworten: 10
    Letzter Beitrag: 20.01.10, 15:24
  2. Zur Laufzeit neue Picturebox erstellen
    Von Rene42 im Forum .NET Café
    Antworten: 1
    Letzter Beitrag: 30.05.07, 19:31
  3. Antworten: 8
    Letzter Beitrag: 29.08.05, 15:43
  4. 3D Max 6 - Aktuelle Modeling Fähigkeiten
    Von the-cR im Forum 3D Studio Max
    Antworten: 1
    Letzter Beitrag: 06.04.04, 21:42
  5. User-Fähigkeiten testen...
    Von Carndret im Forum Smalltalk
    Antworten: 20
    Letzter Beitrag: 07.06.03, 18:29