Arbeiten mit Gruppen von Geschäftsobjekten
In diesem Artikel erläutert eine Arbeitsweise mit Sets von Business objects
Die Bedürfnisse der vielen
In diesem Artikel, die wir in der Welt von einem Allzweck-Objektumgebung zurück und komplette Beziehung Abwicklung unter Berücksichtigung der Arbeit mit Sets oder Sammlungen von Business Objects. Bisher haben wir gesehen, wie einfache 1-1 oder n: 1-Beziehungen ausdrücken, indem einfach das verknüpfte Objekt als eine Eigenschaft, z. B. Order.Customer ausgesetzt. Ist dies eine einfache und natürliche Weise verwandte Objekte mit den richtigen Umgang innerhalb der Accessor-Funktionen der Eigenschaft verfügbar zu machen, aber wie können wir die anderen Varianten von Beziehungen, nämlich 1: n oder n verfügbar machen? Ein einfacher Ansatz, wie Customer.Order, dient nicht unser Ziel, da es bedeutet, dass es ein Auftrag für einen bestimmten Kunden (was im Allgemeinen nicht der Fall ist), und verhindert den Zugriff auf andere Aufträge, die möglicherweise vorhanden sind. Was wir brauchen, ist Syntax und eine effiziente Implementierung, für die Behandlung einer Reihe von Business Objects.
Wenn wir darüber, auf eine andere Weise Nachdenken brauchen wir ein Allzweck-Mittel für den Umgang mit solch einer Menge von Objekten. In der Praxis sowie eine kleine Sammlung von Objekten (z. B. die Liste der Bestellungen für einen bestimmten Kunden, die in der Regel höchstens ein paar hundert Einträge bestehen würde) wollen auch wir große Sammlungen von Objekten, z. B. die Liste aller Elemente der Aktie zu unterstützen. Wie wir in einer Objekt-orientierten Welt tätig sind, ist die logische Schlussfolgerung, dass wir eine neue Klasse benötigt werden, die eine Reihe von Business-Objekten verfügbar macht. Dies nennen wir gehen mit unserer Klasse TPDObject Klasse TPDList (eine Liste der Problemdomäne Objekte). Der Name ist willkürlich, und einige mögen denken, dass dieser eine bestimmte Implementierung impliziert. Leider haben die Alternativen wie 'set' und 'Collection' bereits ähnliche Auswirkungen innerhalb der Delphi-Welt.
Syntaktischer Zucker
Eine syntaktisch angenehme und natürliche Weise des Umgangs mit einer Menge von Objekten wäre diese Anwendung irgendeiner Art von Array, offen legen, wie in Listing 1 gezeigt. Solch eine Klassendefinition würde ermöglichen uns Zugriff auf die Objekte, die Konstrukte in unserem Code wie Customer.Orders [], die sehr vertraut ist. Es gibt jedoch zwei bedeutende Nachteile dieses Ansatzes: es bedeutet, dass wir wissen, wie viele Objekte in der Liste sind, und dass sie alle verfügbaren Verbrennungsgases Direktzugriff Typ. Ist es der einzige Weg um sicherzustellen, werden diese Voraussetzungen erfüllt sind, vollständig Auffüllen der Liste oder zumindest vollständig Auffüllen einer internen Liste des Objekts ID's und jedes Objekt einzeln zu laden, wie darauf zugegriffen wird. Der Nachteil der erste Ansatz ist übermäßiger Speicherverbrauch und eine möglicherweise deutliche Verzögerung, während viele Objekte instanziiert werden, und die Kehrseite der zweite Ansatz die Ineffizienz ist der Erteilung einer Rekord Belastung für jedes Objekt zugegriffen (durchlaufen eine Reihe von 100 Objekten erfordern würde 100 Datenbankabfragen ausgestellt werden).
Also, legt trotz der syntaktischen Vorteile des Arrays Ansatz nicht optimal für den allgemeinen Fall ist natürlich ein Framework zur Unterstützung von zwei (oder mehr) verschiedener Möglichkeiten der Behandlung verlängert werden könnte Objekte für kleine und für große. Persönlich ich bin ein großer Fan von Konsistenz und lieber dort zu einer einheitlichen Syntax für die Arbeit mit Gruppen von Objekten. Da wir in einem späteren Artikel sehen, hindert das uns nicht mit einer Reihe von Implementierungen für diese Syntax für verschiedene Umstände abgestimmt.
Unsere Objekte werden an den grundlegenden Ebene von persistenten Speichermechanismus, in der Regel eine Datenbank aufgefüllt werden. Die meisten Daten in diesen Tagen erfolgt über eine Abfrage (SQL) und wenn man bedenkt, dass die Eigenschaften dieser Elemente sind in der Regel in der Lage, uns mit den 'nächsten' konzeptionelle Datensatz und bestimmen, wann die Liste abgearbeitet ist. Informationen wie die Anzahl der Datensätze in der Liste oder wahlfreien Zugriff auf sie, ist in der Regel nicht verfügbar. Unser Framework sollte so gestaltet werden, mit Leistung und Client Anwendung Ressourcenanforderungen im Auge, so dass eine vorgeschlagene Schnittstelle für unsere TPDList in Listing 2 dargestellt ist. Dies bietet uns eine erste Methode (Neuinitialisierung zurück an den Anfang die Liste), weiter (das nächste Objekt in der Liste Zugriff) und eine IsLast-Eigenschaft (gibt an, wann die Liste leer ist). Das 'aktuelle' Objekt in der Liste ist durch eine entsprechend benannte Eigenschaft vorhanden. Diese Schnittstelle kann unnötig einfach scheinen; wo sind die Methoden zur Navigation rückwärts zu unterstützen? Erfahrung zeigt, dass die umgekehrte Navigation in einer Liste nur sehr selten erforderlich ist, und wo es ist, durch andere Konstrukte leicht erreicht werden kann. Vorerst, halten wir unsere Liste Management Klasse einfach.
Wie ist diese Klasse implementiert werden? Als haben vor, unser Problem Domäne (Geschäftsobjekt) Schicht kein Konzept, wie Daten gespeichert oder verwaltet werden. Unsere TPDList verwaltet eine Auflistung von Geschäftsobjekten und also kein einfachen Wrapper etwas wie Datenbank-spezifische wie eine Datenbankabfrage. Stattdessen wir Entwerfen einer anderen Klasse, die Datenbankunterstützung für Listen von Objekten zu behandeln, und bieten eine objektbasierte datenbankunabhängige Schnittstelle zwischen unseren TPDList und dieser Klasse. Auf diese Weise haben wir gehalten die strikte Trennung zwischen der Geschäftsschicht und Daten-Management-Layer erlaubt uns Installationslautsprecher wie letztere verwaltet wird.
Süßung der Pille
Genauso wie unsere TPDObject eine TDMObject Daten Verwaltung logische Folge hatte, mag es scheinen, dass unsere TPDList ein TDMList Äquivalent haben sollte. In der Praxis gibt es eine große Menge an Gemeinsamkeit zwischen zwei Daten-Management-Klassen, und sie können in einer einzelnen Klasse zusammengefasst werden. Es mag logisch, eine Klassenhierarchie mit einem gemeinsamen Vorfahren für die gemeinsame Funktionalität und Nachkommen, einzelne Instanzen und Listen zu behandeln haben, aber dies erzwingt einen Schreiben von Code-Overhead, wenn es um die Umsetzung tatsächlich unsere Anwendung mit wenig nutzen. Daher verlängern wir unsere TDMObject zur Liste Operationen zur Unterstützung, sowie die vorhandenen Einzelinstanz Load und Save.
Jede TPDList wird daher eine private TDMObject besitzen, die nur für die Verwaltung der Datenzugriff für die Liste der Objekte verantwortlich ist. Die 'aktuelle' TPDObject der Liste aufgeführt, wird den 'aktuellen' Datensatz in der Datenbankcursor imitieren. Benötigen wir eine einzigartige (und privaten) Daten-Management-Objekt für jede TPDList weil es braucht, um Zustand (Abfrageinformationen, aktuelle Cursor Datensatz usw.) erhalten. Im Gegensatz dazu können Problem Domain-Objekte derselben Klasse ein einzelnes Datenobjekt Verwaltung teilen, da die Load und Save-Methoden statusfrei Operationen sind.
Unsere TDMObject kann jetzt erweitert werden, um die erforderlichen Operationen zu unterstützen. Es müssen FirstRecord und NextRecord Methoden (um anzugeben, es ist datensatzbasiertes Natur), und eine IsLastRecord-Eigenschaft, um anzugeben, wenn der Cursor erschöpft ist (der Cursor werden für das Verwaltungsobjekt Daten privat und um einige Datenbank-abhängige Abfragemechanismus basiert). Die Methoden in unserem TPDList einfach delegiert die Arbeit aus auf die Daten verwalten Objekt, fordern diese ähnliche Methoden benannt. Die TPDList fragt das Verwaltungsobjekt private Daten ihr ein Domain-Objekt instanziiert Problem wie der Client Anwendung schrittweise bereitzustellen. Der Code für dieses Objekt aus dem Abfrage-Cursor auffüllen sollten mit, die geteilt werden, für ein einzelnes Objekt in der Load-Routine auffüllen.
Wir haben jetzt eine Klasse, die uns erlaubt, durch eine Reihe von Problem Domain-Objekten zu navigieren haben, und wir unsere Daten-Management-Klasse um diese Vorgänge zu unterstützen. Was wir noch nicht geschehen ist, wie verschiedene Sätze von Objekten definieren sollte definiert werden. Schließlich gibt es viele unterschiedliche Sätze von Objekten, die unsere Anwendung erfordern; wir möglicherweise die Gruppe von Kunden, die einen bestimmten Lagerteil bestellt haben, könnten wir die Kunden namens 'SMITH' benötigen oder wir könnten den Satz aller Kunden (für Berichtszwecke) brauchen. Eine offensichtliche Weise, diese verschiedenen Sets zu definieren, die wir möglicherweise soll benutzerdefinierte Konstruktoren definieren. Listing 3 zeigt die öffentliche Schnittstelle für ein Beispiel TCustomerList, die eine Reihe von Kunden verwaltet. Sie werden auch sehen, dass es eine Customer-Eigenschaft verfügbar macht; Dies gibt einfach die CurrentObject statisch Typumwandlung zu einem 'tCustomer' (wir kennen und erwarten, dass alle Objekte in der Liste dieser Art zu sein, es ist also ein gefahrloser Betrieb und vermeidet Platzierung innerhalb der Hauptanwendung Logik Typumwandlung). Einige Ultra-purist OO Befürworter könnten behaupten, dass anstatt benutzerdefinierte Konstruktoren, die eine Klassenhierarchie erstellt werden soll, die mit einer neuen Klasse für jede Art von Liste erforderlich. Ich sehe persönlich wenig Nutzen in diesem Ansatz, wenn die besonderen Objekte gesetzt erfordert einige besonders involviert Behandlung, die für eine bestimmte Liste-Implementierung privat bleiben muss, und dieser Ansatz hat den Nachteil, erfordern eine beträchtliche Menge an Code geschrieben werden und konsequente Klasse Vermehrung.
Wir können jetzt mit Listen von Kunden umgehen, einfach durch den Bau eines TCustomerList in den geeignetsten Weg. Unsere Anwendungs-Code könnte wie folgt aussehen:
var
CustomerList: TCustomerList;
beginnen
CustomerList: = TCustomerList.CreateByName ('SMITH');
versuchen Sie
CustomerList.First;
während nicht CustomerList.IsLast fangen
Tun Sie etwas mit CustomerList.Customer Objekt
CustomerList.Next;
Ende;
Schließlich
CustomerList.Free;
Ende;
Ende;
Mit dieser Art von Logik innerhalb der Anwendung ist viel klarer als die gleichwertigen Verfahrensmöglichkeiten der Erstellung von Datenbank-spezifische Abfragen und Verwenden von Feldern direkt. Insbesondere haben wir all diese Details in unseren Daten-Management-Klasse gekapselt und dieser Code Zentralisierung ermöglicht uns den Luxus, zu wissen, dass die Chancen für eine ungültige Tabelle referenzieren oder Feldnamen werden erheblich reduziert.
Bisher haben wir in unserer Verwaltungsobjekte Liste nicht die tatsächliche Implementierung der benutzerdefinierten Konstruktoren angegeben. Wie bereits erwähnt diese Klassen sitzen konsequent in unsere Geschäftslogik der Anwendung und müssen daher vollständig datenbankunabhängig. Insbesondere können nicht diese Konstruktoren mit SQL-Abfragen oder ähnlichem Aufbau beteiligt sein. Solche Details sind in den Zuständigkeitsbereich der Rolle für unsere Daten-Management-Klasse, und also die entsprechenden TDMObject für jede Klasse erwerben die benutzerdefinierte Konstruktoren, jeweils genau passenden Namen und Parameter für das TPDList-Objekt, für das es zuständig ist. Nächsten Monat wir werde runden diese Behandlung durch einige Implementierungsdetails betrachten und zeigen, wie Verfeinerungen in unserer Klasse design und die Macht der Polymorphie, führt zu sehr reduzierten Code schreiben für unsere benutzerdefinierte Anwendungsklassen.
In diesem Artikel Frage
Möglichkeit, Objekte zu verarbeiten ist der Baustein für die Behandlung von Objektbeziehungen. Wie können wir ihnen zur Unterstützung von 1: n-Beziehungen wie Customer.Orders und unterstützen wir diese Konstrukte generisch auf die gleiche Weise, die wir für 1-1 und n: 1-Beziehungen haben?
(((Listing 1 - Array-basierte TPDList-Schnittstelle)))
Typ
TPDList = Klasse
öffentliche
Eigenschaft ObjectAtIndex [Index: Integer]: TPDObject; in der Standardeinstellung;
Eigenschaft Count: Integer;
Ende;
(((Ende Codebeispiel 1)))
(((Listing 2 - Navigations-TPDList-Schnittstelle)))
Typ
TPDList = Klasse
öffentliche
Verfahren erster;
Verfahren weiter;
Eigenschaft CurrentObject: TPDObject;
Eigenschaft IsLast: Boolean;
Ende;
(((Ende Codebeispiel 2)))
(((Listing 3 - Beispiel TCustomerList publicinterface)))
Typ
TCustomerList = Class (TPDList)
Private
Ergebnis: = 'tCustomer' (CurrentObject);
GetCustomer-Funktion: 'tCustomer';
öffentliche
Konstruktor CreateAll;
Konstruktor CreateByName (const Name: String);
Konstruktor CreateByStockOrder (Item: TStockItem);
Eigenschaft Kunde: 'tCustomer' lesen GetCustomer;
Ende;
(((Ende Codebeispiel 3)))
Weiter in Serie
Arbeiten mit Gruppen von Geschäftsobjekten
Arbeiten mit Gruppen von Geschäftsobjekten : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
In diesem Artikel erläutert eine Arbeitsweise mit Sets von Business objects
Die Bedürfnisse der vielen
In diesem Artikel, die wir in der Welt von einem Allzweck-Objektumgebung zurück und komplette Beziehung Abwicklung unter Berücksichtigung der Arbeit mit Sets oder Sammlungen von Business Objects. Bisher haben wir gesehen, wie einfache 1-1 oder n: 1-Beziehungen ausdrücken, indem einfach das verknüpfte Objekt als eine Eigenschaft, z. B. Order.Customer ausgesetzt. Ist dies eine einfache und natürliche Weise verwandte Objekte mit den richtigen Umgang innerhalb der Accessor-Funktionen der Eigenschaft verfügbar zu machen, aber wie können wir die anderen Varianten von Beziehungen, nämlich 1: n oder n verfügbar machen? Ein einfacher Ansatz, wie Customer.Order, dient nicht unser Ziel, da es bedeutet, dass es ein Auftrag für einen bestimmten Kunden (was im Allgemeinen nicht der Fall ist), und verhindert den Zugriff auf andere Aufträge, die möglicherweise vorhanden sind. Was wir brauchen, ist Syntax und eine effiziente Implementierung, für die Behandlung einer Reihe von Business Objects.
Wenn wir darüber, auf eine andere Weise Nachdenken brauchen wir ein Allzweck-Mittel für den Umgang mit solch einer Menge von Objekten. In der Praxis sowie eine kleine Sammlung von Objekten (z. B. die Liste der Bestellungen für einen bestimmten Kunden, die in der Regel höchstens ein paar hundert Einträge bestehen würde) wollen auch wir große Sammlungen von Objekten, z. B. die Liste aller Elemente der Aktie zu unterstützen. Wie wir in einer Objekt-orientierten Welt tätig sind, ist die logische Schlussfolgerung, dass wir eine neue Klasse benötigt werden, die eine Reihe von Business-Objekten verfügbar macht. Dies nennen wir gehen mit unserer Klasse TPDObject Klasse TPDList (eine Liste der Problemdomäne Objekte). Der Name ist willkürlich, und einige mögen denken, dass dieser eine bestimmte Implementierung impliziert. Leider haben die Alternativen wie 'set' und 'Collection' bereits ähnliche Auswirkungen innerhalb der Delphi-Welt.
Syntaktischer Zucker
Eine syntaktisch angenehme und natürliche Weise des Umgangs mit einer Menge von Objekten wäre diese Anwendung irgendeiner Art von Array, offen legen, wie in Listing 1 gezeigt. Solch eine Klassendefinition würde ermöglichen uns Zugriff auf die Objekte, die Konstrukte in unserem Code wie Customer.Orders [], die sehr vertraut ist. Es gibt jedoch zwei bedeutende Nachteile dieses Ansatzes: es bedeutet, dass wir wissen, wie viele Objekte in der Liste sind, und dass sie alle verfügbaren Verbrennungsgases Direktzugriff Typ. Ist es der einzige Weg um sicherzustellen, werden diese Voraussetzungen erfüllt sind, vollständig Auffüllen der Liste oder zumindest vollständig Auffüllen einer internen Liste des Objekts ID's und jedes Objekt einzeln zu laden, wie darauf zugegriffen wird. Der Nachteil der erste Ansatz ist übermäßiger Speicherverbrauch und eine möglicherweise deutliche Verzögerung, während viele Objekte instanziiert werden, und die Kehrseite der zweite Ansatz die Ineffizienz ist der Erteilung einer Rekord Belastung für jedes Objekt zugegriffen (durchlaufen eine Reihe von 100 Objekten erfordern würde 100 Datenbankabfragen ausgestellt werden).
Also, legt trotz der syntaktischen Vorteile des Arrays Ansatz nicht optimal für den allgemeinen Fall ist natürlich ein Framework zur Unterstützung von zwei (oder mehr) verschiedener Möglichkeiten der Behandlung verlängert werden könnte Objekte für kleine und für große. Persönlich ich bin ein großer Fan von Konsistenz und lieber dort zu einer einheitlichen Syntax für die Arbeit mit Gruppen von Objekten. Da wir in einem späteren Artikel sehen, hindert das uns nicht mit einer Reihe von Implementierungen für diese Syntax für verschiedene Umstände abgestimmt.
Unsere Objekte werden an den grundlegenden Ebene von persistenten Speichermechanismus, in der Regel eine Datenbank aufgefüllt werden. Die meisten Daten in diesen Tagen erfolgt über eine Abfrage (SQL) und wenn man bedenkt, dass die Eigenschaften dieser Elemente sind in der Regel in der Lage, uns mit den 'nächsten' konzeptionelle Datensatz und bestimmen, wann die Liste abgearbeitet ist. Informationen wie die Anzahl der Datensätze in der Liste oder wahlfreien Zugriff auf sie, ist in der Regel nicht verfügbar. Unser Framework sollte so gestaltet werden, mit Leistung und Client Anwendung Ressourcenanforderungen im Auge, so dass eine vorgeschlagene Schnittstelle für unsere TPDList in Listing 2 dargestellt ist. Dies bietet uns eine erste Methode (Neuinitialisierung zurück an den Anfang die Liste), weiter (das nächste Objekt in der Liste Zugriff) und eine IsLast-Eigenschaft (gibt an, wann die Liste leer ist). Das 'aktuelle' Objekt in der Liste ist durch eine entsprechend benannte Eigenschaft vorhanden. Diese Schnittstelle kann unnötig einfach scheinen; wo sind die Methoden zur Navigation rückwärts zu unterstützen? Erfahrung zeigt, dass die umgekehrte Navigation in einer Liste nur sehr selten erforderlich ist, und wo es ist, durch andere Konstrukte leicht erreicht werden kann. Vorerst, halten wir unsere Liste Management Klasse einfach.
Wie ist diese Klasse implementiert werden? Als haben vor, unser Problem Domäne (Geschäftsobjekt) Schicht kein Konzept, wie Daten gespeichert oder verwaltet werden. Unsere TPDList verwaltet eine Auflistung von Geschäftsobjekten und also kein einfachen Wrapper etwas wie Datenbank-spezifische wie eine Datenbankabfrage. Stattdessen wir Entwerfen einer anderen Klasse, die Datenbankunterstützung für Listen von Objekten zu behandeln, und bieten eine objektbasierte datenbankunabhängige Schnittstelle zwischen unseren TPDList und dieser Klasse. Auf diese Weise haben wir gehalten die strikte Trennung zwischen der Geschäftsschicht und Daten-Management-Layer erlaubt uns Installationslautsprecher wie letztere verwaltet wird.
Süßung der Pille
Genauso wie unsere TPDObject eine TDMObject Daten Verwaltung logische Folge hatte, mag es scheinen, dass unsere TPDList ein TDMList Äquivalent haben sollte. In der Praxis gibt es eine große Menge an Gemeinsamkeit zwischen zwei Daten-Management-Klassen, und sie können in einer einzelnen Klasse zusammengefasst werden. Es mag logisch, eine Klassenhierarchie mit einem gemeinsamen Vorfahren für die gemeinsame Funktionalität und Nachkommen, einzelne Instanzen und Listen zu behandeln haben, aber dies erzwingt einen Schreiben von Code-Overhead, wenn es um die Umsetzung tatsächlich unsere Anwendung mit wenig nutzen. Daher verlängern wir unsere TDMObject zur Liste Operationen zur Unterstützung, sowie die vorhandenen Einzelinstanz Load und Save.
Jede TPDList wird daher eine private TDMObject besitzen, die nur für die Verwaltung der Datenzugriff für die Liste der Objekte verantwortlich ist. Die 'aktuelle' TPDObject der Liste aufgeführt, wird den 'aktuellen' Datensatz in der Datenbankcursor imitieren. Benötigen wir eine einzigartige (und privaten) Daten-Management-Objekt für jede TPDList weil es braucht, um Zustand (Abfrageinformationen, aktuelle Cursor Datensatz usw.) erhalten. Im Gegensatz dazu können Problem Domain-Objekte derselben Klasse ein einzelnes Datenobjekt Verwaltung teilen, da die Load und Save-Methoden statusfrei Operationen sind.
Unsere TDMObject kann jetzt erweitert werden, um die erforderlichen Operationen zu unterstützen. Es müssen FirstRecord und NextRecord Methoden (um anzugeben, es ist datensatzbasiertes Natur), und eine IsLastRecord-Eigenschaft, um anzugeben, wenn der Cursor erschöpft ist (der Cursor werden für das Verwaltungsobjekt Daten privat und um einige Datenbank-abhängige Abfragemechanismus basiert). Die Methoden in unserem TPDList einfach delegiert die Arbeit aus auf die Daten verwalten Objekt, fordern diese ähnliche Methoden benannt. Die TPDList fragt das Verwaltungsobjekt private Daten ihr ein Domain-Objekt instanziiert Problem wie der Client Anwendung schrittweise bereitzustellen. Der Code für dieses Objekt aus dem Abfrage-Cursor auffüllen sollten mit, die geteilt werden, für ein einzelnes Objekt in der Load-Routine auffüllen.
Wir haben jetzt eine Klasse, die uns erlaubt, durch eine Reihe von Problem Domain-Objekten zu navigieren haben, und wir unsere Daten-Management-Klasse um diese Vorgänge zu unterstützen. Was wir noch nicht geschehen ist, wie verschiedene Sätze von Objekten definieren sollte definiert werden. Schließlich gibt es viele unterschiedliche Sätze von Objekten, die unsere Anwendung erfordern; wir möglicherweise die Gruppe von Kunden, die einen bestimmten Lagerteil bestellt haben, könnten wir die Kunden namens 'SMITH' benötigen oder wir könnten den Satz aller Kunden (für Berichtszwecke) brauchen. Eine offensichtliche Weise, diese verschiedenen Sets zu definieren, die wir möglicherweise soll benutzerdefinierte Konstruktoren definieren. Listing 3 zeigt die öffentliche Schnittstelle für ein Beispiel TCustomerList, die eine Reihe von Kunden verwaltet. Sie werden auch sehen, dass es eine Customer-Eigenschaft verfügbar macht; Dies gibt einfach die CurrentObject statisch Typumwandlung zu einem 'tCustomer' (wir kennen und erwarten, dass alle Objekte in der Liste dieser Art zu sein, es ist also ein gefahrloser Betrieb und vermeidet Platzierung innerhalb der Hauptanwendung Logik Typumwandlung). Einige Ultra-purist OO Befürworter könnten behaupten, dass anstatt benutzerdefinierte Konstruktoren, die eine Klassenhierarchie erstellt werden soll, die mit einer neuen Klasse für jede Art von Liste erforderlich. Ich sehe persönlich wenig Nutzen in diesem Ansatz, wenn die besonderen Objekte gesetzt erfordert einige besonders involviert Behandlung, die für eine bestimmte Liste-Implementierung privat bleiben muss, und dieser Ansatz hat den Nachteil, erfordern eine beträchtliche Menge an Code geschrieben werden und konsequente Klasse Vermehrung.
Wir können jetzt mit Listen von Kunden umgehen, einfach durch den Bau eines TCustomerList in den geeignetsten Weg. Unsere Anwendungs-Code könnte wie folgt aussehen:
var
CustomerList: TCustomerList;
beginnen
CustomerList: = TCustomerList.CreateByName ('SMITH');
versuchen Sie
CustomerList.First;
während nicht CustomerList.IsLast fangen
Tun Sie etwas mit CustomerList.Customer Objekt
CustomerList.Next;
Ende;
Schließlich
CustomerList.Free;
Ende;
Ende;
Mit dieser Art von Logik innerhalb der Anwendung ist viel klarer als die gleichwertigen Verfahrensmöglichkeiten der Erstellung von Datenbank-spezifische Abfragen und Verwenden von Feldern direkt. Insbesondere haben wir all diese Details in unseren Daten-Management-Klasse gekapselt und dieser Code Zentralisierung ermöglicht uns den Luxus, zu wissen, dass die Chancen für eine ungültige Tabelle referenzieren oder Feldnamen werden erheblich reduziert.
Bisher haben wir in unserer Verwaltungsobjekte Liste nicht die tatsächliche Implementierung der benutzerdefinierten Konstruktoren angegeben. Wie bereits erwähnt diese Klassen sitzen konsequent in unsere Geschäftslogik der Anwendung und müssen daher vollständig datenbankunabhängig. Insbesondere können nicht diese Konstruktoren mit SQL-Abfragen oder ähnlichem Aufbau beteiligt sein. Solche Details sind in den Zuständigkeitsbereich der Rolle für unsere Daten-Management-Klasse, und also die entsprechenden TDMObject für jede Klasse erwerben die benutzerdefinierte Konstruktoren, jeweils genau passenden Namen und Parameter für das TPDList-Objekt, für das es zuständig ist. Nächsten Monat wir werde runden diese Behandlung durch einige Implementierungsdetails betrachten und zeigen, wie Verfeinerungen in unserer Klasse design und die Macht der Polymorphie, führt zu sehr reduzierten Code schreiben für unsere benutzerdefinierte Anwendungsklassen.
In diesem Artikel Frage
Möglichkeit, Objekte zu verarbeiten ist der Baustein für die Behandlung von Objektbeziehungen. Wie können wir ihnen zur Unterstützung von 1: n-Beziehungen wie Customer.Orders und unterstützen wir diese Konstrukte generisch auf die gleiche Weise, die wir für 1-1 und n: 1-Beziehungen haben?
(((Listing 1 - Array-basierte TPDList-Schnittstelle)))
Typ
TPDList = Klasse
öffentliche
Eigenschaft ObjectAtIndex [Index: Integer]: TPDObject; in der Standardeinstellung;
Eigenschaft Count: Integer;
Ende;
(((Ende Codebeispiel 1)))
(((Listing 2 - Navigations-TPDList-Schnittstelle)))
Typ
TPDList = Klasse
öffentliche
Verfahren erster;
Verfahren weiter;
Eigenschaft CurrentObject: TPDObject;
Eigenschaft IsLast: Boolean;
Ende;
(((Ende Codebeispiel 2)))
(((Listing 3 - Beispiel TCustomerList publicinterface)))
Typ
TCustomerList = Class (TPDList)
Private
Ergebnis: = 'tCustomer' (CurrentObject);
GetCustomer-Funktion: 'tCustomer';
öffentliche
Konstruktor CreateAll;
Konstruktor CreateByName (const Name: String);
Konstruktor CreateByStockOrder (Item: TStockItem);
Eigenschaft Kunde: 'tCustomer' lesen GetCustomer;
Ende;
(((Ende Codebeispiel 3)))
Weiter in Serie
Arbeiten mit Gruppen von Geschäftsobjekten
By Wiezutun
Arbeiten mit Gruppen von Geschäftsobjekten : Mehreren tausend Tipps, um Ihr Leben einfacher machen.