Builder:Location

Aus MimiPedia

Wohin mit dem Builder?

Es giebt zwei Orte, an dem man den Builder unterbringen kann. Man kann ihn als separate Klasse irgendwo' ablegen, oder man kann ihn als member class in der Generat-Klasse ansiedeln. Wo man den Builder unterbringt ist wohl im wesentlichen eine Geschmacksfrage. Hat man keine Möglichkeit die Generat-Klasse zu ändern, bleibt allerdings nur die Möglichkeit, den Builder als separate Klasse zu implementieren.

Der Builder als eigene Klasse

Eigentlich giebt es hierzu nicht viel zu sagen, der Aufbau des Builder ist ziemlich simpel. nehmen wir als Beispiel folgende Klasse als Beispiel:

class Person {
   private String vorname;
   public String getVorname() {
      return vorname;
   }

   public String setVorname(String vorname) {
      this.vorname = vorname;
   }
}

dann sieht der Builder dazu so aus:

class PersonBuilder {
   private Person person = new Person();

   public PersonBuilder withVorname(String vorname) {
      person.setVorname(vorname);
      return this;
   }
   
   public Person get() {
      return person;
   }
}

Nichts Aufregendes hier. Wenn der Builder im gleichen Package angesiedelt ist wie die Generat-Klasse und die Felder des Generats package visibility haben (public sollten sie niemals sein), dann können wir die Modifier-Methoden darauf umschreiben und auf die Indirektion durch den setter verzichten:

public PersonBuilder withVorname(String vorname) {
   person.vorname = vorname;
   return this;
}

In diesem Falle können wir auf den Setter in der Generat-Klasse verzichten und das Feld im Generat immutable machen, oder wir können den Builder für die Manipulation verwenden. Auf diese Weise können wir die vollkommene Kontrolle über die Generat-Felder halten.

Der Builder als member class

Über den Unterschied zwischen member class und inner class sein an dieser Stelle auf die Java-Spec verwiesen. Es genüge an dieser Stelle, daß die member class -- im Gegensatz zur inner class -- unabhängig von der sie umgebenden Klasse zu erzeugen.

Wir verwenden die gleiche Klasse wie oben und fügen den Builder dort ein:

class Person {
   private String vorname;
   String getVorname() {
      return vorname;
   }
   public static class Builder {
      private Person person = new Person();
      Builder withVorname(String vorname) {
         person.vorname = vorname;
         return this;
      }
 
      Person get() {
         return person;
      }
   }
}

Zwei Unterschiede fallen in's Auge: da der Builder in der Generat-Klasse liegt, können wir ihn einfach "Builder" nennen, die Verwendeung sieht damit so aus:

Person person = new Person.Builder().withVorname("Peter").get();

Die Sichtbarkeit der Felder spielt nun keine Rolle mehr. Da die fiel class vollen Zugriff auch auf die private-Felder der Klasse hat die sie enthält, brauchen wir keine Setter mehr. Natürlich können wir welche definieren, brauchen sie aber nicht für den Builder und müssen die Sichtbarkeit nicht mehr aufzuweichen.