Dynamische Navigation für höhere Leistung

Dynamische Navigation für höhere Leistung


Reduzieren oder Entfernen von Navigationscode über die GUI, durch Hinzufügen von abgeleiteten Links und gleichzeitig die Leistung zu verbessern.

Modellierung Klassenstrukturen nimmt einige denken, und wenn das Denken und die Zeichnung fertig und danach starten mit dem Modell, dann verbringen Sie schrecklich viel Code durchlaufen Verknüpfungen um triviale Informationen in einer Struktur angegebene Objekt abzurufen. Navigieren immer und immer wieder die gleichen manchmal komplizierten Verbindung-Pfade nimmt CPU-Leistung und es braucht auch viel redundanten Code bzw. Ausdrücke, die Zugriff auf die gleichen Navigationspfade immer und immer wieder. Im Reich Architektur auch platzieren Sie redundante Abonnements aus vielen verschiedenen Orten zum selben Ziel abonniert die die gleichen Pfade über ein über wieder.

Aber mit Fett können oft direkt adressieren unnötige Navigation, die redundante Navigations/Ocl-Codeausdrücke und Abnahme der CPU-Auslastung durch Hinzufügen von abgeleiteten Verbände stattdessen machen die paar persistenten Verbindungen, nützlicher und 'intelligente' gewinnen. Und darüber hinaus dadurch direkt in Ihrem Modell Modell wird zur gleichen Zeit reflektieren genauer gesagt welche Teile des Modells tatsächlich verwendet wird. Und wie.

Ein Beispiel kann eine typische Situation zeigen, wo hinzufügen viele abgeleitete Verbindungen, erweitern das Modell mit nützlicher Infos, effizienter, weniger redundante und lesbarer Code führen wird. Würden wir traditionelle sprechen hätte Kalligraphieren Sie wahrscheinlich gedacht, dass ich ein Scherz war, weil wir meist uns von mehr Probleme retten nicht durch weitere Beziehungen zwischen Objekten... hinzufügen! Aber ich bin kein Scherz - tatsächlich erreichen Sie alle genannten Vorteile indem Sie das Modell mit Fett ein paar einfache Linien hinzufügen.

BEISPIEL

Eine LKW-Fahrzeug-Kombination kann uns mit einem Beispiel dienen. Das Beispielmodell besteht aus Fahrzeug-Einheiten, einige Parzellen und ein Reise-Objekt alle Reise-Infos und Berechnungen halten. Mit diesen drei Grundkategorien werden wir am Ende schreiben fast 50 % der Code (oder Ausdrücke) in Algorithmen navigieren die Grundstruktur, die nur drei persistente Verbindungen hat... Diese Kodierung ist trivial, nimmt Zeit und fügt nichts von Wert für das System.

Erstklassige ein 'RIL Welt Vertretung' des Beispiels vor repräsentiert mit einem UML Diagramm ('RIL' ist meine Initialen):

Abb. 1: Dieses Fahrzeug Kombination von Parzellen, aber nur die Vorderseite enthält die meisten VehicleUnit hält Reise Infos über Entfernungen, Veranstaltungen und wirtschaftliche Berechnungen.

1.jpg

Die Aspekte der Kunst der Illustration zu ignorieren. Aus mehreren Gründen nicht hier diskutiert, die VehicleUnits immer oben gezeigt hat eine Reise-Objekt angefügt, aber nur das vordere die meisten Reise-Objekt ist, die gesamte Kombination darstellt. Die andere Reise Objekte/Taschenrechner sind 'demobilisiert' bis der Trailer (möglicherweise) vom LKW getrennt wird, und dann werden die Anhänger eine gültigen ('vorderen die meisten') TripHolder allein.

Stellen Sie vor, Sie sind eine der Fahrzeug-Einheiten oder einer der Parzellen in einer Benutzeroberfläche anzeigen und Sie würden wahrscheinlich gerne wissen mehr über Reise Info, vielleicht Entfernungsangaben, Adressen besucht, Visting Bestellung, Kosten oder Erträge pro km usw. (alle von der Reise-Objekt verwaltet) verbunden ist.

Es gibt nur drei Beziehungen in diesem Modell aber noch müssten Sie denken zweimal beim Navigieren richtig versucht, den 'Rechner' (hier für ein 'Reise-Klasse') zu finden.

Noch schlimmer wäre es, wenn Sie möchten einige generische Logic oder Berechnungen für die VehicleUnits zu implementieren, da Sie immer sicherstellen, dass Sie zu den 'vorderen die meisten Fahrzeugeinheit' navigieren müssten (nennen wir es 'Schlepper') und von dort direkt zu den Reise-Info (der Rechner) zu navigieren.

Bei der realen Anwendung gibt es so viel Info in diese grundlegende Struktur eingebettet, dass die drei Verbindungen abgerufen/navigiert wäre wieder so viele Male, die viele hundert Zeilen Code (bzw. OCL Ausdrücke) geschrieben werden würde 'Here, there and everywhere'. Die schlechten Dinge mit diesem gehört, dass wenn Sie explizit diese Links durchlaufen, jedes Mal, wenn Sie in das andere Ende der Struktur ein Objekt/Attribut zugreifen müssen, Sie diese Logik in die CPU jedes Mal ausführen müssen.

Eine weitere schlechte Sache ist, dass Ihr Kern-Business-Logik 'ertrinken' würde im Code und den Umgang mit diesem trivialen Navigation wie Ausdrücken 'Wenn then else für i: =', und weisen Sie Kontrollen. Dies ist, wo abgeleitete Verbindungen helfen kann viel zu einem logischen Chaos zu vermeiden (abgeleitete Attribute würde natürlich auch).

Abb. 2: Eine einfache Klassenmodell der obige Abbildung könnte wie folgt aussehen:

2.jpg

Das Problem der Navigation ist in dieser Klassenmodell als 'RIL Welt Abbildung' offensichtlicher.

Wenn ich eine Parzelle in einer GUI-Liste ausgewählt und Informationen aus dem Reise-Objekt benötigte, ich konnte es nicht werden sicher der der genaue Pfad zur 'mobilisiert' Fahrt Objekt, das einer holding die gültigen Reise-Info. Beispiel:

Wenn das Paket auf einem Anhänger geladen wurde der Ausdruck 'vehicleUnit.trip' wäre ein demobilisierten Reise-Objekt zurückzugeben, aber wenn die Parzelle auf dem Schlepper geladen wurde, würde es das gewünschte 'mobilisiert' Reise-Objekt zurückgeben. Diese Komplikation ist Grund genug, um einen abgeleiteten Link beheben des Problems direkt im Modell, so dass man nie wieder dies bedenken müsste, wenn Algorithmen entwerfen oder die Struktur navigieren. Ich möchte auf jeden Fall eine Verknüpfung namens 'EffectiveTrip' wie folgt hinzufügen:

Abb. 3: Eine Verknüpfung namens 'EffectiveTrip' wird in das Modell aufgenommen. (Ich versuche immer, die blauen Farbe 'persistent' (= 'Einfrieren') darstellen lassen und orange, darstellt 'abgeleitet' Links).

3.jpg

Wie ich bereits vorhersehen können, dass dieser Link für zahlreiche Fahrzeugkombinationen (in Rastern etc.) zugegriffen werden soll würde ich hart code die Ableitung, die Optimierung der Logik hier zu finden, 'die meisten des vorderen' Fahrzeug und das bedeutet durchlaufen den Link Anhänger/Schlepper und aufhören, wenn der Schlepper-Link Nil ist (= IsFrontMost). Von dort aus können wir direkt das Reise-Objekt verweisen. Aber ich weiß auch, dass die meisten Fahrzeug vorne zu finden (die Kombination Schlepper) sehr typisch ist und noch öfter als der Zugriff auf das Reise-Objekt selbst passieren wird. Ich weiß schon, dass der EffectiveTrip-Link als auch solchen abgeleiteten Link verwenden kann! Können es sofort gibt es den Namen 'CombinationFirst' hinzufügen.

Ich wählte den Namen 'CombinationFirst' denn dann Sie sofort die typischen in dieser Situation erkennen. Es ist eine typische Liste Problem behandeln. Sie können bereits vorstellen, die Nützlichkeit von einen anderen abgeleiteten Link die 'CombinationLast' aufgerufen werden kann und sogar eine dritte Verbindung, genannt 'CombinationUnits'!

Ich kann versichern, dass diese Links häufig verwendet werden und somit die 'Kosten' bewerten sie aus bereits zum zweiten Mal, das Sie eine von ihnen verwenden, bezahlt werden!

Abb. 4: Auch erfordert abgeleitete Verbindungen CPU nicht um ausgewertet werden? Man könnte Fragen. Die Antwort ist: Ja natürlich - aber nur einmal - wenn die gezeichneten Elemente nicht ändern. Und dies ist hier nicht sehr wahrscheinlich aber sehr 'Hot Spot' Struktur hier verwendet werden, an vielen Orten in der Logik, die Zugriff auf Objekte über sehr oft zu überqueren und dabei, so dass die Links bereits direkt auf die Instanzen verweist, die Sie zugreifen möchten. Schau dir die 'Mess'...! :

4.jpg

Dies eine leistungsstarke Lösung, die mithilfe des Objektmodells als Tool zur Optimierung und gleichzeitig die zusätzliche Links Klärung/direkt im Modell die beabsichtigte Verwendung der spezifischen Struktur der Angabe!

Für diejenigen, die denken, dass ich verrückt endlich kann ich sagen, dass ich nicht. Stattdessen erhöhte ich die Geschwindigkeit der Berechnungen und alle Aktivitäten, die im Zusammenhang mit dieser Struktur in einer realen Anwendung mit vielen tausend Prozente im Vergleich zu explizit definieren den gesamte Navigationspfad jedes Mal, wenn die Kombination-Reise oder eine spezifische Fahrzeugeinheit (oder Attribut in jedem von ihnen) zugegriffen wurde!

Alle Arten von Daten werden in dieser Struktur gespeichert und mehr als 30 abgeleitete Attribute für verschiedene Berechnungszwecke greift die Struktur hin und her aller Zeiten, die des Clientbenutzers mit Echtzeit-Berechnungen von Einnahmen/km und Entfernungen, Abstand von Gesamt, Anteil der Aktien der Aktien... Etc, etc..

Die Sache ist, lassen einen abgeleiteten Link verwenden, die anderen Links als oft Arsch möglich, dann auch die Notwendigkeit einer Neubeurteilung der Links, wenn Dinge ändert sinkt!

Die letzte Anweisung sehr deutlich mit einem separaten Beispiel zeigt, wie wichtig es ist, zu 'Wiederverwendung' überprüft werden kann alles, was Sie zu jedem höheren (in Bezug auf welchen Teil der Struktur mehr ändern wird und welcher Teil ist mehr 'statische') ableiten. Mit 'Wiederverwendung' meine ich 'CPU bereits geleistete Arbeit' bei der Ableitung des Link. Mehr zu diesem könnte Thema für einen gesonderten Artikel.

Nun ein Blick auf den Code. Wir brauchen zu ergattern die Reise-Objekt (für einige Reson), ausgehend von einer Parzelle, aber wir wissen nicht, auf dem wir geladen werden, damit wir anfangen, hast es über den Link 'EffectiveTrip', die 'die Logik, die bestimmen, welche Reise-Objekt versteckt' VehicleUnit 'mobilisiert' (d.h. 'effektiv') ist:


Funktion TParcel.CalculateTrip_Something...: Double;
var
TripObj: TTrip;
beginnen
TripObj: = vehicleUnit.effectiveTrip; Das ist es! ...

Locker, ist dies klar Code. Details wie wir halten die richtigen Reise-Objekts hat sollte sich die Business Logik Umgang mit Access oder Berechnungen in der Objektstruktur nicht mischen werden.

In unserer realen Welt-Anwendung haben VehicleUnits und Parzellen eine gemeinsame super Klasse (hier nicht gezeigt). Ein Fahrzeug kann auf ein anderes Fahrzeug, genau wie andere Parzellen, so dass der obige Code in meine letzte generische Modell auch einfacher ist, wo der abgeleitete Link geladen werden 'virtuelle overrided' in verschiedenen Unterklassen. Meine letzte Code lautet wie folgt:


beginnen

TripObj: = EffectiveTrip; Das ist es!

Die Parzelle finden ihre gültige Reise über diesen Befehl, unabhängig davon, wie kompliziert der Weg sein könnte. Dies wird gezeigt in Abb. 5 wo eine neue gemeinsame super Klasse tatsächlich besitzt den persistenten und abgeleiteten Link auf der Reise-Klasse und der EffectiveTrip-Link implementiert wird, zuerst in den TParcel und dann overrided für die Klasse VehicleUnit, wie unten dargestellt.

Abb. 5: Hier ich modifiziert das Modell zu allgemeineren werden 'planbar-Objekt' dürfend tragen einen Stapel anderer planbar Objekte - und wie das Modell allgemeinere geht die Rollennamen tun dies auch.


5.jpg

Reise Info gilt direkt für eine Parzelle zu (über AbstractPlanPortion), da ein Transportunternehmen planen eine Parzelle mit geliefert werden, zum Beispiel ein Flugzeug, das Summen wir interessieren uns nicht- aber wir interessieren uns immer noch, dass wir die Verfolgung von Ereignissen Reise beteiligten im eigentlichen Transport und Dokumentation und Transaktionen an die Parzelle selbst befestigt usw.. Das bedeutet aber auch, dass wenn es Notwendigkeit für den Zugriff auf die 'effektive' Reise-Objekt auch muß sehr komplizierte abzugleichen überall auf die Struktur, um herauszufinden, in dem Kontext (richtige, 'mobilisiert') Reise-Objekt gefunden werden kann... Das macht wirklich unsere Logik etwas kompliziert für so eine einfache Sache als einfach Abrufen von Daten aus der Struktur. Einem wahren Alptraum in der Tat...

Diese Komplikation eine einfache Sache ist nicht sehr eindeutig. Das ist einzigartige, wie es bei der Verwendung von Fett-Technologie mit seinen abgeleiteten Verbindungen behandelt werden kann.

Die Parzelle kann die TripHolder selbst sein oder wenn das Paket geladen wird, auf einem Träger, es weiß nicht, ob es auf dem Gepäckträger geladen wird, die eigentlich die Reise-Info hält. Wir müssten wirklich einige Navigatiion hier zu tun. In einer Situation wie dieser können Sie leicht vorstellen, wieviel OCL Kodierung und wie kompliziert ausdrücken würde werden den Zugriff auf Informationen in der Struktur. Ihr Kern-Business-Logik würde 'ertrinken' in der Navigation Logiken beim Abrufen von triviale Dinge einfach aus der Struktur und die CPU würde verbringen viel Zeit, die Suche nach Ihrem Entwicklungsstand zu Objekten Zieldaten.

Endlich: Drei 3 persistente Verbindungen halten die Struktur, die alle zusammen endete in einem anderen fünf 5 sehr nützlich abgeleitete Verbindungen! Das Ergebnis ist, dass die endgültige Anwendung ausgeführt wird, dass viel schneller und Business Logik neben trivial Navigation endlos durchlaufen Objektstrukturen mehr stattfindet.

Vor den effizientesten Code für die optimierte Hardcoded Ableitungen der Links auflisten, möchte ich feststellen, dass die mit diesen Links Sie von überall in der Struktur, überall - direkt - durch Verweisen auf Link-Member mit dem Namen voll Klärung gehen können, was gedenken Sie zu zugreifen, und dies geschieht in der effizienteste Weg, die, den Sie bei der Verwendung der regelmäßigen kühnen Architektur kommen können.

Mit 'effizient' meine ich 'immer direkten Zugriff auf die gewünschte Ziel-Objektinstanz' (mit der Ausnahme, dass für die erste Beurteilung Wich in meinem Fall nur einmal für Hunderttausende Zugriffe... passiert).

Dies ist nur ein Teil der Konzepte, die wir bewusst genutzt, um möglich zu machen, was vorher nicht möglich war: mit regelmäßig, aber 'clean Design', modelliert und strukturiert, objektorientiert Geschäftsklassen Hochleistungs-Real-Time (Rück) Berechnungen sehr fortgeschrittene Reise-Berechnungen (hier nicht besprochen). Auf einer einzigen CPU (Anwendungsserver) für mehrere Clients.

Ableitung-Code, mit Kommentaren

Im folgenden Code betonte ich, alle die interne Referenzierung der abgeleiteten Links ('effiziente Wiederverwendung von bereits ausgewerteten Ergebnisse').

Ich habe auch lokale Variablen, so dass den internen 'Look up' mutige Mitglieder mehr als einmal (= > Vermeidung wiederholte Auslösung der internen Fett Ereignisse usw.).

Die Effizienz der das gesamte Konzept diskutiert und die detaillierte Codierung unten ist mit ProDelphi Profiler (sehr hohe Genauigkeit (+ - 3 %) auf Code Leistungsmessung) geprüft.


{TParcel}



Prozedur TParcel._EffectiveTrip_DeriveAndSubscribe(...);
Wird zurückgegeben, wenn die Träger (effektive) Reise geladen,
sonst ist die lokale Reise (falls vorhanden).
var
CarrierObj: TVehicleUnit;
ResultValue: TTrip;
beginnen
M_batchHolder.DefaultSubscribe (Abonnent, BreResubscribe);
CarrierObj: = BatchHolder;
Wenn Assigned(CarrierObj) dann
beginnen
CarrierObj.M_EffectiveTrip.DefaultSubscribe (Abonnent, BreResubscribe);
ResultValue: = CarrierObj.EffectiveTrip;
Ende
sonst
beginnen
M_trip. DefaultSubscribe (Abonnent, BreResubscribe);
ResultValue: = Ausflug;
Ende;
M_EffectiveTrip.BoldObject: = ResultValue;
Ende;



{TVehicleUnit}



Prozedur TVehicleUnit._EffectiveTrip_DeriveAndSubscribe(...);
var
HaulerObj: TVehicleUnit;
ResultValue,
TripObj: TTrip;
beginnen
ResultValue: = Nil;
M_CombinationFirst.DefaultSubscribe (Abonnent, BreResubscribe);
HaulerObj: = CombinationFirst;
das Traversieren ist hier bereits getan
Wenn Assigned(HaulerObj) dann
beginnen
HaulerObj.M_Trip.DefaultSubscribe (Abonnent, BreResubscribe);
TripObj: = HaulerObj.trip;
Wenn Assigned(TripObj) dann
beginnen
TripObj.M_IsMobilized.DefaultSubscribe(Subscriber);
Wenn TripObj.IsMobilized dann
ResultValue: = TripObj;
Ende;
Ende;
M_EffectiveTrip.BoldObject: = ResultValue;
Ende;



Prozedur TVehicleUnit._CombinationFirst_DeriveAndSubscribe(...);
Dieser Link wird das Fasten 'Short Cut' von vielen vielen verwendet werden
Funktionen in diesem Bereich und andere Links und Attribute, so
Was bedeutet Optimierung, keine 'Extras' oder 'Süßigkeiten' im Modell.
var
LoopObj: TVehicleUnit;
beginnen
LoopObj: = Self; Voraus zu durchlaufen
LoopObj.M_hauler. DefaultSubscribe (Abonnent, BreResubscribe);
während der Assigned(LoopObj.Hauler) zu tun
beginnen
LoopObj: = LoopObj.Hauler;
LoopObj.M_hauler. DefaultSubscribe (Abonnent, BreResubscribe);
Ende;
M_CombinationFirst.BoldObject: = LoopObj;
Ende;




Prozedur TVehicleUnit._CombinationLast_DeriveAndSubscribe (DerivedObject: TObject; Abonnenten: TBoldSubscriber);
var
LoopObj: TVehicleUnit;
beginnen
LoopObj: = Self;
LoopObj.M_trailer. DefaultSubscribe (Abonnent, BreResubscribe);
während der Assigned(LoopObj.trailer) zu tun
beginnen
LoopObj: = LoopObj.trailer;
LoopObj.M_trailer. DefaultSubscribe (Abonnent, BreResubscribe);
Ende;
M_CombinationLast.BoldObject: = LoopObj;
Ende;




Prozedur TVehicleUnit.CombinationUnits_DeriveAndSubscribe(...);
var
LoopObj: TVehicleUnit;
Ergebnisliste: TBoldObjectList;
beginnen
M_CombinationUnits.Clear;
Ergebnisliste: = TBoldObjectList.Create;
versuchen Sie
M_CombinationFirst.DefaultSubscribe (Abonnent, BreResubscribe);
LoopObj: = CombinationFirst;
Wiederholen Sie die
ResultList.Add(LoopObj);
LoopObj.M_trailer. DefaultSubscribe (Abonnent, BreResubscribe);
LoopObj: = LoopObj.trailer;
bis LoopObj = NULL
Schließlich
M_CombinationUnits.AddList(ResultList);
FreeAndNil(ResultList);
Ende;
Ende;




Prozedur TVehicleUnit._CombinationLoadItems_DeriveAndSubscribe (DerivedObject: TObject; Abonnenten: TBoldSubscriber);
Eine Liste sammeln Gesamtindex (Batch) geladen auf jede Einheit in der
Fahrzeugkombination. Der Einfachheit halber implementiert und
Clearification.
var
UnitCnt, i: Integer;
UnitObj: TVehicleUnit;
beginnen
M_CombinationLoadItems.Clear;
CombinationUnits.DefaultSubscribe (Abonnent, BreResubscribe);
UnitCnt: = CombinationUnits.Count;
Wenn UnitCnt > 0 dann
beginnen
für i: = 0 to UnitCnt-1
beginnen
UnitObj: = CombinationUnits [i];
UnitObj.loadedItems.EnsureObjects;
UnitObj.loadedItems.DefaultSubscribe(Subscriber);
Sammeln alle If UnitObj.loadedItems.Count > 0 dann
M_CombinationLoadItems.AddList(UnitObj.loadedItems);
Ende;
Ende;
Ende;

Rolf Lampa

(Aktuelle e-Mail-Adresse: rolf-dot-lampa-at-rilnet-dot-com)








Dynamische Navigation für höhere Leistung


Dynamische Navigation für höhere Leistung : Mehreren tausend Tipps, um Ihr Leben einfacher machen.


Reduzieren oder Entfernen von Navigationscode über die GUI, durch Hinzufügen von abgeleiteten Links und gleichzeitig die Leistung zu verbessern.

Modellierung Klassenstrukturen nimmt einige denken, und wenn das Denken und die Zeichnung fertig und danach starten mit dem Modell, dann verbringen Sie schrecklich viel Code durchlaufen Verknüpfungen um triviale Informationen in einer Struktur angegebene Objekt abzurufen. Navigieren immer und immer wieder die gleichen manchmal komplizierten Verbindung-Pfade nimmt CPU-Leistung und es braucht auch viel redundanten Code bzw. Ausdrücke, die Zugriff auf die gleichen Navigationspfade immer und immer wieder. Im Reich Architektur auch platzieren Sie redundante Abonnements aus vielen verschiedenen Orten zum selben Ziel abonniert die die gleichen Pfade über ein über wieder.

Aber mit Fett können oft direkt adressieren unnötige Navigation, die redundante Navigations/Ocl-Codeausdrücke und Abnahme der CPU-Auslastung durch Hinzufügen von abgeleiteten Verbände stattdessen machen die paar persistenten Verbindungen, nützlicher und 'intelligente' gewinnen. Und darüber hinaus dadurch direkt in Ihrem Modell Modell wird zur gleichen Zeit reflektieren genauer gesagt welche Teile des Modells tatsächlich verwendet wird. Und wie.

Ein Beispiel kann eine typische Situation zeigen, wo hinzufügen viele abgeleitete Verbindungen, erweitern das Modell mit nützlicher Infos, effizienter, weniger redundante und lesbarer Code führen wird. Würden wir traditionelle sprechen hätte Kalligraphieren Sie wahrscheinlich gedacht, dass ich ein Scherz war, weil wir meist uns von mehr Probleme retten nicht durch weitere Beziehungen zwischen Objekten... hinzufügen! Aber ich bin kein Scherz - tatsächlich erreichen Sie alle genannten Vorteile indem Sie das Modell mit Fett ein paar einfache Linien hinzufügen.

BEISPIEL

Eine LKW-Fahrzeug-Kombination kann uns mit einem Beispiel dienen. Das Beispielmodell besteht aus Fahrzeug-Einheiten, einige Parzellen und ein Reise-Objekt alle Reise-Infos und Berechnungen halten. Mit diesen drei Grundkategorien werden wir am Ende schreiben fast 50 % der Code (oder Ausdrücke) in Algorithmen navigieren die Grundstruktur, die nur drei persistente Verbindungen hat... Diese Kodierung ist trivial, nimmt Zeit und fügt nichts von Wert für das System.

Erstklassige ein 'RIL Welt Vertretung' des Beispiels vor repräsentiert mit einem UML Diagramm ('RIL' ist meine Initialen):

Abb. 1: Dieses Fahrzeug Kombination von Parzellen, aber nur die Vorderseite enthält die meisten VehicleUnit hält Reise Infos über Entfernungen, Veranstaltungen und wirtschaftliche Berechnungen.

1.jpg

Die Aspekte der Kunst der Illustration zu ignorieren. Aus mehreren Gründen nicht hier diskutiert, die VehicleUnits immer oben gezeigt hat eine Reise-Objekt angefügt, aber nur das vordere die meisten Reise-Objekt ist, die gesamte Kombination darstellt. Die andere Reise Objekte/Taschenrechner sind 'demobilisiert' bis der Trailer (möglicherweise) vom LKW getrennt wird, und dann werden die Anhänger eine gültigen ('vorderen die meisten') TripHolder allein.

Stellen Sie vor, Sie sind eine der Fahrzeug-Einheiten oder einer der Parzellen in einer Benutzeroberfläche anzeigen und Sie würden wahrscheinlich gerne wissen mehr über Reise Info, vielleicht Entfernungsangaben, Adressen besucht, Visting Bestellung, Kosten oder Erträge pro km usw. (alle von der Reise-Objekt verwaltet) verbunden ist.

Es gibt nur drei Beziehungen in diesem Modell aber noch müssten Sie denken zweimal beim Navigieren richtig versucht, den 'Rechner' (hier für ein 'Reise-Klasse') zu finden.

Noch schlimmer wäre es, wenn Sie möchten einige generische Logic oder Berechnungen für die VehicleUnits zu implementieren, da Sie immer sicherstellen, dass Sie zu den 'vorderen die meisten Fahrzeugeinheit' navigieren müssten (nennen wir es 'Schlepper') und von dort direkt zu den Reise-Info (der Rechner) zu navigieren.

Bei der realen Anwendung gibt es so viel Info in diese grundlegende Struktur eingebettet, dass die drei Verbindungen abgerufen/navigiert wäre wieder so viele Male, die viele hundert Zeilen Code (bzw. OCL Ausdrücke) geschrieben werden würde 'Here, there and everywhere'. Die schlechten Dinge mit diesem gehört, dass wenn Sie explizit diese Links durchlaufen, jedes Mal, wenn Sie in das andere Ende der Struktur ein Objekt/Attribut zugreifen müssen, Sie diese Logik in die CPU jedes Mal ausführen müssen.

Eine weitere schlechte Sache ist, dass Ihr Kern-Business-Logik 'ertrinken' würde im Code und den Umgang mit diesem trivialen Navigation wie Ausdrücken 'Wenn then else für i: =', und weisen Sie Kontrollen. Dies ist, wo abgeleitete Verbindungen helfen kann viel zu einem logischen Chaos zu vermeiden (abgeleitete Attribute würde natürlich auch).

Abb. 2: Eine einfache Klassenmodell der obige Abbildung könnte wie folgt aussehen:

2.jpg

Das Problem der Navigation ist in dieser Klassenmodell als 'RIL Welt Abbildung' offensichtlicher.

Wenn ich eine Parzelle in einer GUI-Liste ausgewählt und Informationen aus dem Reise-Objekt benötigte, ich konnte es nicht werden sicher der der genaue Pfad zur 'mobilisiert' Fahrt Objekt, das einer holding die gültigen Reise-Info. Beispiel:

Wenn das Paket auf einem Anhänger geladen wurde der Ausdruck 'vehicleUnit.trip' wäre ein demobilisierten Reise-Objekt zurückzugeben, aber wenn die Parzelle auf dem Schlepper geladen wurde, würde es das gewünschte 'mobilisiert' Reise-Objekt zurückgeben. Diese Komplikation ist Grund genug, um einen abgeleiteten Link beheben des Problems direkt im Modell, so dass man nie wieder dies bedenken müsste, wenn Algorithmen entwerfen oder die Struktur navigieren. Ich möchte auf jeden Fall eine Verknüpfung namens 'EffectiveTrip' wie folgt hinzufügen:

Abb. 3: Eine Verknüpfung namens 'EffectiveTrip' wird in das Modell aufgenommen. (Ich versuche immer, die blauen Farbe 'persistent' (= 'Einfrieren') darstellen lassen und orange, darstellt 'abgeleitet' Links).

3.jpg

Wie ich bereits vorhersehen können, dass dieser Link für zahlreiche Fahrzeugkombinationen (in Rastern etc.) zugegriffen werden soll würde ich hart code die Ableitung, die Optimierung der Logik hier zu finden, 'die meisten des vorderen' Fahrzeug und das bedeutet durchlaufen den Link Anhänger/Schlepper und aufhören, wenn der Schlepper-Link Nil ist (= IsFrontMost). Von dort aus können wir direkt das Reise-Objekt verweisen. Aber ich weiß auch, dass die meisten Fahrzeug vorne zu finden (die Kombination Schlepper) sehr typisch ist und noch öfter als der Zugriff auf das Reise-Objekt selbst passieren wird. Ich weiß schon, dass der EffectiveTrip-Link als auch solchen abgeleiteten Link verwenden kann! Können es sofort gibt es den Namen 'CombinationFirst' hinzufügen.

Ich wählte den Namen 'CombinationFirst' denn dann Sie sofort die typischen in dieser Situation erkennen. Es ist eine typische Liste Problem behandeln. Sie können bereits vorstellen, die Nützlichkeit von einen anderen abgeleiteten Link die 'CombinationLast' aufgerufen werden kann und sogar eine dritte Verbindung, genannt 'CombinationUnits'!

Ich kann versichern, dass diese Links häufig verwendet werden und somit die 'Kosten' bewerten sie aus bereits zum zweiten Mal, das Sie eine von ihnen verwenden, bezahlt werden!

Abb. 4: Auch erfordert abgeleitete Verbindungen CPU nicht um ausgewertet werden? Man könnte Fragen. Die Antwort ist: Ja natürlich - aber nur einmal - wenn die gezeichneten Elemente nicht ändern. Und dies ist hier nicht sehr wahrscheinlich aber sehr 'Hot Spot' Struktur hier verwendet werden, an vielen Orten in der Logik, die Zugriff auf Objekte über sehr oft zu überqueren und dabei, so dass die Links bereits direkt auf die Instanzen verweist, die Sie zugreifen möchten. Schau dir die 'Mess'...! :

4.jpg

Dies eine leistungsstarke Lösung, die mithilfe des Objektmodells als Tool zur Optimierung und gleichzeitig die zusätzliche Links Klärung/direkt im Modell die beabsichtigte Verwendung der spezifischen Struktur der Angabe!

Für diejenigen, die denken, dass ich verrückt endlich kann ich sagen, dass ich nicht. Stattdessen erhöhte ich die Geschwindigkeit der Berechnungen und alle Aktivitäten, die im Zusammenhang mit dieser Struktur in einer realen Anwendung mit vielen tausend Prozente im Vergleich zu explizit definieren den gesamte Navigationspfad jedes Mal, wenn die Kombination-Reise oder eine spezifische Fahrzeugeinheit (oder Attribut in jedem von ihnen) zugegriffen wurde!

Alle Arten von Daten werden in dieser Struktur gespeichert und mehr als 30 abgeleitete Attribute für verschiedene Berechnungszwecke greift die Struktur hin und her aller Zeiten, die des Clientbenutzers mit Echtzeit-Berechnungen von Einnahmen/km und Entfernungen, Abstand von Gesamt, Anteil der Aktien der Aktien... Etc, etc..

Die Sache ist, lassen einen abgeleiteten Link verwenden, die anderen Links als oft Arsch möglich, dann auch die Notwendigkeit einer Neubeurteilung der Links, wenn Dinge ändert sinkt!

Die letzte Anweisung sehr deutlich mit einem separaten Beispiel zeigt, wie wichtig es ist, zu 'Wiederverwendung' überprüft werden kann alles, was Sie zu jedem höheren (in Bezug auf welchen Teil der Struktur mehr ändern wird und welcher Teil ist mehr 'statische') ableiten. Mit 'Wiederverwendung' meine ich 'CPU bereits geleistete Arbeit' bei der Ableitung des Link. Mehr zu diesem könnte Thema für einen gesonderten Artikel.

Nun ein Blick auf den Code. Wir brauchen zu ergattern die Reise-Objekt (für einige Reson), ausgehend von einer Parzelle, aber wir wissen nicht, auf dem wir geladen werden, damit wir anfangen, hast es über den Link 'EffectiveTrip', die 'die Logik, die bestimmen, welche Reise-Objekt versteckt' VehicleUnit 'mobilisiert' (d.h. 'effektiv') ist:


Funktion TParcel.CalculateTrip_Something...: Double;
var
TripObj: TTrip;
beginnen
TripObj: = vehicleUnit.effectiveTrip; Das ist es! ...

Locker, ist dies klar Code. Details wie wir halten die richtigen Reise-Objekts hat sollte sich die Business Logik Umgang mit Access oder Berechnungen in der Objektstruktur nicht mischen werden.

In unserer realen Welt-Anwendung haben VehicleUnits und Parzellen eine gemeinsame super Klasse (hier nicht gezeigt). Ein Fahrzeug kann auf ein anderes Fahrzeug, genau wie andere Parzellen, so dass der obige Code in meine letzte generische Modell auch einfacher ist, wo der abgeleitete Link geladen werden 'virtuelle overrided' in verschiedenen Unterklassen. Meine letzte Code lautet wie folgt:


beginnen

TripObj: = EffectiveTrip; Das ist es!

Die Parzelle finden ihre gültige Reise über diesen Befehl, unabhängig davon, wie kompliziert der Weg sein könnte. Dies wird gezeigt in Abb. 5 wo eine neue gemeinsame super Klasse tatsächlich besitzt den persistenten und abgeleiteten Link auf der Reise-Klasse und der EffectiveTrip-Link implementiert wird, zuerst in den TParcel und dann overrided für die Klasse VehicleUnit, wie unten dargestellt.

Abb. 5: Hier ich modifiziert das Modell zu allgemeineren werden 'planbar-Objekt' dürfend tragen einen Stapel anderer planbar Objekte - und wie das Modell allgemeinere geht die Rollennamen tun dies auch.


5.jpg

Reise Info gilt direkt für eine Parzelle zu (über AbstractPlanPortion), da ein Transportunternehmen planen eine Parzelle mit geliefert werden, zum Beispiel ein Flugzeug, das Summen wir interessieren uns nicht- aber wir interessieren uns immer noch, dass wir die Verfolgung von Ereignissen Reise beteiligten im eigentlichen Transport und Dokumentation und Transaktionen an die Parzelle selbst befestigt usw.. Das bedeutet aber auch, dass wenn es Notwendigkeit für den Zugriff auf die 'effektive' Reise-Objekt auch muß sehr komplizierte abzugleichen überall auf die Struktur, um herauszufinden, in dem Kontext (richtige, 'mobilisiert') Reise-Objekt gefunden werden kann... Das macht wirklich unsere Logik etwas kompliziert für so eine einfache Sache als einfach Abrufen von Daten aus der Struktur. Einem wahren Alptraum in der Tat...

Diese Komplikation eine einfache Sache ist nicht sehr eindeutig. Das ist einzigartige, wie es bei der Verwendung von Fett-Technologie mit seinen abgeleiteten Verbindungen behandelt werden kann.

Die Parzelle kann die TripHolder selbst sein oder wenn das Paket geladen wird, auf einem Träger, es weiß nicht, ob es auf dem Gepäckträger geladen wird, die eigentlich die Reise-Info hält. Wir müssten wirklich einige Navigatiion hier zu tun. In einer Situation wie dieser können Sie leicht vorstellen, wieviel OCL Kodierung und wie kompliziert ausdrücken würde werden den Zugriff auf Informationen in der Struktur. Ihr Kern-Business-Logik würde 'ertrinken' in der Navigation Logiken beim Abrufen von triviale Dinge einfach aus der Struktur und die CPU würde verbringen viel Zeit, die Suche nach Ihrem Entwicklungsstand zu Objekten Zieldaten.

Endlich: Drei 3 persistente Verbindungen halten die Struktur, die alle zusammen endete in einem anderen fünf 5 sehr nützlich abgeleitete Verbindungen! Das Ergebnis ist, dass die endgültige Anwendung ausgeführt wird, dass viel schneller und Business Logik neben trivial Navigation endlos durchlaufen Objektstrukturen mehr stattfindet.

Vor den effizientesten Code für die optimierte Hardcoded Ableitungen der Links auflisten, möchte ich feststellen, dass die mit diesen Links Sie von überall in der Struktur, überall - direkt - durch Verweisen auf Link-Member mit dem Namen voll Klärung gehen können, was gedenken Sie zu zugreifen, und dies geschieht in der effizienteste Weg, die, den Sie bei der Verwendung der regelmäßigen kühnen Architektur kommen können.

Mit 'effizient' meine ich 'immer direkten Zugriff auf die gewünschte Ziel-Objektinstanz' (mit der Ausnahme, dass für die erste Beurteilung Wich in meinem Fall nur einmal für Hunderttausende Zugriffe... passiert).

Dies ist nur ein Teil der Konzepte, die wir bewusst genutzt, um möglich zu machen, was vorher nicht möglich war: mit regelmäßig, aber 'clean Design', modelliert und strukturiert, objektorientiert Geschäftsklassen Hochleistungs-Real-Time (Rück) Berechnungen sehr fortgeschrittene Reise-Berechnungen (hier nicht besprochen). Auf einer einzigen CPU (Anwendungsserver) für mehrere Clients.

Ableitung-Code, mit Kommentaren

Im folgenden Code betonte ich, alle die interne Referenzierung der abgeleiteten Links ('effiziente Wiederverwendung von bereits ausgewerteten Ergebnisse').

Ich habe auch lokale Variablen, so dass den internen 'Look up' mutige Mitglieder mehr als einmal (= > Vermeidung wiederholte Auslösung der internen Fett Ereignisse usw.).

Die Effizienz der das gesamte Konzept diskutiert und die detaillierte Codierung unten ist mit ProDelphi Profiler (sehr hohe Genauigkeit (+ - 3 %) auf Code Leistungsmessung) geprüft.


{TParcel}



Prozedur TParcel._EffectiveTrip_DeriveAndSubscribe(...);
Wird zurückgegeben, wenn die Träger (effektive) Reise geladen,
sonst ist die lokale Reise (falls vorhanden).
var
CarrierObj: TVehicleUnit;
ResultValue: TTrip;
beginnen
M_batchHolder.DefaultSubscribe (Abonnent, BreResubscribe);
CarrierObj: = BatchHolder;
Wenn Assigned(CarrierObj) dann
beginnen
CarrierObj.M_EffectiveTrip.DefaultSubscribe (Abonnent, BreResubscribe);
ResultValue: = CarrierObj.EffectiveTrip;
Ende
sonst
beginnen
M_trip. DefaultSubscribe (Abonnent, BreResubscribe);
ResultValue: = Ausflug;
Ende;
M_EffectiveTrip.BoldObject: = ResultValue;
Ende;



{TVehicleUnit}



Prozedur TVehicleUnit._EffectiveTrip_DeriveAndSubscribe(...);
var
HaulerObj: TVehicleUnit;
ResultValue,
TripObj: TTrip;
beginnen
ResultValue: = Nil;
M_CombinationFirst.DefaultSubscribe (Abonnent, BreResubscribe);
HaulerObj: = CombinationFirst;
das Traversieren ist hier bereits getan
Wenn Assigned(HaulerObj) dann
beginnen
HaulerObj.M_Trip.DefaultSubscribe (Abonnent, BreResubscribe);
TripObj: = HaulerObj.trip;
Wenn Assigned(TripObj) dann
beginnen
TripObj.M_IsMobilized.DefaultSubscribe(Subscriber);
Wenn TripObj.IsMobilized dann
ResultValue: = TripObj;
Ende;
Ende;
M_EffectiveTrip.BoldObject: = ResultValue;
Ende;



Prozedur TVehicleUnit._CombinationFirst_DeriveAndSubscribe(...);
Dieser Link wird das Fasten 'Short Cut' von vielen vielen verwendet werden
Funktionen in diesem Bereich und andere Links und Attribute, so
Was bedeutet Optimierung, keine 'Extras' oder 'Süßigkeiten' im Modell.
var
LoopObj: TVehicleUnit;
beginnen
LoopObj: = Self; Voraus zu durchlaufen
LoopObj.M_hauler. DefaultSubscribe (Abonnent, BreResubscribe);
während der Assigned(LoopObj.Hauler) zu tun
beginnen
LoopObj: = LoopObj.Hauler;
LoopObj.M_hauler. DefaultSubscribe (Abonnent, BreResubscribe);
Ende;
M_CombinationFirst.BoldObject: = LoopObj;
Ende;




Prozedur TVehicleUnit._CombinationLast_DeriveAndSubscribe (DerivedObject: TObject; Abonnenten: TBoldSubscriber);
var
LoopObj: TVehicleUnit;
beginnen
LoopObj: = Self;
LoopObj.M_trailer. DefaultSubscribe (Abonnent, BreResubscribe);
während der Assigned(LoopObj.trailer) zu tun
beginnen
LoopObj: = LoopObj.trailer;
LoopObj.M_trailer. DefaultSubscribe (Abonnent, BreResubscribe);
Ende;
M_CombinationLast.BoldObject: = LoopObj;
Ende;




Prozedur TVehicleUnit.CombinationUnits_DeriveAndSubscribe(...);
var
LoopObj: TVehicleUnit;
Ergebnisliste: TBoldObjectList;
beginnen
M_CombinationUnits.Clear;
Ergebnisliste: = TBoldObjectList.Create;
versuchen Sie
M_CombinationFirst.DefaultSubscribe (Abonnent, BreResubscribe);
LoopObj: = CombinationFirst;
Wiederholen Sie die
ResultList.Add(LoopObj);
LoopObj.M_trailer. DefaultSubscribe (Abonnent, BreResubscribe);
LoopObj: = LoopObj.trailer;
bis LoopObj = NULL
Schließlich
M_CombinationUnits.AddList(ResultList);
FreeAndNil(ResultList);
Ende;
Ende;




Prozedur TVehicleUnit._CombinationLoadItems_DeriveAndSubscribe (DerivedObject: TObject; Abonnenten: TBoldSubscriber);
Eine Liste sammeln Gesamtindex (Batch) geladen auf jede Einheit in der
Fahrzeugkombination. Der Einfachheit halber implementiert und
Clearification.
var
UnitCnt, i: Integer;
UnitObj: TVehicleUnit;
beginnen
M_CombinationLoadItems.Clear;
CombinationUnits.DefaultSubscribe (Abonnent, BreResubscribe);
UnitCnt: = CombinationUnits.Count;
Wenn UnitCnt > 0 dann
beginnen
für i: = 0 to UnitCnt-1
beginnen
UnitObj: = CombinationUnits [i];
UnitObj.loadedItems.EnsureObjects;
UnitObj.loadedItems.DefaultSubscribe(Subscriber);
Sammeln alle If UnitObj.loadedItems.Count > 0 dann
M_CombinationLoadItems.AddList(UnitObj.loadedItems);
Ende;
Ende;
Ende;

Rolf Lampa

(Aktuelle e-Mail-Adresse: rolf-dot-lampa-at-rilnet-dot-com)

Dynamische Navigation für höhere Leistung

Dynamische Navigation für höhere Leistung : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
Freunden empfehlen
  • gplus
  • pinterest

Kürzliche Posts

Kommentar

Einen Kommentar hinterlassen

Wertung