Implementierung von Business-Objekten
Klassen mit Geschäftsregeln legen die Grundstein für eine echte objektorientierte Anwendung.
Implementierung von Business-Objekten
Dieser Artikel ist der erste einer Serie, in dem wir die vielen Facetten der Umsetzung einer echte objektorientierte Anwendung erkunden werde. Auf dem Weg wir nehmen in fast jedem Aspekt der Anwendungsentwurf und fordern einige akzeptierten Möglichkeiten eine Delphi-Anwendung zu schreiben. Das grundlegende Konzept hinter diesem Ansatz ist die Kapselung: eine Reihe von Klassen mit klar definierten Schnittstellen (Methoden) zu entwerfen, die auf Eigenschaften operieren. Diese Konzepte werden durchdringen die gesamte Anwendung und werden großen Einfluss auf die Art und Weise, in der Daten gespeichert und dargestellt werden. Ich würde die empfohlene Leser Francis Glassborows C++-Spalte zu studieren; Obwohl das Delphi-Objektmodell die Vollständigkeit (und die Komplexität) von C++ fehlt, sind die Konzepte der gute Klassenentwurf sprachunabhängige.
Typischste Delphi-Anwendungen, die heute geschrieben werden nicht objektorientiert. Nur weil die Sprache ein Objektmodell hat und viele bestehende und neue Klassen werden verwendet, bedeutet dies nicht, dass die Anwendung als wirklich OO angesehen werden kann. Wiederverwendung von Code ist beendet mit Drittanbieter-Komponenten auf Formulare löschen, und Interdependenzen zwischen Formen und Einheiten schnell vermehren. Zukunftschancen für das Ändern der Anwendung Grundlagen (z. B. Wechsel der Datenbank oder Verschieben von 2 Reihen zu 3-stufig-Umsetzung) sind stark eingeschränkt oder sehr teuer zu betrachten. Die Anwendung einer OO Manier zu schreiben wäre erleichtern, anstatt zu beschränken, diese Möglichkeiten. Allerdings erfordert das Schreiben von solchen Anwendungen eine Geist-Verschiebung, begleitet von einer anfänglichen Mangel an Produktivität, die meisten Entwicklungsteams abgeneigt oder nicht imstande, zu berücksichtigen sind. Im Laufe dieser Artikel hoffe ich demonstrieren machen einige der Grundlagen, die Entwicklern helfen, den Schritt zu bessere Anwendungen implementieren. Die resultierende Systeme werden immer zuverlässiger, verwaltbar, konsequente, flexible, wiederverwendbare und in der Regel eine bessere Leistung als eine Anwendung in der Weise geschrieben. Insbesondere sind die Vorteile der Klarheit des Codes, so dass für große Anwendungen, ein geschrieben OO Weise deutlich weniger Wartung Ressourcen als der gleichen Anwendung traditionell geschrieben erfordern kann. Ich sollte vielleicht rechtfertigen diese Vorteile einer OO-Anwendung weiter: Ich glaube, dass nur wenige es befürwortet, etwas zu verkaufen (in diesem Fall die Vision einer besseren Anwendungen) sollten wegkommen unangefochten!
OO-Anwendungen für verbesserte Zuverlässigkeit rührt daher, dass die Daten und Vorgänge werden in genau definierten Klassen gekapselt. Der Compiler selbst fördert die richtige Verwendung von Klasse, Methode und Eigenschaft durch starken Typ überprüfen, und mit einzigartigen, anstatt duplizierten Code bedeutet, dass künftige an einer einzigen Routine Änderungen werden überall in der gesamten Anwendung. Folge die korrekte Verwendung von Klassen ist, dass die Beziehungen zwischen ihnen selbstverständlich sind und ein weit größerer Anteil der Code geschrieben ist eigentlich das 'Fleisch' der Anwendung implementieren, anstatt sich Gedanken über Details wie wie die Daten tatsächlich dauerhaft gespeichert werden. Dies macht die Anwendung wesentlich einfacher zu verwalten, einen Faktor, der durch größere Konsistenz weiter vereinfacht. Wie wir sehen werden, Klassenvererbung intensiv zu nutzen beide steigert Produktivität und Zuverlässigkeit, aber auch Konsistenz auferlegt. Diese Konsistenz ist offensichtlich in der Weise, die dass Code angeordnet ist und wie Klassen Verhalten, aber auch in dem Maße wie Daten gespeichert und wie ist die Benutzeroberfläche präsentiert. Wie viele der Funktionen in Basisklassen vorgesehen ist, ist es möglich, schnell ändern ihr Verhalten, um die Anwendung (z. B. ändern die Schnittstelle, um sein html-basierte, anstatt Formular-) grundlegend zu beeinflussen. Diese Basisklassen können anwendungsunabhängig, sein, damit die zweite Anwendung, die auf diese Weise geschrieben eine sofortige Produktivität-Steigerung erhält auszulegen. Eine gute Abstimmung der Basisklassen bieten bis zu 50 % des Codes in einer mittleren Anwendung, einen offensichtlichen Vorteil aus einer Zeit, Kosten und Zuverlässigkeit stehen. Es ist nur vernünftig zu bemerken, dass damit der Wechsel zu 'echten' OO-Entwicklung nicht trivial und nur werden, zum ersten Mal mit erfahrener Unterstützung oder für ein Projekt klein ohne dringende Termine durchgeführt sollte. Es sollte auch betont werden, dass eine OO-Lösung kein anderer Klassen festgelegt wird, die innerhalb der Anwendung verwendet werden, müssen (oder nicht müssen). Wenn eine Firma hat ihre eigenen visuellen Komponenten entwickelt,, die von einem Dritten verwendet oder auf einer bestimmten Datenbank-Plattform standardisiert hat dann es gibt keinen Grund, warum diese (mit einer bedeutenden Ausnahme) verwendet werden kann. Entwickeln einer OO-Anwendung ist über einen konsistenten Satz von Entwurfsmuster anwenden, anstatt Sie zu diktieren, welche Komponenten verwendet werden soll.
Fokussierte Klassen
Der erste Schritt bei der Gestaltung einer objektorientierten Anwendung denkt über die Klassen, die benötigt werden. Dies ist ein fundamentaler Schritt, wie mit jeder anderen Entwicklung Technik, wie man sich vertun frühzeitig teuer zu beheben sein wird. Im entwerfen, die unsere Klassen, mit denen wir in der Regel anstreben sollten niedrige Kopplung und hohe Kohäsion - Klassen sollte so unabhängig wie möglich von anderen Klassen, sondern sollte möglich sein, in leistungsfähige Möglichkeiten kombiniert werden. Eine Möglichkeit hierfür besteht darin Klassengruppen von den Rollen, die sie innerhalb der Anwendung zu kategorisieren. Vernünftige Auswahl dieser Rollen wird ein zusammenhängender Satz von Klassen führen.
Gibt es eine grundsätzliche Regel, die ganze Rolle Klassenentwurf wiederkehrt: die starke Trennung der Klassen zuständig für Präsentation, Anwendung und Dauerhaftigkeit. Präsentation kann in der Regel werden geboten als Benutzeroberfläche und Persistenz als etwas, in dem Daten (in der Regel in einer Datenbank) gespeichert. Obwohl dies die gleiche Trennung wie für 3-Schichtentwicklung vorhanden ist ist, ist anzumerken, dass dies eine Konzeption-Trennung, die in vielerlei Hinsicht implementiert werden können: als eine einzelne monolithische Anwendung, die alle den Weg durch ein vollständig verteilten Multi-Tier-System. Der Satz von Klassen, aus denen die Anwendungslogik sind diejenigen, die tatsächlich die harte Arbeit der Reaktion auf Reize der Benutzer zu manipulieren und Daten verarbeiten. Eine Teilmenge der Klassen innerhalb dieser Schicht wird als Vertreter der realen Welt-Organisationen, die vom System nach dem Vorbild identifiziert. Diese sind sehr oft als 'Geschäft' oder 'Problemdomäne' Klassen gekennzeichnet. Sie bilden einen wichtiger Teil eines jeden OO-Systems, wie die meisten anderen Klassen sie werden, eine oder andere Weise unterstützen werden, und sie den Fokus aller Entwickler beteiligt bilden.
Ermittlung der Business-Objekte für eine bestimmte Anwendung im Allgemeinen mit Erfahrung, instinktive wird, gibt es zwar eine ganze Wissenschaft (oder ist es Kunst?) hinter den Prozess. Die Schönheit des OO verglichen mit traditionellen Techniken wie SSADM ist, dass die Prozesse von Analyse und Design, die entwickelt haben, die gleichen Einheiten im gesamten pflegen: Es ist möglich, eine Darstellung der jedes Geschäftsobjekt in OOA (Analyse), OOD (Design) und schließlich die Umsetzung selbst (OOP) zu sehen. Wir werden einige der Techniken für die Identifizierung der entsprechenden Geschäftsobjekte in zukünftigen Spalten erforschen. Vorerst, gehen wir davon aus, dass diese Prozesse durchgeführt wurden.
Die Kommunikation zwischen Klassen, die in den verschiedenen Schichten (Präsentation, Anwendung, Persistenz) vorhanden ist wohldefiniert und sollte unbedingt eingehalten werden. Dies wird in Abbildung 1 gezeigt, und die Pfeile zeigen, dass eine Klasse in einer Schicht Methodenaufrufe in einer anderen Klasse machen kann. Dieses Diagramm zeigt, dass die Darstellungsschicht (Benutzerschnittstelle) der Anwendungsschicht oder andere Klassen innerhalb der Benutzeroberfläche bearbeiten kann und die Anwendungsschicht (Business-Objekte) kann selbst zu manipulieren und telefonieren in die Persistenz-Schicht, die aus dem Application Layer nur auf Anfragen reagieren können.
Business-Objekte
Um zu demonstrieren, wie Business-Objekte implementiert werden können, folgen wir einem Berechnungsbeispiel mit einer kleinen Gruppe von Klassen, die die klassischen Lager, Customer- und Order-Entitäten offenlegen (ein Unternehmen bietet eine Anzahl von Elementen der Aktie zu verkaufen, die gekauft werden können (geordnet) von Kunden). Unsere Analyse (trivial) hat bestätigt, dass zunächst wir drei Business-Objekte um jeden dieser Entitäten darzustellen erfordern. In unserer Delphi-Anwendung haben wir drei Klassen: TStockItem, 'tCustomer' und TOrder. Listing 1 zeigt eine gekürzte öffentliche Schnittstelle für diese Klassen. Es ist darauf hinzuweisen, dass alle Attribute der Klasse als Eigenschaften verfügbar gemacht werden: Dies ist einfach gut Klasse Design und erleichtert die Kontrolle über den Zugriff auf die Eigenschaften (sollte dies erforderlich sein). Auch ist darauf hinzuweisen, dass die Eigenschaften im Abschnitt veröffentlichte der Klasse (aus Gründen, die wir, in Zukunft diskutieren werden) ausgesetzt sind und sie gegebenenfalls mit Standardwerten vollständig qualifiziert sind. Obwohl dieser Eigenschaft Qualifizierer angeblich beim streaming von Komponenten verwendet wird, es dient einem nützlichen Zweck um den Anfangswert der einzelnen Eigenschaften zu kennzeichnen und hilft den Code selbst beschreibende sein.
Etwas, das grundlegend für Geschäftsobjekte (Problemdomäne) ist, dass sie keine Kenntnis von wie sie dauerhaft gespeichert werden können. Sie wissen nicht, wie sie in Datenbanktabellen gespeichert sind, in der Tat können sie absolut keine Annahmen über Speicherung jeglicher Art. Ein Geschäftsobjekt ist sehr konzentriert-Klasse, die nur entsprechende Eigenschaften und die Methoden zu manipulieren verfügbar macht. Bei der Gestaltung der öffentlichen Schnittstelle der Klasse sollten keine Konzession hinsichtlich der Typen der Eigenschaften für die beständige (Datenbank) Speicherung erfolgen. Sie sollten immer auswählen, den am besten geeigneten Typ für die Eigenschaft betrifft, unabhängig davon, ob die beabsichtigte Datenbank sie nativ unterstützt. Ein gutes Beispiel ist eine Set-Eigenschaft: Einige Datenbanken unterstützen Sätze direkt, aber ist dies eine natürliche Art und Weise verfügbar zu machen eine Eigenschaft eines Geschäftsobjekts dann es sollte gewählt werden anstelle einer anderen Darstellung (möglicherweise mehrere boolesche Werte). Ein weiteres Beispiel ist so etwas wie eine Adresse als eine TStringList verfügbar zu machen. Es ist nicht Aufgabe des Geschäftsobjekts es Schnittstelle Datenbankspeicherung begünstigen nicht beeinträchtigen: Dies ist die Aufgabe der Persistenz-Schicht.
Unsere erste framework
Wir haben erkannt und drei Business-Objekte als erste Basis für unsere Anwendung implementiert. Diese drei Objekte nutzen eine gemeinsame Rolle: zu realen Personen in irgendeiner Weise vertreten. Wir erwarten daher, dass sie ähnliche Eigenschaften haben und daher eine Klassenhierarchie ist angebracht. Wir geben jedes dieser Objekte einen gemeinsamen Vorfahren, genannt TPDObject (für Problem Domain-Objekt). Diese TPDObject-Klasse wird im Laufe der Zeit erweitert werden, wenn wir gemeinsame Methoden und Eigenschaften unserer Klassen einführen. Es sei darauf hingewiesen, dass TPDObject keine Applikations-spezifische Elemente enthalten (und wird es nie). Als ein Konstrukt anwendungsunabhängig es sollte in einer separaten Einheit platziert werden und bildet die Grundlage eines Rahmens: eine Reihe von Klassen, die in vielen Anwendungen wiederverwendet werden können. Im Laufe der Zeit wird unser Framework stark erweitert, viele Basisklassen bereitstellen, die erhebliche anwendungsunabhängig Funktionalitäten bereit, die für bestimmte Systeme spezialisiert werden bereitzustellen. Unsere Klassen TStockItem, 'tCustomer' und TOrder sind Beispiele für spezialisierte Versionen unserer generische TPDObject. Eine nähere Untersuchung von Listing 1 zeigt, dass in der Tat unsere drei Übungsleiter Domäne jeweils von einer anderen Klasse, TMyAppPDObject, selbst abstammen ein Nachkomme des TPDObject. Obwohl die Umsetzung der TMyAppPDObject leer ist, ist es ein weiteres Beispiel für gute Klassenentwurf, damit wollen wir anwendungsspezifische Elemente zu bieten alles von unserem Problem Domain-Objekten gibt ist eine entsprechende Klasse in unsere Hierarchie.
Listing 2 zeigt unsere embryonale Framework-Einheit. Im Moment stellt die TPDObject-Klasse nur eine schreibgeschützte Eigenschaft mit dem Namen ID, die vom Typ TObjectID ist. Diese Eigenschaft wird verwendet, um eine Unterrichtsstunde geben den Begriff der Identität: zwei Instanzen definieren wir als das gleiche Objekt darstellt, wenn sie vom gleichen Typ sind und den gleichen ID-Wert haben. Dies wurde bewusst wie es eigene Art ist, so dass es nicht direkt zuweisungskompatibel mit anderen skalaren Typen definiert. Die Auswahl des Typs für den TObjectID ist willkürlich: Ich habe mich entschieden in diesem Fall zu machen, einen ganzzahligen Typ, aber es gibt einen Fall zu machen, es ist Klasse. Obwohl eine weitere 'reine' Ansatz, habe ich dagegen auf der Grundlage beschlossen, dass unser Problem Domain-Objekte werden gebaut (und zerstört) mehrere tausend Mal während einer Anwendung und können wir den Aufwand für den Bau und die Zerstörung der Extraklasse TObjectID (mein puristisch-Argument für diese Umsetzung-Wahl ist, dass die separate TObjectID-Klasse in der TPDObject-Klasse als zusammengesetzte Objekt subsumiert worden hat) vermeiden. Es gibt einige zusätzliche Methoden in dieser Einheit um unsere Identität Objekttyp in eine String-Darstellung und eine Konstante 'hat keine Identität' Anfangswert zu konvertieren.
Es gibt eine Reihe von Denkschulen auf Objektidentität; man sagt, dass alle Geschäftsobjekte eine Identität zugewiesen werden soll, wenn er erstellt wird und die Identität eindeutig innerhalb einer Anwendung (oder sogar weltweit wie in eine GUID) sein sollte. In der Praxis ist es wichtig nur zwischen zwei Objekten in einem bestimmten Kontext unterscheiden können, und dies einfach zu halten, hat offensichtlich Leistung und Vorteile, obwohl Sie sicherlich nicht mich argumentiert gegen eine Wahl für ein komplexer Typ unter geeigneten Umständen finden.
Eine Frage der Ethik
Um einige der Entwurfsaspekte und Umsetzung hervorzuheben entwerfen einen Rahmen werde ich gelegentlich Entscheidungen wenn Fragen stellen und laden die Leser die Logik dahinter zu berücksichtigen. Am Anfang der Spalte spielte ich auf eine bedeutende Ausnahme zu der Aussage, dass eine wirklich OO-Design nicht die Verwendung von bestimmten Klassen verbieten. Was ist die Ausnahme zu dieser Aussage (Tipp: die Antwort liegt in der Abbildung 1).
(((Listing 1 - eine anwendungsspezifische Problemdomäne Einheit (gekürzt))))
Einheit ProblemDomain;
Schnittstelle
verwendet
Rahmen;
Typ
TMyAppPDObject = Class (TPDObject)
Ende;
TStockItem = Class (TMyAppPDObject)
veröffentlicht
Eigenschaft Name: String;
Eigenschaft QuantityInStock: Kardinal Voreinstellung 0;
Eigenschaft TradePrice: Währung;
Eigenschaft Verkaufspreis: Währung;
Ende;
'TCustomer' = Class (TMyAppPDObject)...;
TOrder = Class (TMyAppPDObject)...;
Umsetzung
Ende.
(((Ende Codebeispiel 1)))
(((Listing 2 - ein anwendungsunabhängiger Framework Einheit)))
Einheit Framework;
Schnittstelle
const
NotAssigned = 0;
Typ
TObjectID = Typ Integer;
TPDObject = Klasse
Private
FID: TObjectID;
öffentliche
Objekt-ID: TObjectID lesen FID Standard NotAssigned;
Ende;
Funktion StrToID (Value: String): TObjectID;
Funktion IDToStr (Wert: TObjectID): String;
Umsetzung
...
Ende.
(((Ende Codebeispiel 2)))
(((Abbildung 1 - Klassenübersicht Interaktion)))
(((Ende Abbildung 1)))
Weiter in Serie
Implementierung von Business-Objekten
Implementierung von Business-Objekten : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
Klassen mit Geschäftsregeln legen die Grundstein für eine echte objektorientierte Anwendung.
Implementierung von Business-Objekten
Dieser Artikel ist der erste einer Serie, in dem wir die vielen Facetten der Umsetzung einer echte objektorientierte Anwendung erkunden werde. Auf dem Weg wir nehmen in fast jedem Aspekt der Anwendungsentwurf und fordern einige akzeptierten Möglichkeiten eine Delphi-Anwendung zu schreiben. Das grundlegende Konzept hinter diesem Ansatz ist die Kapselung: eine Reihe von Klassen mit klar definierten Schnittstellen (Methoden) zu entwerfen, die auf Eigenschaften operieren. Diese Konzepte werden durchdringen die gesamte Anwendung und werden großen Einfluss auf die Art und Weise, in der Daten gespeichert und dargestellt werden. Ich würde die empfohlene Leser Francis Glassborows C++-Spalte zu studieren; Obwohl das Delphi-Objektmodell die Vollständigkeit (und die Komplexität) von C++ fehlt, sind die Konzepte der gute Klassenentwurf sprachunabhängige.
Typischste Delphi-Anwendungen, die heute geschrieben werden nicht objektorientiert. Nur weil die Sprache ein Objektmodell hat und viele bestehende und neue Klassen werden verwendet, bedeutet dies nicht, dass die Anwendung als wirklich OO angesehen werden kann. Wiederverwendung von Code ist beendet mit Drittanbieter-Komponenten auf Formulare löschen, und Interdependenzen zwischen Formen und Einheiten schnell vermehren. Zukunftschancen für das Ändern der Anwendung Grundlagen (z. B. Wechsel der Datenbank oder Verschieben von 2 Reihen zu 3-stufig-Umsetzung) sind stark eingeschränkt oder sehr teuer zu betrachten. Die Anwendung einer OO Manier zu schreiben wäre erleichtern, anstatt zu beschränken, diese Möglichkeiten. Allerdings erfordert das Schreiben von solchen Anwendungen eine Geist-Verschiebung, begleitet von einer anfänglichen Mangel an Produktivität, die meisten Entwicklungsteams abgeneigt oder nicht imstande, zu berücksichtigen sind. Im Laufe dieser Artikel hoffe ich demonstrieren machen einige der Grundlagen, die Entwicklern helfen, den Schritt zu bessere Anwendungen implementieren. Die resultierende Systeme werden immer zuverlässiger, verwaltbar, konsequente, flexible, wiederverwendbare und in der Regel eine bessere Leistung als eine Anwendung in der Weise geschrieben. Insbesondere sind die Vorteile der Klarheit des Codes, so dass für große Anwendungen, ein geschrieben OO Weise deutlich weniger Wartung Ressourcen als der gleichen Anwendung traditionell geschrieben erfordern kann. Ich sollte vielleicht rechtfertigen diese Vorteile einer OO-Anwendung weiter: Ich glaube, dass nur wenige es befürwortet, etwas zu verkaufen (in diesem Fall die Vision einer besseren Anwendungen) sollten wegkommen unangefochten!
OO-Anwendungen für verbesserte Zuverlässigkeit rührt daher, dass die Daten und Vorgänge werden in genau definierten Klassen gekapselt. Der Compiler selbst fördert die richtige Verwendung von Klasse, Methode und Eigenschaft durch starken Typ überprüfen, und mit einzigartigen, anstatt duplizierten Code bedeutet, dass künftige an einer einzigen Routine Änderungen werden überall in der gesamten Anwendung. Folge die korrekte Verwendung von Klassen ist, dass die Beziehungen zwischen ihnen selbstverständlich sind und ein weit größerer Anteil der Code geschrieben ist eigentlich das 'Fleisch' der Anwendung implementieren, anstatt sich Gedanken über Details wie wie die Daten tatsächlich dauerhaft gespeichert werden. Dies macht die Anwendung wesentlich einfacher zu verwalten, einen Faktor, der durch größere Konsistenz weiter vereinfacht. Wie wir sehen werden, Klassenvererbung intensiv zu nutzen beide steigert Produktivität und Zuverlässigkeit, aber auch Konsistenz auferlegt. Diese Konsistenz ist offensichtlich in der Weise, die dass Code angeordnet ist und wie Klassen Verhalten, aber auch in dem Maße wie Daten gespeichert und wie ist die Benutzeroberfläche präsentiert. Wie viele der Funktionen in Basisklassen vorgesehen ist, ist es möglich, schnell ändern ihr Verhalten, um die Anwendung (z. B. ändern die Schnittstelle, um sein html-basierte, anstatt Formular-) grundlegend zu beeinflussen. Diese Basisklassen können anwendungsunabhängig, sein, damit die zweite Anwendung, die auf diese Weise geschrieben eine sofortige Produktivität-Steigerung erhält auszulegen. Eine gute Abstimmung der Basisklassen bieten bis zu 50 % des Codes in einer mittleren Anwendung, einen offensichtlichen Vorteil aus einer Zeit, Kosten und Zuverlässigkeit stehen. Es ist nur vernünftig zu bemerken, dass damit der Wechsel zu 'echten' OO-Entwicklung nicht trivial und nur werden, zum ersten Mal mit erfahrener Unterstützung oder für ein Projekt klein ohne dringende Termine durchgeführt sollte. Es sollte auch betont werden, dass eine OO-Lösung kein anderer Klassen festgelegt wird, die innerhalb der Anwendung verwendet werden, müssen (oder nicht müssen). Wenn eine Firma hat ihre eigenen visuellen Komponenten entwickelt,, die von einem Dritten verwendet oder auf einer bestimmten Datenbank-Plattform standardisiert hat dann es gibt keinen Grund, warum diese (mit einer bedeutenden Ausnahme) verwendet werden kann. Entwickeln einer OO-Anwendung ist über einen konsistenten Satz von Entwurfsmuster anwenden, anstatt Sie zu diktieren, welche Komponenten verwendet werden soll.
Fokussierte Klassen
Der erste Schritt bei der Gestaltung einer objektorientierten Anwendung denkt über die Klassen, die benötigt werden. Dies ist ein fundamentaler Schritt, wie mit jeder anderen Entwicklung Technik, wie man sich vertun frühzeitig teuer zu beheben sein wird. Im entwerfen, die unsere Klassen, mit denen wir in der Regel anstreben sollten niedrige Kopplung und hohe Kohäsion - Klassen sollte so unabhängig wie möglich von anderen Klassen, sondern sollte möglich sein, in leistungsfähige Möglichkeiten kombiniert werden. Eine Möglichkeit hierfür besteht darin Klassengruppen von den Rollen, die sie innerhalb der Anwendung zu kategorisieren. Vernünftige Auswahl dieser Rollen wird ein zusammenhängender Satz von Klassen führen.
Gibt es eine grundsätzliche Regel, die ganze Rolle Klassenentwurf wiederkehrt: die starke Trennung der Klassen zuständig für Präsentation, Anwendung und Dauerhaftigkeit. Präsentation kann in der Regel werden geboten als Benutzeroberfläche und Persistenz als etwas, in dem Daten (in der Regel in einer Datenbank) gespeichert. Obwohl dies die gleiche Trennung wie für 3-Schichtentwicklung vorhanden ist ist, ist anzumerken, dass dies eine Konzeption-Trennung, die in vielerlei Hinsicht implementiert werden können: als eine einzelne monolithische Anwendung, die alle den Weg durch ein vollständig verteilten Multi-Tier-System. Der Satz von Klassen, aus denen die Anwendungslogik sind diejenigen, die tatsächlich die harte Arbeit der Reaktion auf Reize der Benutzer zu manipulieren und Daten verarbeiten. Eine Teilmenge der Klassen innerhalb dieser Schicht wird als Vertreter der realen Welt-Organisationen, die vom System nach dem Vorbild identifiziert. Diese sind sehr oft als 'Geschäft' oder 'Problemdomäne' Klassen gekennzeichnet. Sie bilden einen wichtiger Teil eines jeden OO-Systems, wie die meisten anderen Klassen sie werden, eine oder andere Weise unterstützen werden, und sie den Fokus aller Entwickler beteiligt bilden.
Ermittlung der Business-Objekte für eine bestimmte Anwendung im Allgemeinen mit Erfahrung, instinktive wird, gibt es zwar eine ganze Wissenschaft (oder ist es Kunst?) hinter den Prozess. Die Schönheit des OO verglichen mit traditionellen Techniken wie SSADM ist, dass die Prozesse von Analyse und Design, die entwickelt haben, die gleichen Einheiten im gesamten pflegen: Es ist möglich, eine Darstellung der jedes Geschäftsobjekt in OOA (Analyse), OOD (Design) und schließlich die Umsetzung selbst (OOP) zu sehen. Wir werden einige der Techniken für die Identifizierung der entsprechenden Geschäftsobjekte in zukünftigen Spalten erforschen. Vorerst, gehen wir davon aus, dass diese Prozesse durchgeführt wurden.
Die Kommunikation zwischen Klassen, die in den verschiedenen Schichten (Präsentation, Anwendung, Persistenz) vorhanden ist wohldefiniert und sollte unbedingt eingehalten werden. Dies wird in Abbildung 1 gezeigt, und die Pfeile zeigen, dass eine Klasse in einer Schicht Methodenaufrufe in einer anderen Klasse machen kann. Dieses Diagramm zeigt, dass die Darstellungsschicht (Benutzerschnittstelle) der Anwendungsschicht oder andere Klassen innerhalb der Benutzeroberfläche bearbeiten kann und die Anwendungsschicht (Business-Objekte) kann selbst zu manipulieren und telefonieren in die Persistenz-Schicht, die aus dem Application Layer nur auf Anfragen reagieren können.
Business-Objekte
Um zu demonstrieren, wie Business-Objekte implementiert werden können, folgen wir einem Berechnungsbeispiel mit einer kleinen Gruppe von Klassen, die die klassischen Lager, Customer- und Order-Entitäten offenlegen (ein Unternehmen bietet eine Anzahl von Elementen der Aktie zu verkaufen, die gekauft werden können (geordnet) von Kunden). Unsere Analyse (trivial) hat bestätigt, dass zunächst wir drei Business-Objekte um jeden dieser Entitäten darzustellen erfordern. In unserer Delphi-Anwendung haben wir drei Klassen: TStockItem, 'tCustomer' und TOrder. Listing 1 zeigt eine gekürzte öffentliche Schnittstelle für diese Klassen. Es ist darauf hinzuweisen, dass alle Attribute der Klasse als Eigenschaften verfügbar gemacht werden: Dies ist einfach gut Klasse Design und erleichtert die Kontrolle über den Zugriff auf die Eigenschaften (sollte dies erforderlich sein). Auch ist darauf hinzuweisen, dass die Eigenschaften im Abschnitt veröffentlichte der Klasse (aus Gründen, die wir, in Zukunft diskutieren werden) ausgesetzt sind und sie gegebenenfalls mit Standardwerten vollständig qualifiziert sind. Obwohl dieser Eigenschaft Qualifizierer angeblich beim streaming von Komponenten verwendet wird, es dient einem nützlichen Zweck um den Anfangswert der einzelnen Eigenschaften zu kennzeichnen und hilft den Code selbst beschreibende sein.
Etwas, das grundlegend für Geschäftsobjekte (Problemdomäne) ist, dass sie keine Kenntnis von wie sie dauerhaft gespeichert werden können. Sie wissen nicht, wie sie in Datenbanktabellen gespeichert sind, in der Tat können sie absolut keine Annahmen über Speicherung jeglicher Art. Ein Geschäftsobjekt ist sehr konzentriert-Klasse, die nur entsprechende Eigenschaften und die Methoden zu manipulieren verfügbar macht. Bei der Gestaltung der öffentlichen Schnittstelle der Klasse sollten keine Konzession hinsichtlich der Typen der Eigenschaften für die beständige (Datenbank) Speicherung erfolgen. Sie sollten immer auswählen, den am besten geeigneten Typ für die Eigenschaft betrifft, unabhängig davon, ob die beabsichtigte Datenbank sie nativ unterstützt. Ein gutes Beispiel ist eine Set-Eigenschaft: Einige Datenbanken unterstützen Sätze direkt, aber ist dies eine natürliche Art und Weise verfügbar zu machen eine Eigenschaft eines Geschäftsobjekts dann es sollte gewählt werden anstelle einer anderen Darstellung (möglicherweise mehrere boolesche Werte). Ein weiteres Beispiel ist so etwas wie eine Adresse als eine TStringList verfügbar zu machen. Es ist nicht Aufgabe des Geschäftsobjekts es Schnittstelle Datenbankspeicherung begünstigen nicht beeinträchtigen: Dies ist die Aufgabe der Persistenz-Schicht.
Unsere erste framework
Wir haben erkannt und drei Business-Objekte als erste Basis für unsere Anwendung implementiert. Diese drei Objekte nutzen eine gemeinsame Rolle: zu realen Personen in irgendeiner Weise vertreten. Wir erwarten daher, dass sie ähnliche Eigenschaften haben und daher eine Klassenhierarchie ist angebracht. Wir geben jedes dieser Objekte einen gemeinsamen Vorfahren, genannt TPDObject (für Problem Domain-Objekt). Diese TPDObject-Klasse wird im Laufe der Zeit erweitert werden, wenn wir gemeinsame Methoden und Eigenschaften unserer Klassen einführen. Es sei darauf hingewiesen, dass TPDObject keine Applikations-spezifische Elemente enthalten (und wird es nie). Als ein Konstrukt anwendungsunabhängig es sollte in einer separaten Einheit platziert werden und bildet die Grundlage eines Rahmens: eine Reihe von Klassen, die in vielen Anwendungen wiederverwendet werden können. Im Laufe der Zeit wird unser Framework stark erweitert, viele Basisklassen bereitstellen, die erhebliche anwendungsunabhängig Funktionalitäten bereit, die für bestimmte Systeme spezialisiert werden bereitzustellen. Unsere Klassen TStockItem, 'tCustomer' und TOrder sind Beispiele für spezialisierte Versionen unserer generische TPDObject. Eine nähere Untersuchung von Listing 1 zeigt, dass in der Tat unsere drei Übungsleiter Domäne jeweils von einer anderen Klasse, TMyAppPDObject, selbst abstammen ein Nachkomme des TPDObject. Obwohl die Umsetzung der TMyAppPDObject leer ist, ist es ein weiteres Beispiel für gute Klassenentwurf, damit wollen wir anwendungsspezifische Elemente zu bieten alles von unserem Problem Domain-Objekten gibt ist eine entsprechende Klasse in unsere Hierarchie.
Listing 2 zeigt unsere embryonale Framework-Einheit. Im Moment stellt die TPDObject-Klasse nur eine schreibgeschützte Eigenschaft mit dem Namen ID, die vom Typ TObjectID ist. Diese Eigenschaft wird verwendet, um eine Unterrichtsstunde geben den Begriff der Identität: zwei Instanzen definieren wir als das gleiche Objekt darstellt, wenn sie vom gleichen Typ sind und den gleichen ID-Wert haben. Dies wurde bewusst wie es eigene Art ist, so dass es nicht direkt zuweisungskompatibel mit anderen skalaren Typen definiert. Die Auswahl des Typs für den TObjectID ist willkürlich: Ich habe mich entschieden in diesem Fall zu machen, einen ganzzahligen Typ, aber es gibt einen Fall zu machen, es ist Klasse. Obwohl eine weitere 'reine' Ansatz, habe ich dagegen auf der Grundlage beschlossen, dass unser Problem Domain-Objekte werden gebaut (und zerstört) mehrere tausend Mal während einer Anwendung und können wir den Aufwand für den Bau und die Zerstörung der Extraklasse TObjectID (mein puristisch-Argument für diese Umsetzung-Wahl ist, dass die separate TObjectID-Klasse in der TPDObject-Klasse als zusammengesetzte Objekt subsumiert worden hat) vermeiden. Es gibt einige zusätzliche Methoden in dieser Einheit um unsere Identität Objekttyp in eine String-Darstellung und eine Konstante 'hat keine Identität' Anfangswert zu konvertieren.
Es gibt eine Reihe von Denkschulen auf Objektidentität; man sagt, dass alle Geschäftsobjekte eine Identität zugewiesen werden soll, wenn er erstellt wird und die Identität eindeutig innerhalb einer Anwendung (oder sogar weltweit wie in eine GUID) sein sollte. In der Praxis ist es wichtig nur zwischen zwei Objekten in einem bestimmten Kontext unterscheiden können, und dies einfach zu halten, hat offensichtlich Leistung und Vorteile, obwohl Sie sicherlich nicht mich argumentiert gegen eine Wahl für ein komplexer Typ unter geeigneten Umständen finden.
Eine Frage der Ethik
Um einige der Entwurfsaspekte und Umsetzung hervorzuheben entwerfen einen Rahmen werde ich gelegentlich Entscheidungen wenn Fragen stellen und laden die Leser die Logik dahinter zu berücksichtigen. Am Anfang der Spalte spielte ich auf eine bedeutende Ausnahme zu der Aussage, dass eine wirklich OO-Design nicht die Verwendung von bestimmten Klassen verbieten. Was ist die Ausnahme zu dieser Aussage (Tipp: die Antwort liegt in der Abbildung 1).
(((Listing 1 - eine anwendungsspezifische Problemdomäne Einheit (gekürzt))))
Einheit ProblemDomain;
Schnittstelle
verwendet
Rahmen;
Typ
TMyAppPDObject = Class (TPDObject)
Ende;
TStockItem = Class (TMyAppPDObject)
veröffentlicht
Eigenschaft Name: String;
Eigenschaft QuantityInStock: Kardinal Voreinstellung 0;
Eigenschaft TradePrice: Währung;
Eigenschaft Verkaufspreis: Währung;
Ende;
'TCustomer' = Class (TMyAppPDObject)...;
TOrder = Class (TMyAppPDObject)...;
Umsetzung
Ende.
(((Ende Codebeispiel 1)))
(((Listing 2 - ein anwendungsunabhängiger Framework Einheit)))
Einheit Framework;
Schnittstelle
const
NotAssigned = 0;
Typ
TObjectID = Typ Integer;
TPDObject = Klasse
Private
FID: TObjectID;
öffentliche
Objekt-ID: TObjectID lesen FID Standard NotAssigned;
Ende;
Funktion StrToID (Value: String): TObjectID;
Funktion IDToStr (Wert: TObjectID): String;
Umsetzung
...
Ende.
(((Ende Codebeispiel 2)))
(((Abbildung 1 - Klassenübersicht Interaktion)))
(((Ende Abbildung 1)))
Weiter in Serie
Implementierung von Business-Objekten
By Wiezutun
Implementierung von Business-Objekten : Mehreren tausend Tipps, um Ihr Leben einfacher machen.