AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Noch immer Probleme mit dem Brückenmuster
Thema durchsuchen
Ansicht
Themen-Optionen

Noch immer Probleme mit dem Brückenmuster

Ein Thema von ice.icewing · begonnen am 5. Mär 2007 · letzter Beitrag vom 8. Mär 2007
Antwort Antwort
ice.icewing

Registriert seit: 10. Feb 2005
17 Beiträge
 
#1

Noch immer Probleme mit dem Brückenmuster

  Alt 5. Mär 2007, 15:17
Datenbank: verschiedene • Zugriff über: BDE
Hi,

Bernhard Geyer hat hier im Forum bereits öfter darauf hingewiesen das ein Brückenmuster (Bridge Pattern) der beste Weg ist eine Unterstützung mehrerer DBMS in einem Projekt zu realisieren. Ich habe diesen Vorschlag aufgenommen, komme aber jetzt bei der Umsetzung ins Stocken.
Mein Problem ist hier hauptsächlich das ich mir nicht sicher bin welche Klasse ich von welcher erben lassen soll. Ein Versuch mit Interfaces zu arbeiten schlug gänzlich fehl. Am Beispiel der BDE TQuery. Hier lasse ich den Abstrakten Implementor von TQuery erben und den Konkreten Implementor vom Abstrakten. Hat aber den Nachteil das ich bei jedem Wechsel der Zugriffsart auch die Abstrakte Klasse ein klein wenig verändern muss, was so schon nicht richtig sein kann aber wenigstens funktioniert.
Größere Schwierigkeiten habe ich auf der Linken Seite. Von was soll die abstrakte Klasse Erben. Ich will sie als Komponente in die Komponentenpalette aufnehmen. Daher ist TComponent nahe liegend, aber der gemeinsame Nenner meiner Querys ist TDataSet.
So wie ich verschiedene Beispiele im Internet verstanden habe wird in der abstrakten Klassen auf der Linken Seite ein Objekt des abstrakten Implementor erstellt und die Aufrufe darauf weitergeleitet. Ist dass so korrekt?
Ich kann auch nicht herausfinden wie ich es im constructor der Spezialisierung machen soll, das meine Methodenaufrufe auch an die richtige Stelle kommen. Nicht die eine Hälfte auf Das von TDataSet geerbte und die andere Hälfte weitergeleitet auf über die Brücke auf die TQuery.

Es ist wirklich wichtig für mich die Zusammenhänge zu verstehen und anwenden zu können. Wenn jemand eine Deklaration oder ein Beispiel für mich hat welches auch Vererbung nutzt würde mir das sehr helfen.
J. Renner
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Noch immer Probleme mit dem Brückenmuster

  Alt 6. Mär 2007, 17:28
Zitat von ice.icewing:
Bernhard Geyer hat hier im Forum bereits öfter darauf hingewiesen das ein Brückenmuster (Bridge Pattern) der beste Weg ist eine Unterstützung mehrerer DBMS in einem Projekt zu realisieren. Ich habe diesen Vorschlag aufgenommen, komme aber jetzt bei der Umsetzung ins Stocken.
Hi,
vor deinem Beispiel und den dort beschriebenen Problemen steht natürlich das Verständnis des Musters, deswegen vorab einmal die Frage, wie weit Du es bereits verstanden hast?

Die Frage
Zitat von ice.icewing:
Es ist wirklich wichtig für mich die Zusammenhänge zu verstehen und anwenden zu können. Wenn jemand eine Deklaration oder ein Beispiel für mich hat welches auch Vererbung nutzt würde mir das sehr helfen.
lässt (soweit ich Dich nicht falsch verstehe) ein wenig darauf schließen, dass Du hier noch nicht ganz sicher bist.
Ein eigentlich ganz schönes Beispiel, dass Du häufig als Anwendungsbeispiel findest, können wir ja mal näher betrachten. Das Typische Beispiel (das ich jetzt kenne) ist immer die Darstellung von Formen.
Hier sind zwei Dinge wichtige:
  1. Die Darstellung
  2. Die Formen

Fangen wir mit der linken Seite an. Hier steht die Abstraktion. Wie der Name unschwer vermuten lässt, möchte man als von etwas Konkreten abstahieren und mit dem Abstrakten (den Gemeinsamkeiten) arbeiten. Die Abstraktion besteht in diesem Fall aus den Formen. Formen gibt es unzählige, ich verzichte mal auf eine all zu große Aufzählung, denke jeder kennt Ellipsen und Vielecke zu genüge.
Das ich sagen kann, dass ein Dreieck, ein Viereck, ein Kreis, ... Formen sind, das zeigt, dass Formen etwas gemeinsames haben. Um einen Kreis zu beschreiben brauche ich aber (i.d.R.) andere Dinge als wenn ich ein Dreieck oder Viereck beschreiben möchte. Die Abstraktion wäre in diesem Fall jedenfalls die Form, ihre Eigenschaften fässt man in einer abstrakten Klasse zusammen. Eine Eigenschaft, die jede Form z.B. hat ist ihre Größe, ihr Flächeninhalt, was auch immer. Eine der wichtigsten Eigenschaften ist dann noch, dass man Formen zeichnen kann. Hier stellt sich die Frage, wie man dies idealerweise tut.

Eine einfache Idee wäre es, dass man eine Bibliothek diese Aufgabe übernehmen lässt, diese Bibliothek zeichnet dann einfach alle Formen. Das Problem, dass man dann aber natürlich hat ist, dass man nicht alle Formen kennt. So gibt es zu jeder natürlichen Zahl >= 3 ein entsprechendes Vieleck (mit entsprechend vielen Punkten). Und dann wären noch die Kombinationen aus allen Formen möglich...

Da man nicht alle Formen kennt, die auftreten könnten, lässt man einfach die Formen die Aufgabe des Zeichnens übernehmen. Jede Form weiß natürlich wie sie aussieht. Sie kann sich also ohne Probleme selbst darstellen.
Das ist auch schon alles, was wir über die linke Seite wissen, es gibt eine abstrakte Klasse Form, die hat bestimmte Eigenschaften (Größe, Position, ...) und kann sich selbst zeichnen. Von dieser Abstrakten Klasse erben jetzt ganz unterschiedliche Formen (alle die halt erstellt werden).

Nun müssen wir uns noch Gedanken zum Zeichnen machen. Wie gesagt, alle Nachfahren einer Form können sich zeichnen, die Frage ist aber wie. Wie man zeichnet hängt wiederum sehr stark vom System ab, auf dem die Anwendung läuft. So unterscheidet sich natürlich OpenGL von DirectX oder GDI. Auch hier gibt es also verschiedene Möglichkeiten. Das zeichnen für jede dieser Grafik-Schnittstellen und für jede Form zu implementieren wäre sicherlich keine schöne Aufgabe (und würde den Sinn der Abstraktion Form auch stark in Frage stellen).
Einschränkungen der verwendeten Zeichenroutinen sind aber natürlich auch nicht gerade von Vorteil. Nehmen wir einfach an, dass Du z.B. gerne mit GDI+ zeichnen möchtest, weil es schnell und schön ist. Auf älteren Windowssystemen muss diese Bibliothek aber nicht vorhanden sein. Hier möchtest Du aber dem Benutzer auch nicht den Download zumuten, sondern verwendest das vermeintlich langsamere GDI, das aber anders arbeitet.
Je nach System würde also anders gezeichnet werden.
Was Du an dieser Stelle machst ist aber einfach davon abstrahieren. Du beachtest nicht weiter, wie jetzt tatsächlich gezeichnet wird sondern schaffst eine Schnittstelle Zeichnen, die davon abstrahiert. Diese Schnittstelle ist dann deine Impelementierung, das Zeichnen mit GDI oder GDI+ sind dann die konkreten Implementierungen.

Was jetzt noch fehlt ist die Zusammenführung. Möchte ein Objekt vom Typ Form sich selbst zeichnen, dann holt es sich über eine bestimmte Methode der abstrakten Klasse einfach eine Zeichnen Instanz. Zeichnen entscheidet selbst für das entsprechende System, ob GDI oder GDI+ verwendet wird (je nachdem was vorhanden ist). Die konkrete Form bekommt jedenfalls durch den Aufruf einer bestimmten Methode ein Zeichnen-Objekt und weiß, wie es das benutzt. Dieser Weg (wie man an dieses Objekt kommt) ist für alle Formen gleich!

So, was Du jetzt hast sind einfach zwei Unabhängige Abstraktionen. Steigst Du für die Darstellung auf GTK+ um, so benötigst Du dazu nur eine andere Implementierung der Schnittstelle Zeichnen. Für die Formen bleibt dies aber hinter der Schnittstelle verborgen, sie bekommen ein Objekt, dass alle Funktionen der Schnittstelle Zeichnen zur Verfügung stellt.
Auf der anderen Seite gibt es aber auch ganz unterschiedliche Formen, mit völlig unterschiedlichen Eigenschaften, aber eben auch Gemeinsamkeiten, zu denen eben auch in Teilen das Zeichnen gehört (natürlich zeichnet sich ein Rechteck etwas anders als ein Kreis).

Ja, das ist es auch schon. Idee ist also, dass Du zwei Abstraktionen benutzt. Die linke (die auch als Abstraktion bezeichnet wird) ist dabei eine abstrakte Klasse, die auf die Implementierung (rechte) zugreift. Hinter der Implementierung können sich aber wiederum konkrete Implementierungen verbergen. Da die linke Abstraktion zudem abstrakt ist, muss es hier sogar konkrete Nachfahren geben, also auch hier hinter verbergen sich verschiedene Implementierungen.

Ja, wie gesagt, es ist erstmal wichtig diese Idee zu verstehen. Falls Du noch Fragen hast, stell sie einfach. Für Dein Beispiel wäre es schön, wenn Du nochmal sagst, was für Dich die Abstraktion und konkrete Abstraktionen und was die Implementierung/konkrete Implementierungen sind und warum. Da ist es dann vermeintlich leichter den Überblick zu behalten (hatte heute zuwenig Kaffe und hab dein Beispiel nur überflogen, da ist mir gerade nicht mehr klar, wer jetzt von wem erben soll).

Gruß Der Unwissende
  Mit Zitat antworten Zitat
ice.icewing

Registriert seit: 10. Feb 2005
17 Beiträge
 
#3

Re: Noch immer Probleme mit dem Brückenmuster

  Alt 8. Mär 2007, 08:00
Vielen dank für deine Antwort.
Ich dachte das Brückenmuster verstanden zu haben. Meine Frage beruhte darauf das ich genau darüber ins Zweifeln geraten bin. Zu recht wie sich nun zeigte. Ich habe mir gestern noch einmal die Grundlagen angeschaut und erneut ein Beispiel für ein Brückenmuster programmiert und an diesen Beitrag angehängt. Leider habe ich im Internet immer nur Primitivbeispiele gefunden und hoffe das zum einen mein Beispiel ein Brückenmuster korrekt darstellt und zukünftig vielleicht auch dem einen oder anderen weiter hilft.

Nun lösen die neuen Erkenntnisse aber nicht mein Problem sondern zeigen es mir nur um so deutlicher auf. Eine Schnittstelle um Figuren so zu übertragen, das viele Arten der Darstellung möglich sind, ist schon nicht einfach. Wie soll ich das erst für ein Tabelle machen oder ein Query.
Meine erste Frage beruhte auf dem Versuch die gemeinsamen Eigenschaften unverändert über die Brücke zu schleifen und für die restlichen auf der Anwendungsseite benötigten bei der jeweiligen Konkreten Implementation mit einzubauen. Schon allein diese Vorgehensweise ermöglicht mir nur bedingt Unabhängigkeit auf der Anwendungsseite zu gewähren.

Daher frage ich jetzt: Ist das Brückenmuster überhaupt für eine variable DBMS-Anbindung geeignet oder sollte ich auf der Anwendungsseite lieber auf Unabhängigkeit verzichten und einen Adapter nutzen, wobei ich auch hier nicht sicher bin in wie weit das möglich ist.

Schöne Grüße icewing
Angehängte Dateien
Dateityp: zip bsp_188.zip (148,9 KB, 20x aufgerufen)
J. Renner
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Noch immer Probleme mit dem Brückenmuster

  Alt 8. Mär 2007, 21:47
Zitat von ice.icewing:
Ich habe mir gestern noch einmal die Grundlagen angeschaut und erneut ein Beispiel für ein Brückenmuster programmiert und an diesen Beitrag angehängt. Leider habe ich im Internet immer nur Primitivbeispiele gefunden und hoffe das zum einen mein Beispiel ein Brückenmuster korrekt darstellt und zukünftig vielleicht auch dem einen oder anderen weiter hilft.
Hi,
bitte versteh mich nicht falsch, an deinem Beispiel möchte ich dann doch etwas Kritik üben. Das erste was mir aufgefallen ist ist, dass leider wenig Kommentiert wurde. Natürlich hast Du hier die einzelnen Elemente benannt, es wäre aber deutlich schöner, wenn Du ein paar Erklärende Worte dazu schreibst. Du sagst selbst, dass Du gerne jmd. helfen würdest, diesem jmd. würde es aber ggf. doch weiter helfen, wenn er nicht alle Beiträge im Thread lesen muss um den Ansatz in deiner Implementierung zu verstehen.

Wichtig wäre (imho), dass Du kurz erläuterst, worum es in dem Beispiel geht. Natürlich musst Du nicht nochmal das Brückenmuster erklären, aber darauf verweisen wäre schon nicht schlecht. Wie der Name ja vorweg nimmt handelt es sich um ein Muster. Die Entwurfsmuster heißen ja nicht zu Unrecht so. Das heißt natürlich auch, dass man die Bestandteile und deren Verhalten in der Implementierung wiederfindet. Erstere hast Du noch benannt (Abstraktion, konkrete Abstraktion,..) aber das Verhalten bleibt unkommentiert.
Nun ja, bei Beispielen muss ich sagen ist es natürlich auch immer schöner, wenn Du die Benennung sinnvoll wählst. Das gilt dann für die Namen der Units, die Variablen und auch die (visuellen) Komponenten und deren Caption. Das eigentliche Brückmuster kannst Du zudem natürlich auch von der Anzeige auf dem Formular trennen. Nicht falsch verstehen, ist halt nur so, dass es gerade bei Beispielen immer toll ist, wenn jmd. gutes Vorbild ist, hat aber auch weniger mit dem eigentlichen Problem zu tun.

Zitat von ice.icewing:
Daher frage ich jetzt: Ist das Brückenmuster überhaupt für eine variable DBMS-Anbindung geeignet oder sollte ich auf der Anwendungsseite lieber auf Unabhängigkeit verzichten und einen Adapter nutzen, wobei ich auch hier nicht sicher bin in wie weit das möglich ist.
Nun ja, hier musst Du klar zwischen einfach, zeit-aufwendig und geeignet differenzieren. Geeignet ist es auf jeden Fall, denn genau das Problem (Abstrahieren von etwas Konkretem an mehr als einer Stelle) ist das Brückenmuster gedacht.
Vorallem ist die Umsetzung des Brückenmusters mit einem gewissen zeitlichen Aufwand verbunden, das ist aber immer der Fall, wenn Du sauber modellieren möchtest. Dabei sollte hier aber auch klar gesagt werden, dass eine schlechte/unvollständige Modellierung später deutlich mehr Zeit kostet, als man hier bei der Planung investiert.
Dann wäre da noch der Punkt der Einfachheit. An sich hängt hier natürlich viel von der konkreten Umsetzung ab. Dennoch lassen sich Komplexe Probleme immer in einfachere Teilprobleme zerlegen. Führt man dies weiter fort, so erreicht man irgendwann den Punkt sehr einfacher Probleme, die sich zudem auch einfach lösen lassen. Beziehst Du also Einfachheit auf die Komplexität des Codes, so würde ich Dir generell dazu raten, immer möglichst einfachen Code zu verwenden, was aber wieder ein Thema für sich ist.

An sich bleibt natürlich weiterhin die Frage, ob sich für Dich das Brückenmuster lohnt oder nicht. Dabei solltest Du aber berücksichtigen, dass Du hier ein Front- und Back-End hast, dass Du in vielen unterschiedlichen Projekten verwenden kannst. Die so erstellte Lösung ist (wenn gut modelliert) recht abstrakt und wäre damit nicht auf bestimmte DBMSe beschränkt, auch eine XML-basierte oder sonstige Dateisystem-basierte Lösung wäre z.B. denkbar (z.B. bei lokalem Export oder so).

An sich setzen natürlich auch existierende Delphi-Lösungen auf das Brücken-Muster. Nimm hier einfach TDataset und die verschiedenen konkreten Ausprägungen auf der einen Seite und der Zugriff auf ein DMBS über BDE, ADO usw. auf der Anderen. Da wird im Prinzip nichts anderes gemacht.
Bei einer eigenen Umsetzung hast Du allerdings eine höhere Flexibilität und mehr Einfluss auf die Umsetzung. Ggf. kannst Du hier mehr Leistung aus spezielleren Umsetzungen rausholen. Vorallem kannst Du einfach auf Änderungen an einem DBMS reagieren (bessere Treiber, neue Eigenschaften, ...). Nicht immer werden solche Änderungen auch für eine bestimmte, vorhandene Abstraktion von Borland übernommen. Andererseits bist Du natürlich mit einer eigenen Lösung auf eigene Anpassungen angewiesen.
Als Alternative (und vielleicht guter Anfang) bietet sich zudem noch die Kombination mit dem Adapter-Muster an. Du kannst natürlich Dein eigenes Interface erstellen und einen Adapter als eine konkrete Implementierung verwenden, die auf etwas wie TDataset zurückgreift. Hier entsteht natürlich erstmal unnötiger Overhead, den Du nicht benötigst. Da dies aber nur eine mögliche Abstraktion ist, ermöglicht sie Dir die Arbeit mit deiner Schnittstelle (hier kannst Du schauen, wie gut Deine Planung war), gleichzeitig kannst Du aber auch nach und nach weitere Alternativen schaffen, die vielleicht durch den Verzicht auf andere Abstraktionen und gezielteren Anpassungen sogar perfomanter arbeiten als bestehende Lösungen.

Das Brückenmuster bleibt dabei der einfache Zusammenhang, dass Du zwei Seiten hast, die eine gewisse Abstraktion darstellen und verschieden implementiert werden. Um es nochmal deutlich zu machen möchte ich hier auf ein schönes Beispiel, dass sich auch bei Wikipedia findet zurückgreifen:
Zitat:
(nicht wörtlich zitiert, nur sinngemäß!)
Eine Abstraktion sind Autos. Es gibt ganz unterschiedliche Arten von Autos, da wäre z.B. ein Merced SLK 500, ein BMW M6, und ein VW-Golf. Ist klar, dass das alles ganz unterschiedliche Autos sind (man könnte da natürlich noch weiter verfeinern, aber egal).
Auf der anderen Seite hätten wir Straßen. Da gibt es u.A. Autobahnen und Landstraßen. Ein beliebiges Auto muss jetzt so entworfen werden, dass es auf jeder Straße fährt, das ist alles.
Ich denke das gibt ganz gut die eigentliche Idee des Brücken-Musters wieder, da man hier sehr schön die zwei Abstraktionen (Auto und Straße), ihre verschiedenen Implementierungen und ihr Zusammenspiel (jedes Auto benutzt beliebige Straße auf gleiche Art und Weise) sieht.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz