Ein Designmechanismus ist eine Präzisierung eines entsprechenden Analysemechanismus (siehe auch Konzept:
Analysemechanismen). Ein Designmechanismus fügt dem konzeptionellen Analysemechanismus konkrete Details hinzu,
braucht aber keine bestimmte Technologie, z. B. eine bestimmte Implementierung eines Anbieters eines objektorientiertes
Datenbankmanagementsystems. Wie bei den Analysemechanismen kann ein Designmechanismus ein oder mehrere Muster
instanzieren, in diesem Fall Architektur - oder Designmuster.
Ein Implementierungsmechanismus ist eine Konkretisierung eines entsprechenden
Designmechanismus, der beispielsweise eine bestimmte Programmiersprache oder eine andere Implementierungstechnologie
(z. B. ein Middleware-Produkt eines bestimmten Anbieters) verwendet. Ein Implementierungsmechanismus kann ein oder
mehrere Idiome oder Implementierungsmuster instanzieren.
Schauen Sie sich den Analysemechanismus für Persistenz an:
-
Möglicherweise müssen viele (2.000) kleine Objekte (jeweils 200 Bytes) nur für ein paar Sekunden gespeichert
werden.
-
Möglicherweise müssen mehrere sehr große Objekte für mehrere Monate permanent auf der Platte gespeichert werden,
die nie aktualisiert werden, aber anspruchsvolle Abrufmethoden erfordern.
Diese Objekte erfordern unterschiedliche Persistenzunterstützung. Die folgenden
Merkmale von Designmechanismen für Persistenzunterstützung können ermittelt werden:
-
Merkmale für Speicherung im Hauptspeicher:: für bis zu 1 Mb insgesamt (Größe x Volumen), sehr schneller
Zugriff für Lesen, Schreiben, Aktualisieren
-
Merkmale für Flash-Karte: für bis zu 8 Mb, langsamer Zugriff beim Aktualisieren und Schreiben, mittelmäßiger
Lesezugriff
-
Merkmale für Binärdatei: für 100 Kb bis 200 Mb, langsame Aktualisierung, langsamer Lese- und Schreibzugriff.
-
Merkmale für Datenbankmanagementsystem (DBMS): für 100 Kb und höher (praktisch keine Obergrenze), noch
langsamerer Aktualisierungs-, Lese- und Schreibzugriff.
Diese Geschwindigkeiten sind nur im Vergleich mit der Speicherung im Hauptspeicher als 'langsam' zu bewerten. In
manchen Umgebungen können die Zugriffszeiten natürlich durch die Verwendung von Caching verbessert werden.
Zunächst ist die Zuordnung zwischen Designmechanismen und Implementierungsmechanismen wahrscheinlich suboptimal, reicht
aber aus, um das Projekt in den Gang zu bringen, noch nicht bemerkte Risiken aufzudecken und weitere Untersuchungen und
Auswertungen auszulösen. Mit Fortschreiten des Projekts und mit zunehmendem Wissen muss die Zuordnung präzisiert
werden.
Gehen Sie bei der Präzisierung der Zuordnung von Design- und Implementierungsmechanismen iterativ vor und eliminieren
Sie redundante Pfade, indem Sie sich von oben nach unten und von unten nach oben durch das Design arbeiten.
Design von oben nach unten durcharbeiten. Bei dieser Vorgehensweise, auch "Top-down" genannt, stellen neue und
präzisierte Anwendungsfallrealisierungen durch die erforderlichen Analysemechanismen neue Anforderungen an die
erforderlichen Designmechanismen. Solche neuen Anforderungen können zusätzliche Merkmale eines Designmechanismus
aufdecken und möglicherweise eine Aufteilung zwischen Mechanismen erzwingen. Außerdem muss ein Kompromiss zwischen
Systemkomplexität und Systemleistung gefunden werden:
-
Zu viele unterschiedliche Designmechanismen machen das System zu komplex.
-
Zu wenig Designmechanismen können bei manchen Implementierungsmechanismen, die bereits an ihre Grenzen gehen,
Leistungsprobleme hervorrufen.
Design von unten nach oben durcharbeiten. Bei dieser Vorgehensweise, auch "Bottom-up" genannt, werden Sie bei
der Untersuchung der verfügbaren Implementierungsmechanismen vielleicht Produkte finden, die mehrere Designmechanismen
gleichzeitig befriedigen, aber eine gewisse Anpassung bzw. Neuaufteilung Ihrer Designmechanismen erfordern. Sie können
die Anzahl der verwendeten Implementierungsmechanismen zwar verringern, aber wenn Sie zu wenig
Implementierungsmechanismen haben, kann dies unter Umständen zu Leistungsproblemen führen.
Nachdem Sie sich entschieden haben, ein Datenbankmanagementsystem (DBMS) zum Speichern der Objekte der Klasse A zu
verwenden, sind Sie möglicherweise versucht, alle Objekte im System in diesem DBMS zu speichern. Dies könnte sich als
extrem ineffizient oder mühsam erweisen. Nicht alle Objekte, die Persistenz erfordern, müssen im DBMS gespeichert
werden. Einige Objekte können persistent sein, werden aber möglicherweise häufig von der Anwendung und nur selten von
anderen Anwendungen aufgerufen. In diesem Fall kann eine Hybridstrategie, in der das Objekt aus dem DBMS in den
Hauptspeicher eingelesen und regelmäßig synchronisiert wird, die beste Lösung sein.
Beispiel
Ein Flug kann für schnelle Zugriffe im Hauptspeicher und für Langzeitpersistenz in einem DBMS gespeichert werden. Dies
löst jedoch den Bedarf an einem Synchronisationsmechanismus aus.
Es ist nicht ungewöhnlich, einer Clientklasse mehrere Designmechanismen zuzuordnen, um unterschiedlichen Merkmalen
gerecht zu werden.
Da Implementierungsmechanismen häufig als Pakete in Standardkomponenten (Betriebssysteme und Middleware-Produkte)
bereitgestellt werden, müssen basierend auf Kosten, Impedanzabweichungen oder Stilvereinheitlichung gewisse
Optimierungsarbeiten vorgenommen werden. Außerdem sind Mechanismen häufig voneinander abhängig, was eine klare
Aufteilung von Services in Designmechanismen schwierig macht.
Beispiele
Verbesserungen müssen die gesamte Ausarbeitungsphase hindurch vorgenommen werden und sind häufig ein Kompromiss
zwischen:
-
einer exakten 'Entsprechung' mit den Anforderungen der Auftraggeber der Designmechanismen in Bezug auf die
erwarteten Merkmale und
-
den Kosten und der Komplexität mit zu vielen Implementierungsmechanismen, die erworben und integriert werden
müssen.
Das Gesamtziel ist immer, eine einfache, saubere Gruppe von Mechanismen zu haben, die einem großen System
konzeptionelle Integrität, Einfachheit und Eleganz verleihen.
Die Designmechanismen für Persistenz können Implementierungsmechanismen wie folgt zugeordnet werden:
Eine mögliche Zuordnung zwischen Analysemechanismen und Designmechanismen. Der gepunktete Pfeil bedeutet "wird
spezialisiert von" und impliziert, dass die Merkmale der Designmechanismen von den Analysemechanismen übernommen, aber
spezialisiert und verbessert werden.
Nachdem Sie die Mechanismen optimiert haben, sind die folgenden Zuordnungen vorhanden:
Die Designentscheidungen für eine Clientklasse, dargestellt durch Zuordnung der Mechanismen: Eine Klasse Flug
erfordert zwei Formen der Persistenz: Speicherung im Hauptspeicher, implementiert durch eine gebrauchsfertige
Bibliotheksroutine, und Speicherung in einer Datenbank, implementiert durch ein Standardprodukt für
Objektspeicherung.
Die Zuordnung muss in beide Richtungen navigierbar sein, so dass die Clientklassen leicht erkennbar sind, wenn die
Implementierungsmechanismen geändert werden.
Designmechanismen und Details zu ihrer Verwendung werden im Arbeitsergebnis Projektspezifische Richtlinien dokumentiert. Die Beziehung (oder
Zuordnung) der Analysemechanismen zu Designmechanismen zu Implementierungsmechanismen und die zugehörige Begründung für
diese Auswahl wird im Arbeitsergebnis Softwarearchitekturdokument dokumentiert.
Wie Analysemechanismen können Designmechanismen mit einer Kollaboration modelliert werden, die eine oder mehrere Architekturmuster oder Designmuster instanzieren kann.
Beispiel: Ein Persistenzmechanismus
Dieses Beispiel verwendet eine Instanz eines Musters für RDBMS-basierte Persistenz, entnommen aus JDBC™ (Java Data Base Connectivity). Wir
präsentieren das Design hier zwar, aber JDBC stellt echten Code für einige der Klassen bereit, so dass es von unserer
Präsentation bis hin zu einem Implementierungsmechanismus nur ein kleiner Schritt ist.
Die Abbildung "Statische Sicht: JDBC" zeigt die Klassen (d. h. eigentlich die Klassifikatorrollen) in der
Kollaboration.
Statische Sicht: JDBC
Die gelb gefüllten Klassen sind die Klassen, die bereitgestellt wurden. Die anderen (meineDBKlasse etc.) wurden vom
Designer gebunden, um den Mechanismus zu erstellen.
In JDBC arbeitet ein Client mit einer DBClass, um persistente Daten zu lesen und zu schreiben. Die DBClass ist
für den Zugriff auf die JDBC-Datenbank unter Verwendung der Klasse DriverManager verantwortlich. Nachdem eine
Datenbankverbindung geöffnet wurde, kann die DBClass SQL-Anweisungen erstellen, die an das zugrunde liegende
RDBMS gesendet und mit der Klasse Statement ausgeführt werden. Die Klasse Statement "spricht" mit der Datenbank.
Das Ergebnis der SQL-Abfrage wird in einem Objekt ResultSet zurückgegeben.
Die Klasse DBClass ist dafür verantwortlich, eine andere Klasseninstanz persistent zu machen. Sie kennt die
OO-RDBMS-Zuordnung und hat das Verhalten, um als Schnittstelle mit dem RDBMS aufzutreten. Die DBClass vereinfacht das
Objekt, schreibt es in das RDBMS und liest die Objektdaten aus dem RDBMS
und erstellt das Objekt. Jede persistente Klasse erhält eine entsprechende DBClass.
PersistentClassList wird verwendet, um eine Gruppe persistenter Objekte als Ergebnis einer Datenbankabfrage (z.
B. DBClass.read()) zurückzugeben.
Im Folgenden präsentieren wir Ihnen eine Reihe dynamischer Sichten, um Ihnen zu zeigen, wie der Mechanismus
funktioniert.
JDBC: Initialize
Die Initialisierung muss stattfinden, damit auf persistente Klassen zugegriffen werden kann.
Zum Initialisieren der Verbindung zur Datenbank muss die DBClass den entsprechenden Treiber laden, indem sie die
Operation DriverManager getConnection() mit einem URL, Benutzer und Kennwort aufruft.
Die Operation getConnection() versucht, eine Verbindung zum angegebenen Datenbank-URL herzustellen. Der DriverManager
versucht, einen entsprechenden Treiber aus einer Gruppe registrierter JDBC-Treiber auszuwählen.
Parameter:
url: Ein Datenbank-URL mit dem Format jdbc:Unterprotokoll:Untername. Dieser URL wird verwendet, um den
eigentlichen Datenbankserver zu suchen und ist in dieser Instanz nicht webbezogen.
user: Der Datenbankbenutzer, für den die Verbindung hergestellt wird.
pass: das Kennwort des Benutzers.
Rückgabewerte:
Eine Verbindung zum URL.
JDBC: Create
Zum Erstellen einer neuen Klasse fordert der Persistenzclient die DBClass auf, die neue Klasse zu erstellen. Die
DBClass erstellt eine neue Instanz von PersistentClass mit Standardwerten. Anschließend erstellt die DBClass eine neue
Anweisung (Statement) mit der Operation createStatement() der Klasse Connection. Die Anweisung wird ausgeführt, und die
Daten werden in die Datenbank eingefügt.
JDBC: Read
Zum Lesen einer persistenten Klasse fordert der Persistenzclient die DBClass zum Lesen auf. Die DBClass erstellt eine
neue Anweisung mit der Operation createStatement() der Klasse Connection. Die Anweisung wird ausgeführt, und die Daten
werden in einem Objekt ResultSet zurückgegeben. Anschließend erstellt die DBClass eine neue Instanz von PersistentClass
und füllt diese mit den abgerufenen Daten. Die Daten werden in einem Erfassungsobjekt zurückgegeben, einer Instanz der
Klasse PersistentClassList.
Anmerkung: Die an executeQuery() übergebene Zeichenfolge muss nicht dieselbe Zeichenfolge sein, die an read() übergeben
wird. Die DBClass erstellt die SQL-Abfrage zum Abruf der persistenten Daten aus der Datenbank unter Verwendung der an
read() übergebenen Bedingungen. Dies geschieht deswegen, weil wir nicht möchten, dass der Client der DBClass die
Interna der Datenbank kennen muss, um eine gültige Abfrage zu erstellen. Dieses Wissen ist in der DBClass gekapselt.
JDBC: Update
Zum Aktualisieren einer Klasse fordert der Persistenzclient die DBClass zum Aktualisieren auf. Die DBClass ruft die
Daten aus dem angegebenen PersistentClass-Objekt ab und erstellt eine neue Anweisung mit der Operation
createStatement() der Klasse Connection. Nachdem die Anweisung erstellt wurde, wird die Aktualisierung durchgeführt und
die Datenbank mit den neuen Daten aus der Klasse aktualisiert.
Beachten Sie Folgendes: Die DBClass hat die Aufgabe, die PersistentClass zu vereinfachen und in die Datenbank zu
schreiben. Deshalb muss sie aus der angegebenen PersistentClass abgerufen werden, bevor die SQL-Anweisung erstellt
wird.
Anmerkung: Im zuvor beschriebenen Mechanismus muss die PersistentClass Zugriffsroutinen für alle persistenten Daten
bereitstellen, damit die DBClass auf sie zugreifen kann. Damit ist externer Zugriff auf bestimmte persistente Attribute
möglich, die andernfalls nicht öffentlich wären. Dies ist der Preis, den Sie zahlen müssen, um das Persistenzwissen aus
der Klasse zu ziehen, die die Daten kapselt.
JDBC: Delete
Zum Löschen einer Klasse fordert der Persistenzclient die DBClass auf, die PersistentClass zu löschen. Die DBClass
erstellt eine neue Anweisung mit der Operation createStatement() der Klasse Connection. Die Anweisung wird ausgeführt,
und die Daten werden aus der Datenbank gelöscht.
In der Implementierung dieses Designs müssen bestimmte Entscheidungen über die Zuordnung von DBClass zu den
persistenten Klassen getroffen werden, z. B. Verwendung einer DBClass pro persistenter Klasse und Zuordnung dieser
Klassen zu Paketen. Diese Pakete sind vom angegebenen Paket java.sql (siehe JDBC™
API-Dokumentation) abhängig, das die unterstützenden Klassen DriverManager, Connection, Statement und ResultSet
enthält.
|