Strategie [ Übersicht ] [ Beispiel ] [ Quellen ] [ Home Entwurfsmuster ]


Beschreibung

Im Beispiel wird ein aus einer Datei einzulesender Text nach einem Muster (Zeichen, Wort oder Satzteil) durchsucht. Dabei kommen verschiedene Algorithmen zur Anwendung.

Das Muster Strategie wird verwendet, um während des Programmlaufs den Algorithmus ändern zu können, ohne die Klasse, die den Text enthält, zu ändern. Der Suchalgorithmus soll unanbhängig vom Text entwickelt und gewartet werden können. Wenn ein oder sogar mehrere Algorithmen in der Klasse Text enthalten sind, würde diese unnötig spezialisiert und komplex werden.

Deshalb sieht das Muster Strategie eine Teilung vor: Ein Text-Objekt enthält nicht den Algorithmus selbst, sondern nur eine Referenz auf ein Objekt, das die Suche ausführen kann. Dieses Objekt, Strategie genannt, implementiert eine abstrakte Klasse, im Beispiel Textsucher. Sobald ein Text aufgeforsert wird, nach einem Muster zu suchen, wird diese Aufgabe an die Strategie delegiert. Die Auswahl des Algorithmus ist bei Erstellung des Text-Objektes vorzunehmen, eine Änderung während der Lebenszeit des Text-Objektes ist ebenfalls möglich.

Alternativ zu diesem Ansatz könnte man alle benötigten Algorithmen in der Klasse Text vorrätig halten oder in einer Klassenhierarchie mehrere Unterklassen von Text bilden, wobei jede Klasse einen Algorithmus impementiert.

Ein weiterer Grund für die Benutzung dieses Musters ist, neben den bereits oben genannten, dass die Algorithmen Daten verwenden könnten, die mit der eigentlichen Klasse Text nichts zu tun haben. Man verwendet dann das Strategiemuster, um algorithmenspezifische Datenstrukturen zu verbergen.

Das Beispiel ist wie folgt aufgebaut: In der Klasse App wird ein Objekt der Klasse Main_Dialog erzeugt, dass die Oberfläche für den Benutzer des Programms darstellt. Sie erlaubt die Auswahl einer zu durchsuchenden Datei und die Eingabe eines Musters, nach dem gesucht werden soll. Nach Aktivierung der Suchfunktion wird in der Methode find ein Objekt der Klasse Text erzeugt. Diesem wird bei der Erstellung der aus der Datei gelesene Text (String) sowie der erste der Suchalgorithmen übergeben.

Alle Suchalgorithmen stellen Impementationen der abstrakten Klasse Textsucher dar. Textsucher hat nur eine abstrakte Methode suche, die von den drei Unterklassen InternTextSucher, BruteForceTextSucher und ShiftOrTextSucher definiert wird. Sie können Näheres zu den 3 Algorithmen erfahren.

Zum Quelltext
 Abb. 1: Die Struktur des Beispiels


Nachdem der erste Algorithmus sein Ergebnis, die Stelle an der das Muster gefunden wurde, zurückgeliefert hat, wird die Strategie, also der Algorithmus geändert. So erfolgt das Durchsuchen nach den verschiedenen Algorithmen. Die Ergebnisse werden jeweils dargestellt.

Auf eine Besonderheit sei an dieser Stelle noch hingewiesen. Da die unterschiedlichen Strategien unterschiedliche Daten des Textes erfordern, wird neben dem Muster auch eine Referenz auf den Text an die Suchalgorithmen übergeben.

Die Nachteile des Strategiemusters sollen auch nicht verschweigen werden. Die Klienten der Text-Objekte, in diesem Fall der Haupt-Dialog, müssen um die unterschiedlichen Strategien wissen, bzw. diese selber erzeugen. Dies bedeutet, das die Unterschiede zwischen den Strategien bekannt sein müssen, um eine passende Strategie auszuwählen. Somit kann es ein, dass die Klienten über Implementaionsaspekte Bescheid wissen müssen. Es ist ebenfalls offensichtlich, dass das Muster zu einer erhöhten Anzahl von Objekten führt, was bei einer erhöhten Flexibilität jedoch zu verschmerzen ist.

 Abb. 2: Screenshot des Beispiels


Gepackte Ausführbare Datei für Windows 95/NT: Strategie.zip



Algorithmen zur Volltextsuche

Im Muster Strategie werden 3 verschiedene Algorithmen zur Suche in Textdokumenten verwendet. Diese sollen hier kurz erläutert werden.

Interner Algorithmus
Es wird die Bibliotheksfunktion zur Suche nach Teilstrings der Klasse String verwendet. Diese Variante ist mit Abstand die schnellste der 3 Algorithmen.

Brute Force - Textsuche
Der Text wird von links nach rechts durchsucht. Dabei wird an jeder Stelle probiert, ob das Muster passt. Dieser Algorithmus ist einfach zu implementieren, jedoch nicht effizient.

Shift-Or - Textsuche
Der Algorithmus nutzt ein Wort von m Bits, ein Bit für jedes Zeichen des Musters, um den Zustand der Suche zu zeigen. Das i-te Bit ist eine 0, wenn die ersten i Zeichen des Musters mit den letzten i Zeichen des Textes übereinstimmen, andernfalls ist es eine 1. Wenn das m-te Bit 0 ist, passt das Muster.

Um den Zustand nach Einlesen eines neuen Zeichens zu aktualisieren, wird eine Bitverschiebung des Zustands und ein logisches Or mit dem Eintrag des Zeichens einer vorberechneten Tabelle durchgeführt. Die Tabelle wird durch das Muster und das Alphabet bestimmt.

Die Suche untersucht jedes Zeichen nur einmal. Durch eine kleine Änderung kann der Algorithmus auch Wildcards verarbeiten. Dafür iost er der schnellste bekannte Algorithmus. Für die hier verwendete Suche ist der Algorithmus eigentlich weniger geeignet, er ist in etwa so schnell wie der Brute Force-Algorithmus.

Quelle: G.H. Gonnet, R. Baeza-Yates: Handbook of Algorithms and Data Structures, Chapter 7: Text Algorithms


[ Übersicht ] [ Beispiel ] [ Quellen ] [ Home Entwurfsmuster ]
Stand: 31.03.2005, Autor: Danko Mannhaupt