2015-02-04 11 views
5

Als ich Builder-Muster in Joshs Bloch Buch überprüfte, kam ich mit einfacheren Implementierung, aber ich bin nicht sicher, ob es richtig ist. Zum Beispiel:Weniger ausführliche Builder-Muster?

public class Test { 
    public static void main(String[] args) { 
     Numbers first = new Numbers.Builder().setD(3.14).build(); 
     System.out.println(first); 
     Numbers second = new Numbers.Builder().setI(17).setF(1.24F).build(); 
     System.out.println(second); 
     System.out.println(first); 
    } 
} 

final class Numbers { 
    private int i; 
    private long l; 
    private float f; 
    private double d; 

    private Numbers() {} 


    public static class Builder { 
     private final Numbers instance = new Numbers(); 

     public Builder setI(int i) { 
      instance.i = i; 
      return this; 
     } 

     public Builder setL(long l) { 
      instance.l = l; 
      return this; 
     } 

     public Builder setF(float f) { 
      instance.f = f; 
      return this; 
     } 

     public Builder setD(double d) { 
      instance.d = d; 
      return this; 
     } 

     public Numbers build() { 
      return instance; 
     } 
    } 

    @Override 
    public String toString() { 
     return String.format("%4d %4d %7.3f %7.3f", i, l, f, d); 
    } 
} 

Ist es immer noch kann als Builder Muster betrachtet werden oder ich etwas verpasst?

EDIT

Was ist das?

//... 

private Numbers() {} 


private Numbers(Numbers o) { 
     i = o.i; 
     l = o.l; 
     f = o.f; 
     d = o.d; 
    } 

public static class Builder { 
     private final Numbers instance = new Numbers(); 

      //... 

     public Numbers build() { 
      return new Numbers(instance); 
     } 
    } 
+5

Ein großes Problem bei diesem Ansatz besteht darin, dass Sie jedes Mal, wenn Sie build() mehrmals auf demselben Builder aufrufen, immer die gleiche Instanz haben. –

+0

@JB Nizet oh, rechts, Builder ist public -_- ty – Dmytro

+0

Erzeuge die Builder Instanz in der build() Methode –

Antwort

4

Das Problem mit Ihrem Code ist, dass, wenn Sie build zweimal für die gleiche Builder Instanz aufrufen, werden Sie die gleiche Numbers Instanz erhalten. Und wenn Sie Methoden der Builder aufrufen, nachdem Sie build aufgerufen und die Numbers Instanz erhalten haben, werden Sie diese Instanz ändern. Die vom Builder erstellte Instanz sollte unabhängig vom Builder sein, sobald sie erstellt wurde.

+0

Ich sehe jetzt, danke. – Dmytro

+4

Die anderen Probleme damit sind, dass es bedeutet, dass keines Ihrer Felder "final" sein kann, und Ihr Konstruktor kann keine Validierung für die Felder durchführen (vielleicht möchten Sie eine Logik, die von mehreren Feldern abhängt, wie "if i == 3 dann kann f nicht negativ sein "). – yshavit

+0

@yshavit so jetzt (nach Bearbeitung) der Nachteil dieses Ansatzes ist, dass ich Invarianten nicht überprüfen kann? – Dmytro

Verwandte Themen