2015-02-04 10 views
5

Quando stavo rivedendo modello Builder nel libro di Josh's Bloch, ho trovato un'implementazione più semplice, ma non sono sicuro che sia corretto. Per esempio:Pattern di builder meno dettagliato?

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); 
    } 
} 

Is It può ancora essere considerato come un modello Builder o mi sono perso qualcosa?

EDIT

Che dire di questo?

//... 

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

Un grosso problema con questo approccio è che se si chiama build() più volte sullo stesso builder, si finisce con la stessa istanza ogni volta. –

+0

@JB Nizet oh, giusto, Builder è public -_- ty – Dmytro

+0

Creare l'istanza Builder nel metodo build() –

risposta

4

Il problema con il vostro codice è che se si chiama build due volte per lo stesso Builder esempio, si otterrà lo stesso Numbers istanza. E se chiami i metodi dello Builder dopo aver chiamato build e ottenuto l'istanza Numbers, cambierai quell'istanza. L'istanza creata dal builder dovrebbe essere indipendente dal Builder una volta creata.

+0

Vedo ora, grazie. – Dmytro

+4

Gli altri problemi con questo sono che significa che nessuno dei tuoi campi può essere 'final', e il tuo costruttore non può eseguire alcuna convalida sui campi (forse vuoi una logica che dipende da più campi, come" se i == 3 quindi f non può essere negativo "). – yshavit

+0

@yshavit così ora (dopo la modifica) lo svantaggio di questo approccio è che non riesco a controllare gli invarianti? – Dmytro

Problemi correlati