Sie sind auf Seite 1von 4

Aufgaben 

zur Übung Software Engineering SE‐1                C3 
Schritt 3: Aufteilung von Funktionen auf Komponenten, Punkte: 2           
1.) Erstellen Sie eine neue Klasse Application_C3.java im Paket application, welche die neue Struktur 
verwendet und zu Beginn die ComponentFactory erzeugt, indem die statische Methode getInstance() 
aufgerufen wird. Damit werden auch alle System‐Komponenten erzeugt und deren Referenzen über die 
Methoden der Factory‐Klasse zugänglich gemacht: 
 
public final class Application_C3 {
   
    public static void main( String[] args ) { 
      System.out.println( "SE1‐Bestellsystem" ); 
      ComponentFactory componentFactory = ComponentFactory.getInstance(); 
      Components.OutputProcessor outputProcessor =  
  componentFactory.getOutputProcessor(); 

      Components.DataFactory dataFactory = componentFactory.getDataFactory(); 
      Components.OrderProcessor orderProcessor = 
componentFactory.getOrderProcessor(); 
 
    /* 
       * Erzeugung der Kunden, Artikel und Bestellungen aus Application_1.java 
       */ 
    List<Order> orders = new ArrayList<Order>( List.of( ... ) ); 
   
      outputProcessor.printOrders( orders, false );  // Ausgabe aller Bestellungen 
  } 
  } 
 
Die Methode printOrders( orders, … ); ist nicht länger eine Methode in der Hauptklasse, sondern wurde 
in die Komponente OutputProcessor verlagert. Sie kann daher über die Referenz outputProcessor 
aufgerufen werden. 
Übertragen Sie die Erzeugung der Bsp.‐Kunden, ‐Artikel und ‐Bestellungen aus Application_B1.java . 
Wenn Sie das Programm starten, werden Sie jedoch (noch) eine leere Ausgabe sehen: 
SE1‐Bestellsystem 
da die Methode printOrders() in OutputProcessor.java noch nicht implementiert ist. 
2.) Übertragen Sie Ihre Implementierung von printOrders() aus der vorherigen Übung B in die Klasse 
OutputProcessor.java in den dort generierten Stub der Methode. Übertragen Sie auch alle privaten 
Methoden aus Application_B1.java in die entsprechenden Stubs in OutputProcessor.java : 
 fmtPrice( long price, String currency ), 
 fmtPrice( long price, String currency, int width ) und 
 fmtLine( String leftStr, String rightStr, int width ). 

3.) Des weiteren befinden sich in OutputProcessor.java die Stubs für die Methoden zur Umwandlung von 
Kunden‐Namen. Übertragen Sie auch hierfür den Code und entfernen Sie die Methoden getName() und 
setName( String name ) aus Customer.java., so dass nur die Getter‐ und Setter‐Methoden für firstName, 
lastName und contact übrig bleiben sowie die Methode getId(); Damit wird erreicht, dass Klassen im 
Paket datamodel „keine Logik“ mehr enthalten, sondern nur „Daten“, d.h. Informationen über Kunden, 
Artikel und Bestellungen. Die Logik befindet sich fortan in den Komponenten des Pakets system. 


 
Übertragen Sie den Code der Namensumwandlung aus Customer.java in die Stubs der Klasse Output‐
Processor.java . Entfernen Sie die Methoden getName(), setName(…) in Customer.java und initialisieren 
Sie im Konstruktor den Nachnamen mit dem Parameter name und den Vornamen mit ““. 
  /** 
   * Split single‐String name to first‐ and last name and set to the customer 
 * object, e.g. single‐String "Eric Meyer" is split into "Eric" and "Meyer". 
   *  
   * @param customer object for which first‐ and lastName are set 
 * @param name single‐String name that is split into first‐ and last name 
   * @return returns single‐String name extracted from customer object 
 */ 
 
@Override 
  public String splitName( Customer customer, String name ) { 
    // ... 

 
 
  /** 
 * Returns single‐String name obtained from first‐ and lastName attributes of 
   * Customer object, e.g. "Eric", "Meyer" returns single‐String "Meyer, Eric". 
   *  
 * @param customer object referred to 
   * @return sanitized name derived from first‐ and lastName attributes 
   */ 
  @Override 
public String singleName( Customer customer ) { 
    // ... 
  } 

4.) Wenn Sie in der Methode printOrders( orders, … ) die Ausgabe des Kundennamens einer Bestellung 
ändern zu: 
  Customer customer = order.getCustomer(); 
  String customerName = splitName( customer, customer.getFirstName() + " " + 
customer.getLastName() ); 
und den erhaltenen Kundennamen in der Ausgabe der Bestellungen verwenden, sollten Sie bei der 
Ausführung von Application_C3 die folgende Ausgabe erhalten (printLineWidth = 95): 
 
SE1‐Bestellsystem 
  ‐‐‐‐‐‐‐‐‐‐‐‐‐ 
  #5234968294, Schulz‐Mueller, Eric's Bestellung: 1x Kanne                20,00 EUR 
#8592356245, Schulz‐Mueller, Eric's Bestellung: 4x Teller, 8x Becher... 49,84 EUR 
  #3563561357, Meyer, Anne's Bestellung: 1x Kanne aus Porzellan           20,00 EUR 
  #6135735635, Blumenfeld, Nadine Ulla's Bestellung: 12x Teller blau/w... 77,88 EUR 
  #4835735356, Werner, Timo's Bestellung: 1x Kaffeemaschine, 6x Tasse     47,93 EUR 
#6399437335, Müller, Sandra's Bestellung: 1x Teekocher, 4x Becher, 4... 51,91 EUR 
  ‐‐‐‐‐‐‐‐‐‐‐‐‐                                                       ‐‐‐‐‐‐‐‐‐‐‐‐‐ 
  Gesamtwert aller Bestellungen:                                         267,56 EUR 
 
Bestellwerte werden korrekt berechnet und ausgegeben:          [ 1 Pkt ] 
Kundennamen mit Nachname, Vorname werden korrekt ausgegeben:        [ 1 Pkt ] 


 
Aufgaben zur Übung Software Engineering SE‐1                C4 
Schritt 4: Einbau der DataFactory zur zentralen Erzeugung der Geschäftsobjekte, Punkte: 4     
Im abschließenden Teil dieser Übung soll eine weitere Factory für die Erzeugung der Objekte der Klassen 
aus dem Paket datamodel eingeführt werden. Bislang können diese Objekte mit new ohne Einschrän‐
kung erzeugt werden, z.B. auch mehrere Kunden‐Objekte mit demselben ID, da der ID bislang einfach 
dem Konstruktor übergeben wird: 
  Customer cAnne = new Customer( "C64327", "Meyer, Anne", "+4917223524" ); 
  Customer cNadine = new Customer( "C64327", "Nadine Blumenfeld", nub@gmx.de" ); 
Diese Fehlerquelle soll vermieden werden, indem keine direkte Erzeugung der (Daten‐) Objekte aus dem 
Paket datamodel mehr mit new möglich sein soll und statt dessen durch die eingeführte Komponente 
der DataFactory erfolgen soll, die wie folgt definiert wurde: 

Das Interface hat die entsprechenden Erzeugungs‐Methoden für Kunden, Artikel, Bestellungen und Be‐
stellpositionen – jedoch ohne Parameter für ID, welche von der DataFactory zentral erzeugt werden. Im 
Gegensatz zur ComponentFactory können beliebig viele Objekte der jeweiligen Klassen erzeugt werden. 
1.) Da DataFactory die alleinige Komponente im System sein soll, welche die Erzeugung der Geschäfts‐
objekte ermöglicht, müssen in einem ersten Schritt die bislang öffentlichen (public) Konstruktoren der 
Klassen im Paket datamodel auf den Zugriff ‚protected‘ geändert werden. 
Führen Sie diese Änderung in den Klassen Customer, Article, Order und OrderItem aus. 
public Customer( ... )   protected Customer( ... ) { } oder 
 Customer( ... ) { }  // ebenfalls protected 
Daraufhin erscheinen u.a. in Application_C3.java erwartbare Fehler: „Constructor is not visible“, da ein 
protected‐Konstruktor nur innerhalb des Pakets datamodel aufgerufen werden kann. 
2.) Stellen Sie in Application_2.java die Erzeugung der Beispiel‐/Mock‐Objekte auf die Erzeugung mit 
Methoden der DataFactory um: 
  public final class Application_C3 {
   
  public static void main( String[] args ) { 
 
    System.out.println( "SE1‐Bestellsystem" ); 
 
      ComponentFactory componentFactory = ComponentFactory.getInstance(); 

      Components.DataFactory dataFactory = componentFactory.getDataFactory(); 
      ... 
 


 
 
    /* 
       * Erzeugung der Kunden, Artikel und Bestellungen über die DataFactory... 
       */ 
    Customer cEric = dataFactory.createCustomer( "Eric Schulz‐Mueller",  
  "eric2346@gmail.com" ); 
      Customer cAnne = dataFactory.createCustomer( "Meyer, Anne", "+4917223524" ); 
      Article aTasse = dataFactory.createArticle( "Tasse", 299, 2000 ); 
      Article aBecher = dataFactory.createArticle( "Becher", 149, 8400 ); 
      // Eric's 1st order 
      Order o5234 = dataFactory.createOrder( cEric ); 
    OrderItem oi1 = dataFactory.createOrderItem( 
  aKanne.getDescription(), aKanne, 1 );  // 1x Kanne 
      o5234.addItem( oi1 ); 
      List<Order> orders = new ArrayList<Order>( List.of( o5234,  ... ) ); 
      outputProcessor.printOrders( orders, false );  // Ausgabe aller Bestellungen 
    } 

 
Daraufhin sollten die Compiler‐Fehler verschwinden, die Anwendung ist aber noch nicht ablauffähig, da 
die Implementierung der DataFactory noch fehlt. 
3.) Damit DataFactory Objekte im Paket datamodel erzeugen kann, ist dort eine Stellvertreter‐Factory 
erforderlich, die hier RawDataFactory genannt wird und zu der eine Abhängigkeit besteht (siehe UML 
Komponenten‐Diagramm). 
In Moodle finden Sie die Klassen RawDataFactory.java und DataFactory.java, die Sie bitte in die Pakete 
datamodel bzw. system einfügen. Anschließend können Sie die Abhängigkeit im privaten Konstruktor 
der Klasse ComponentFactory einfügen: 
 
  private ComponentFactory() { 
 
    ... 
 
    // Object objectRawFactory = null; 
 
    RawDataFactory.RawDataFactoryIntf objectRawFactory = 
  RawDataFactory.getInstance( this ); 
      this.dataFactory = new DataFactory( objectRawFactory, 
  inventoryManager, outputProcessor ); 
  } 
 
Entfernen Sie Application_XX.java aus früheren Übungen, da diese Fehler verursachen. Am Ende sollte 
das Programm Application_C3.java die Liste der Bestellungen wie vorher (siehe Ausgabe in Aufgabe B1) 
erzeugen.                      [ 1 Pkt ] 
4.) Prüfen Sie, dass in den Klassen der Geschäftsobjekte in datamodel nur Getter‐ und Setter‐Methoden 
enthalten sind und kein anderweitiger Code und dass die Konstruktoren protected sind.    [ 1 Pkt ] 
5.) Analysieren Sie den Code der Klasse RawDataFactory und beantworten Sie die Fragen:  [ 2 Pkt ] 
a. Was ist der Zweck dieser Klasse? Warum ist sie notwendig? 
b. Erklären Sie die Wirkungsweise der Methode getInstance() ? 
c. Wie wird erreicht, dass die Klasse system.DataFactory die einzige Klasse ist, welche die Funktion 
der Klasse RawDataFactory benutzen kann?