ERLEDIGT
JA
JA
ANTWORTEN
5
5
ZUGRIFFE
503
503
EMPFEHLEN
-
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
-
09.11.05 21:43 #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 TomJava 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
-
09.11.05 22:44 #3
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Das meinte ich übrigens ungefähr so: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 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 TomJava 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
-
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
-
Zu Delegates vielleicht ein kleiner Link:
http://www.codersource.net/csharp_delegates_events.html
-
Danke, sehr schönes Beispiel!
Ähnliche Themen
-
JSON neue Objekte während der Laufzeit hinzufügen
Von yeronimo im Forum Javascript & AjaxAntworten: 10Letzter Beitrag: 20.01.10, 15:24 -
Zur Laufzeit neue Picturebox erstellen
Von Rene42 im Forum .NET CaféAntworten: 1Letzter Beitrag: 30.05.07, 19:31 -
Neue "Klassen" zur Laufzeit erzeugen !nicht Instanzen
Von Romsl im Forum JavaAntworten: 8Letzter Beitrag: 29.08.05, 15:43 -
3D Max 6 - Aktuelle Modeling Fähigkeiten
Von the-cR im Forum 3D Studio MaxAntworten: 1Letzter Beitrag: 06.04.04, 21:42 -
User-Fähigkeiten testen...
Von Carndret im Forum SmalltalkAntworten: 20Letzter Beitrag: 07.06.03, 18:29





Zitieren

Login





