> Inhalt: JavaScout-Fat-Client-Framework (JS-FCF) 

> Verzeichnis der Dokumente mit den Muster-Codes 

Muster-Code für ein BO_Set (Liste mit Business-Objects, Generelle Klasse)

* Bitte beachten Sie die Hinweise und Bestimmungen bezüglich Urheberrecht, Haftungsausschluß und geschützte Marken oder Warenzeichen die für dieses Web-Dokument und möglicherweise auch für 'verlinkte' Dokumente gelten.

  • Der Betreiber dieser Web-Site (www.javascout.biz) ist nicht verantwortlich für den Inhalt von Web-Sites, die innerhalb dieses Web-Dokumentes oder anderer Dokumente von www.javascout.biz verlinkt sind.

  • Wenn dieses Web-Dokument oder andere Dokumente dieser Web-Site (www.javascout.biz) Rechte von Ihnen verletzen, oder sie glauben, dass Rechte Anderer (Dritter Personen) dadurch verletzt werden, informieren Sie bitte den Betreiber dieser Web-Site.
    Eine E-Mail können Sie ganz einfach durch anklicken des Symbols oder Textes im Frame rechts oben senden.

Dieses Dokument drucken.

 Letzte Bearbeitung dieses  Dokuments:
2011-01-11

Voraussetzungen für das Verständnis dieses Dokuments:

Grundkenntnisse in der Programmierung von Java (Klassen, Methoden, Schleifen).
Grundkenntnisse der SQL-Kommandos für relationale Datenbanksysteme.

Ungefährer Zeitbedarf zum Durcharbeiten dieses Dokuments:

Arbeitszeit:
Abhängig von der Komplexität der zu entwickelnden BOS-Klasse.
Ein Kopieren des Muster-Codes und 'Find/Replace' der 'Platzhalter' dauert ca. 10 Minuten.

Für das Implementieren komplexerer Abfragen hängt der Arbeitsaufwand stark von der Aufgabe und der Routine ab. Eine Schätzung des Zeitaufwandes kann in diesen Fällen nicht gegeben werden.

Dieses Dokument enthält Code-Muster für eine einfache Generelle Klasse mit einer Liste mit BO (BO_Set) und Erweiterungen, die entsprechend den jeweiligen Anforderungen zusätzlich implementiert werden können.

Inhaltsverzeichnis:

Vorbedingung 
Einfacher Muster-Code für ein BO_Set
 
Anleitung zur Adaptierung 
* Änderung des Namens der Java-Packages der Anwendung 
* Änderung des Namens der Klasse 
* Adaptieren des Kommentars 
* Methoden
copyFromapplication_entity_BO(..) und isDifferent(..) prüfen 
* Bei Version 'MobileClient': Codieren der Sortier-Methode(n) 


Spezieller Muster-Code 
* Sortieren der Liste (aufsteigend) 
* Sortieren der Liste (absteigend) 


Weitere Schritte und verwandte Dokumentation 

Vorbedingung:

zum Inhaltsverzeichnis

Einfacher Muster-Code für ein BO_Set

Welche Platzhalter durch Bezeichnungen des eigentlichen Projektes zu ersetzen sind finden Sie im Abschnitt
Anleitung zur Adaptierung.

package application_package.bo;
/*
 * Package mit den Klassen für die Serialization eines Objekts dieser Klasse.
 * Serialization ist notwendig um ein BO vom Java Application Server (JAS)
 * zum Client zu übertragen.
*/
import java.io.Serializable;
/*
 * Package mit der Basisklasse für ein BO-Set. */

import js_base.bo.JSBS_BO_Set;
/*
 * Package mit der BO-Klasse, dessen Objekte in der Liste dieser Klasse enthalten sind. */

import application_package.bo.application_entity_BO;
/**
 * 
 * @author name[at]company
 * @date 20xx-xx-xx
 *
 * @description
 *  Generelle Klasse für eine Liste von Business-Objects
 *  der Klasse
application_entity_BO.
 *  Für eine Beschreibung des BO sehen Sie bitte im Kommentar
 *  der Klasse
application_entity_BO nach.
 * 
 * @change-log
 * when          who                       why
 * -----------------------------------------------------------------
 * 
 */
public class application_entity_BO_Set extends JSBS_BO_Set implements Serializable {
/*
 * METHODEN */

/* ---------------------
 * METHODE zum Kopieren der Liste mit den BO eines anderen Objekts dieser Klasse
 * in diese Klasse. */

    
public void copyFromapplication_entity_BO_Set(
                  
application_entity_BO_Set parmapplication_entity_BO_Set) {
/*
 * Größe des Vectors mit den BO (der in der geerbten Basisklasse definiert ist) feststellen
 * und Index zum Durchsuchen definieren. */

      
int locintVectorSize = parmapplication_entity_BO_Set.vecRecordSet.size();
      
int locintVectorIndex;
/* 
 * Vector mit der Liste der BO in dieser Klasse leeren. */
      this.vecRecordSet.removeAllElements();
/* 
 * Mit einer for-Schleife alle BO in der Liste des als Parameter übergebenen Objekts durchgehen. */
      for (locintVectorIndex = 0;
           locintVectorIndex < locintVectorSize;
           locintVectorIndex++) {
/* 
 * Das durch den Index gewählte BO aus der Liste durch eine lokale Variable leichter
 * 'greifbar' machen. */
        application_entity_BO locstructBO = (application_entity_BO)
          parm
application_entity_BO_Set.vecRecordSet.elementAt(locintVectorIndex);
/* 
 * Neues BO 'konstruieren' und die Methode der BO-Klasse zum Kopieren der Variablen-Werte
 * aufrufen. */
        application_entity_BO locstructBO_New = new application_entity_BO();
        locstructBO_New.copyFrom
application_entity_BO(locstructBO);
/* 
 * Das 'neue' BO in die Liste dieses Objekts einfügen. */
        this.vecRecordSet.addElement(locstructBO_New);
      };
/* 
 * Status-Code und erklärenden Zusatz-Text in dieses Objekt übernehmen. */
      this.StatusCode = parmapplication_entity_BO_Set.StatusCode;
      this.StatusMsg = parmapplication_entity_BO_Set.StatusMsg;
    }
/* ---------------------
 * METHODE zum Vergleichen der Werte der in der Liste enthaltenen Business-Objects.
 * Voraussetzung ist, dass die Sortier-Reihenfolge innerhalb der Liste gleich ist.
 * Die Methode liefert 'true' zurück wenn mindestens die Werte einer Variablen
 * in einem BO der Liste verschieden sind. */

    
public boolean isDifferent(
                    
application_entity_BO_Set parmapplication_entity_BO_Set) {
/* 
 * Wenn der Parameter 'null' ist dann 'true' (verschieden) zurück liefern. */

      
if (parmapplication_entity_BO_Set == null) return true;
/* 
 * Anzahl der BO ('Länge') in den Listen der beiden BO-Set-Objekte ermitteln. */

      
int intThisVectorSize = this.vecRecordSet.size();
      
int intParmVectorSize = parmapplication_entity_BO_Set.vecRecordSet.size();
/* 
 * Wenn die Anzahl der BOs in den Listen verschieden ist dann sind beide Sets verschieden. */

      
if (intThisVectorSize != intParmVectorSize) return true;
/* 
 * Variable für die beiden zu vergleichenden BO definieren.
*/
      
application_entity_BO structThisapplication_entity_BO;
      
application_entity_BO structParmapplication_entity_BO;
/* 
 * In einer 'for'-Schleife jedes einzelne BO 'herausholen' und die Methode des BO
 
 * zum Vergleichen aufrufen.
*/
      
for (int intVectorIndex = 0; intVectorIndex < intThisVectorSize; intVectorIndex++) {
/* 'Herausholen' der beiden BO und übertragen auf die dafür vorgesehenen Variablen. */
        structThis
application_entity_BO = (application_entity_BO)
                  
this.vecRecordSet.elementAt(intVectorIndex);
        structParm
application_entity_BO = (application_entity_BO)
                  parm
application_entity_BO_Set.vecRecordSet.elementAt(intVectorIndex);
/* 
 * Prüfung ob eines oder beide BO 'null' sind; dann ist ein besonderer Vergleich notwendig. */

        if (structThisapplication_entity_BO == null) {
/* 
 * Vergleich über die Methode der Klasse ist nicht möglich (weil Objekt 'null' ist);
 
 * aber beide BO sind 'verschieden' wenn das zu vergleichende BO nicht 'null' ist. */

          if (structParmapplication_entity_BO != nullreturn true;
        }
        
else {
/* 
 * Methode des BO aufrufen; darin wird auch behandelt wenn das als Parameter übergebene BO
 * 'null' ist. Wenn die BO verschieden sind dann diese Methode beenden. */

          
if (structThisapplication_entity_BO.isDifferent(structParmapplication_entity_BO)) 
              
return true;
        }
      }

/*
 * Beide Sets sind identisch; 'false' als Zeichen für 'nicht verschieden' zurückliefern. */

      
return false;
    }
}

zum Inhaltsverzeichnis

Anleitung zur Adaptierung

Am leichtesten funktioniert die Anpassung des Muster-Codes an die eigenen Erfordernisse durch Kopieren des Muster-Codes und Verwendung von Edit > Find/Replace... .

Wenn vorher der zu ersetzende Text markiert wurde, wird er zu findende Text von der Suchfunktion übernommen.

Für 'Platzhalter', die nur einmalig im Muster-Code vorkommen ist die 'Find'-Funktion ist hilfreich zum Finden der beschriebenen 'Platzhalter'.

zum Inhaltsverzeichnis

Änderung des Namens der Java-Packages der Anwendung

package application_package.bo;
/*

Der Name dieses Packages kommt in der ersten Zeile und beim import der Klasse für das zugehörige BO im Muster-Code vor.

zum Inhaltsverzeichnis

Änderung des Namens der Klasse

/*
 * Package mit der BO-Klasse, dessen Objekte in der Liste dieser Klasse enthalten sind. */

import application_package.bo.application_entity_BO;

Dieser Name muss mit dem Namen der Klasse übereinstimmen, der beim Eröffnen der Klasse gewählt wurde.

Der Name der Klasse kommt mehrmals im gesamten Code vor.
Deswegen empfehle ich, mit 'Find/Replace' alle Platzhalter
application_entity_BO im Muster-Code durch den gewählten Klassen-Namen zu ersetzen.

zum Inhaltsverzeichnis

Adaptieren des Kommentars

'Kein Kommentar ist besser als ein falscher'.

Aus diesem Grund ist im Muster-Code auch keine Hintergrund-Information über Entwurfs-Entscheidungen für das BO vorhanden.
Zur Information über den Geschäftszweck wird auf den Kommentar bei der zugehörigen Generellen Klasse für das BO verwiesen.

zum Inhaltsverzeichnis

Methoden copyFromapplication_entity_BO_Set(...) und isDifferent(...) prüfen

Die beiden Methoden enthalten einen universellen Code der für das Kopieren bzw. Vergleichen der einzelnen BOs der Liste die zugehörigen Methoden der Klasse für ein BO aufruft.

Das Ersetzen des Platzhalters application_entity_BO ist bereits erfolgt wenn Sie das im Abschnitt Änderung des Namens der Klasse beschriebenen Verfahren durchgeführt haben.

zum Inhaltsverzeichnis

Bei Version 'MobileClient': Codieren der Sortier-Methode(n)

Wenn für dieses Business-Object auch die Version 'MobileClient' (Erfassen und Verwalten von Daten auf der lokalen Datenbank eines 'Client'-Gerätes mit späterer Synchronisation mit der zentralen Datenbank des Servers) vorgesehen ist, muss nach dem Synchronisieren der Daten die Liste mit den BO möglicherweise neu sortiert werden.

Nach welchen Variablen sortiert wird und in welcher Klasse (dieser Generellen, Server-Seite, Client-Seite) die Sortierung erfolgt hängt von den Anforderungen des Anwendungsprogramms ab und kann nicht generell beantwortet werden.
Eine Implementierung in dieser (allgemeinen) Klasse für das BO ist sinnvoll, wenn das Sortieren auf der Client-Seite und auf der Server-Seite erforderlich ist.

Den Muster-Algorithmus für das Sortieren finden Sie in den Abschnitt Sortieren der Liste (aufsteigend) und Sortieren der Liste (absteigend).

zum Inhaltsverzeichnis

Spezieller Muster-Code

In diesem Teil wird Muster-Code vorgestellt, der nicht in jeder Server-seitigen Klasse mit einer Liste von BO vorkommen wird und deswegen nicht in den Muster-Code der Klasse aufgenommen wurde.

zum Inhaltsverzeichnis

Sortieren der Liste (aufsteigend)

Unter Umständen ist es notwendig, die BO in der Liste anders zu sortieren als sie durch das SQL-Kommando von der Datenbank selektiert wurden.
Als Alternative zum Erstellen eines weiteren Datenbank-Zugriffs bietet sich an, die BO innerhalb der Liste entsprechend den geänderten Anforderungen zu sortieren.
In diesem Muster-Code werden die BO nach den gewünschten Variablen aufsteigend sortiert.

/* ---------------------
 * METHODE zum Sortieren der BO innerhalb der Liste.
 * Verwendet wird ein doppelter Bubble-Sort.
*/
    
public void sortByVariable1_Variable2_Variable3_Variable4(){
/* Variable für die beiden zu vergleichenden (und eventuell zu tauschenden) BOs aus
 * der Liste. */

      
application_entity_BO struct1application_entity_BO;
      
application_entity_BO struct2application_entity_BO;
/* Variable für den Index zum Adressieren der BO in der Liste. */
      
int intIndex = 0;
/* 
 * Variable für die 'Grenzen', ausserhalb derer die 'kleinsten' und 'größten'
 * BO der Liste schon sortiert sind.
 * Ein Vorteil des Bubble-Sort ist, dass mit dem ersten Durchlauf die 'größten' bzw.
 * 'kleinsten' BO sicher an die richtige
Stelle wandern und nach dem Durchlauf n
 * mindestens die n 'größten' bzw. 'kleinsten' BO an der richtigen Stelle sind.
 * Dadurch muss mit jedem weiteren Durchlauf nur mehr eine geringere Anzahl der BO
 * verglichen (und eventuell getauscht) werden.
 * Die beiden Variablen verbessern den Algorithmus, weil sie nach einem Durchlauf
 * erkennen lassen, bis zu welchen Index-Werten die BOs noch verglichen werden müssen.
  */
      
int intLowestSortedIndicator = 0;
      
int intHighestSortedIndicator = vecRecordSet.size() - 1;
/*
 * Weitere Variable die notwendig sind um eine planbare Steuerung der for-Schleifen zu
 * erreichen.
  */
      
int intLowerAlreadySortedIndex = intLowestSortedIndicator;
      
int intUpperAlreadySortedIndex = intHighestSortedIndicator;
/* 
 * Für den Vergleich von Text wird ein Collator verwendet; dieser sorgt auch für die
 
 * passende Reihenfolge von Umlauten. */

      java.text.Collator locCollator = java.text.Collator.getInstance();
      locCollator.setStrength(java.text.Collator.
TERTIARY);
/* 
 
 * In der while-Schleife das Vergleichen der BO so lange ausführen bis
 * in den for-Schleifen kein Tausch mehr erfolgt ist.
 
 * Das wird daran erkannt, dass die Variablen mit den Indizes, wie weit die Liste
 
 * schon sortiert ist, noch einen zu untersuchenden Bereich anzeigen. */

      
while (intLowestSortedIndicator < intHighestSortedIndicator) {
/* 
 
 * Zuerst wird die Liste mit den BO von 'unten' (niederster Index) nach 'oben'
 
 * durchlaufen. Dabei wandern die 'größeren' BO nach 'oben'. */
/* 
 
 * Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim  
 * Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darüber sind schon in der richtigen Reihenfolge. */

        intUpperAlreadySortedIndex = intHighestSortedIndicator;

/* 
 
 * Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf den
  
 * Wert des unteren Indikators setzen. Damit wird die while-Schleife beendet
  
 * wenn in der folgenden for-Schleife kein Tausch mehr erfolgt. */

        intHighestSortedIndicator
= intLowestSortedIndicator;
/* 
 
 * Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab dem
beim  
 * Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darunter sind schon in der richtigen Reihenfolge - und geht bis
  
 * zu jenem Index, bei dem beim Durchlauf von 'unten' nach 'oben' kein Tausch
  
 * mehr erfolgt ist.
 */
        
for (intIndex = intLowestSortedIndicator + 1;
             intIndex
<= intUpperAlreadySortedIndex;
             intIndex++
) {
/* 
 
 * Die beiden zu vergleichenden BO aus der Liste 'holen'. */

          
struct1application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex - 1);
          
struct2application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex);
/* 
 
 * Der folgende Vergleich ist Ihren individuellen Anforderungen anzupassen.
 
 * Der Muster-Code geht davon aus, dass Variablen der Klasse 'String' verglichen werden
 
 * und benutzt den 'Collator'
- bei numerischen Werten vereinfacht sich der Vergleich. */
          
if (     (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) > 0)
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) > 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) > 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_4.trim(),
                    
                   struct2application_entity_BO.Variable_4.trim()) > 0)) 
             
) {
/* 
 
 * BO sind in falscher Reihenfolge und müssen vertauscht werden. */

            
vecRecordSet.setElementAt(struct2application_entity_BO, intIndex - 1);
            
vecRecordSet.setElementAt(struct1application_entity_BO, intIndex);
/* 
 
 * Indikator, wie weit die Liste sortiert ist, anpassen. */

            
intHighestSortedIndicator = intIndex;
          }
        }
/* 
 
 * Jetzt wird die Liste mit den BO von 'oben' (höchster Index) nach 'unten'
 
 * durchlaufen. Dabei wandern die 'kleineren' BO nach 'unten'. */
/* 
 
 * Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim  
 * Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darunter sind schon in der richtigen Reihenfolge. */

        intLowerAlreadySortedIndex = intLowestSortedIndicator;

/* 
 
 * Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf den
  
 * Wert des oberen Indikators setzen. Damit wird die while-Schleife beendet
  
 * wenn in der folgenden for-Schleife kein Tausch mehr erfolgt. */

        intLowestSortedIndicator
= intHighestSortedIndicator;
/* 
 
 * Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab dem
beim  
 * Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darüber sind schon in der richtigen Reihenfolge - und geht bis
  
 * zu jenem Index, bei dem beim Durchlauf von 'oben' nach 'unten' kein Tausch
  
 * mehr erfolgt ist.
 */
        
for (intIndex = intHighestSortedIndicator - 1;
             intIndex
>= intLowerAlreadySortedIndex;
             intIndex--
) {
/* 
 
 * Die beiden zu vergleichenden BO aus der Liste 'holen'. */

          
struct1application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex);
          
struct2application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex + 1);
/* 
 
 * Der folgende Vergleich ist gleich wie beim Sortieren von 'unten' nach 'oben'.

 * Es ist zeitsparend, den einmal codierten Vergleich hierher zu kopieren. */

          
if (     (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) > 0)
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) > 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) > 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_4.trim(),
                    
                   struct2application_entity_BO.Variable_4.trim()) > 0)) 
             
) {
/* 
 
 * BO sind in falscher Reihenfolge und müssen vertauscht werden. */

            
vecRecordSet.setElementAt(struct2application_entity_BO, intIndex);
            
vecRecordSet.setElementAt(struct1application_entity_BO, intIndex + 1);
/* 
 
 * Indikator, wie weit die Liste sortiert ist, anpassen. */

            
intLowestSortedIndicator = intIndex;
          }
        }
      }
    
}

Üblicherweise wird die Methode zum Sortieren in einer Methode zugehörigen BOS-Set aufgerufen - und zwar bevor die Methode ordnungsgemäß beendet wird.

Unter bestimmten Voraussetzungen kann die Methode auch im zugehörigen BOC-Set aufgerufen werden.
Das ist dann sinnvoll, wenn die CPU-Zeit auf einem Server zu bezahlen ist und daher möglichst viel Rechenleistung auf einem Client-Computer ausgeführt werden soll.

zum Inhaltsverzeichnis

Sortieren der Liste (absteigend)

Der Muster-Code für das Sortieren nach absteigenden Kriterien ist gleich wie der unter Sortieren der Liste (aufsteigend) vorgestellte Muster-Code.
Einziger Unterschied sind die Vergleiche in den beiden
if.

/* ---------------------
 * METHODE zum Sortieren der BO innerhalb der Liste nach 'absteigenden' Kriterien.
 * Verwendet wird ein doppelter Bubble-Sort.
*/
    
public void sortDescendingByVariable1_Variable2_Variable3_Variable4(){
/* Variable für die beiden zu vergleichenden (und eventuell zu tauschenden) BOs aus
 * der Liste. */

      
application_entity_BO struct1application_entity_BO;
      
application_entity_BO struct2application_entity_BO;
/* Variable für den Index zum Adressieren der BO in der Liste. */
      
int intIndex = 0;
/* 
 * Variable für die 'Grenzen', ausserhalb derer die 'kleinsten' und 'größten'
 * BO der Liste schon sortiert sind.
 * Ein Vorteil des Bubble-Sort ist, dass mit dem ersten Durchlauf die 'größten' bzw.
 * 'kleinsten' BO sicher an die richtige
Stelle wandern und nach dem Durchlauf n
 * mindestens die n 'größten' bzw. 'kleinsten' BO an der richtigen Stelle sind.
 * Dadurch muss mit jedem weiteren Durchlauf nur mehr eine geringere Anzahl der BO
 * verglichen (und eventuell getauscht) werden.
 * Die beiden Variablen verbessern den Algorithmus, weil sie nach einem Durchlauf
 * erkennen lassen, bis zu welchen Index-Werten die BOs noch verglichen werden müssen.
  */
      
int intLowestSortedIndicator = 0;
      
int intHighestSortedIndicator = vecRecordSet.size() - 1;
/*
 * Weitere Variable die notwendig sind um eine planbare Steuerung der for-Schleifen zu
 * erreichen.
  */
      
int intLowerAlreadySortedIndex = intLowestSortedIndicator;
      
int intUpperAlreadySortedIndex = intHighestSortedIndicator;
/* 
 * Für den Vergleich von Text wird ein Collator verwendet; dieser sorgt auch für die
 
 * passende Reihenfolge von Umlauten. */

      java.text.Collator locCollator = java.text.Collator.getInstance();
      locCollator.setStrength(java.text.Collator.
TERTIARY);
/* 
 
 * In der while-Schleife das Vergleichen der BO so lange ausführen bis
 * in den for-Schleifen kein Tausch mehr erfolgt ist.
 
 * Das wird daran erkannt, dass die Variablen mit den Indizes, wie weit die Liste
 
 * schon sortiert ist, noch einen zu untersuchenden Bereich anzeigen. */

      
while (intLowestSortedIndicator < intHighestSortedIndicator) {
/* 
 
 * Zuerst wird die Liste mit den BO von 'unten' (niederster Index) nach 'oben'
 
 * durchlaufen. Dabei wandern die 'größeren' BO nach 'oben'. */
/* 
 
 * Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim  
 * Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darüber sind schon in der richtigen Reihenfolge. */

        intUpperAlreadySortedIndex = intHighestSortedIndicator;

/* 
 
 * Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf den
  
 * Wert des unteren Indikators setzen. Damit wird die while-Schleife beendet
  
 * wenn in der folgenden for-Schleife kein Tausch mehr erfolgt. */

        intHighestSortedIndicator
= intLowestSortedIndicator;
/* 
 
 * Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab dem
beim  
 * Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darunter sind schon in der richtigen Reihenfolge - und geht bis
  
 * zu jenem Index, bei dem beim Durchlauf von 'unten' nach 'oben' kein Tausch
  
 * mehr erfolgt ist.
 */
        
for (intIndex = intLowestSortedIndicator + 1;
             intIndex
<= intUpperAlreadySortedIndex;
             intIndex++
) {
/* 
 
 * Die beiden zu vergleichenden BO aus der Liste 'holen'. */

          
struct1application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex - 1);
          
struct2application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex);
/* 
 
 * Der folgende Vergleich ist Ihren individuellen Anforderungen anzupassen.
 
 * Der Muster-Code geht davon aus, dass Variablen der Klasse 'String' verglichen werden
 
 * und benutzt den 'Collator'
- bei numerischen Werten vereinfacht sich der Vergleich. */
          
if (     (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) < 0)
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) < 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) < 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_4.trim(),
                    
                   struct2application_entity_BO.Variable_4.trim()) < 0))
             
) {
/* 
 
 * BO sind in falscher Reihenfolge und müssen vertauscht werden. */

            
vecRecordSet.setElementAt(struct2application_entity_BO, intIndex - 1);
            
vecRecordSet.setElementAt(struct1application_entity_BO, intIndex);
/* 
 
 * Indikator, wie weit die Liste sortiert ist, anpassen. */

            
intHighestSortedIndicator = intIndex;
          }
        }
/* 
 
 * Jetzt wird die Liste mit den BO von 'oben' (höchster Index) nach 'unten'
 
 * durchlaufen. Dabei wandern die 'kleineren' BO nach 'unten'. */
/* 
 
 * Der Durchlauf in der for-Schleife endet bei jenem Index, ab dem
beim  
 * Sortieren von 'oben' nach 'unten' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darunter sind schon in der richtigen Reihenfolge. */

        intLowerAlreadySortedIndex = intLowestSortedIndicator;

/* 
 
 * Indikator, bei welchem Index der letzte Tausch von BO erfolgt ist auf den
  
 * Wert des oberen Indikators setzen. Damit wird die while-Schleife beendet
  
 * wenn in der folgenden for-Schleife kein Tausch mehr erfolgt. */

        intLowestSortedIndicator
= intHighestSortedIndicator;
/* 
 
 * Der Durchlauf in der for-Schleife wird bei jenem Index begonnen, ab dem
beim  
 * Sortieren von 'unten' nach 'oben' kein Tausch der BO mehr erfolgt ist - d.h.
  
 * alle BO darüber sind schon in der richtigen Reihenfolge - und geht bis
  
 * zu jenem Index, bei dem beim Durchlauf von 'oben' nach 'unten' kein Tausch
  
 * mehr erfolgt ist.
 */
        
for (intIndex = intHighestSortedIndicator - 1;
             intIndex
>= intLowerAlreadySortedIndex;
             intIndex--
) {
/* 
 
 * Die beiden zu vergleichenden BO aus der Liste 'holen'. */

          
struct1application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex);
          
struct2application_entity_BO =
              (
application_entity_BO) vecRecordSet.elementAt(intIndex + 1);
/* 
 
 * Der folgende Vergleich ist gleich wie beim Sortieren von 'unten' nach 'oben'.

 * Es ist zeitsparend, den einmal codierten Vergleich hierher zu kopieren. */

          
if (     (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) < 0)
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) < 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) < 0))
             
| (  (locCollator.compare(struct1application_entity_BO.Variable_1.trim(),
                    
                   struct2application_entity_BO.Variable_1.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_2.trim(),
                    
                   struct2application_entity_BO.Variable_2.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_3.trim(),
                    
                   struct2application_entity_BO.Variable_3.trim()) == 0)
             
   & (locCollator.compare(struct1application_entity_BO.Variable_4.trim(),
                    
                   struct2application_entity_BO.Variable_4.trim()) < 0))
             
) {
/* 
 
 * BO sind in falscher Reihenfolge und müssen vertauscht werden. */

            
vecRecordSet.setElementAt(struct2application_entity_BO, intIndex);
            
vecRecordSet.setElementAt(struct1application_entity_BO, intIndex + 1);
/* 
 
 * Indikator, wie weit die Liste sortiert ist, anpassen. */

            
intLowestSortedIndicator = intIndex;
          }
        }
      }
    
}

Üblicherweise wird die Methode zum Sortieren in einer Methode zugehörigen BOS-Set aufgerufen - und zwar bevor die Methode ordnungsgemäß beendet wird.

Unter bestimmten Voraussetzungen kann die Methode auch im zugehörigen BOC-Set aufgerufen werden.
Das ist dann sinnvoll, wenn die CPU-Zeit auf einem Server zu bezahlen ist und daher möglichst viel Rechenleistung auf einem Client-Computer ausgeführt werden soll.

zum Inhaltsverzeichnis

Weitere Schritte und verwandte Dokumentation

Dokument

Inhalt

Tutorial: JavaScout ProjectAssist (Java_Fatclient_01) – General BO-Set Klasse für eine Liste mit 'ProjectLanguage' Business-Objects  

Schritt desTutorials für die Entwicklung von Heavyweight-Client Anwendungen in dem die Implementierung der Generellen BO-Set Klasse vorgestellt wird.

Muster-Code für ein BO

Muster-Code für die BO-Klasse mit der Definition der Variablen des Business-Object.

zum Inhaltsverzeichnis