2016-04-19 5 views
1

Ich versuche, eine Java-Klasse für ein Liniendiagramm (mit Builder-Muster) zu erstellen, die viele Eigenschaften enthält. Basierend auf der Anwendung dieser Eigenschaften versuche ich, innere Builder-Klassen zu erstellen (z. B. X-Achsen-Eigenschaften, Y-Achsen-Eigenschaften usw.). Ich bin neu in Java und ich würde gerne wissen, ob es möglich ist, Builder-Objekte wie unten in meinem Beispiel aufzurufen. Ich folgte einem Link Can the builder pattern ever be doing too much?. das würde Objekte in Inkrementen bauen. Ich mochte die Idee. Ich weiß jedoch nicht, wie ich es für mein Szenario verwenden könnte.Verschachtelungsersteller Musterklassen in Java

Invoke-Methode:

new LineGraph().UiPropBuilder(ctx) 
       .setBackgroundColor(Color.BLUE) 
       .build() 
       .XAxisProperties() 
       .enableGridLines(true) 
       .build() 
       .YAxisProperties() 
       .enableGridLines(false) 
       .build(); 

Ist es möglich, zu nennen .build() Anweisung nur einmal alle Objekte zu erstellen, anstatt sie mehrere Male des Wiederholens?

Klasse:

public class LineGraph{ 

    private LineGraph() 

    public static class UiPropBuilder{ 

     private Integer mBackgroundColor; 
     private Boolean bTouchEnabled; 
     ... 

     public UiPropBuilder (Context ctx) { this.ctx = ctx; } 

     public UiPropBuilder setBackgroundColor(Integer mBackgroundColor){ this.mBackgroundColor = mBackgroundColor; return this;} 

     public UiPropBuilder touchEnabled(Boolean bTouchEnabled){ this.bTouchEnabled = bTouchEnabled; return this;} 

     ... some more properties... 
     public UiPropBuilder build(){ return new UiPropBuilder(this); }  

    } 

// X-Axis properties builder 
public static class XAxisProperties{ 
    // variable declarations and constructor omitted 
    public XAxisProperties enableGridLines(Boolean enable) {this.enable = enable); return this;} 
    public XAxisProperties build(){ return new XAxisProperties(this);} 


// Y-Axis properties Builder 

public static class YAxisProperties{ 
    // variable declarations and constructor omitted 
    public YAxisProperties enableGridLines(Boolean enable) {this.enable = enable); return this;} 
    public YAxisProperties build(){ return new YAxisProperties(this);} 
} 
+0

In Ihrer Frage "Anweisung .build() nur einmal aufrufen, um alle Objekte zu erstellen". Konnte man schreiben "Anweisung .build()" nur einmal zu erstellen, um das mit allen Eigenschaften zu erstellen " – alphablue

Antwort

1

Eine Möglichkeit, es so wäre tun könnte, wo man 3-Builder-Objekte haben, die alle aufeinander verweisen können und zwischen ihnen wechseln. Es ist ähnlich zu dem, was waren Sie bereits versucht zu tun:

public static class UiPropBuilder { 
    private XAxisProperties xAxisProperties = new XAxisProperties(); 
    private YAxisProperties yAxisProperties = new YAxisProperties(); 
    // ... 
    public XAxisProperties xAxisProperties() { return xAxisProperties; } 
    public YAxisProperties yAxisProperties() { return yAxisProperties; } 

    public LineGraph build() { 
     return new LineGraph(..., ..., ..., ...); 
    } 

    public class XAxisProperties { 
     // ... 
     public YAxisProperties yAxisProperties() { yAxisProperties; } 
     public UiPropBuilder uiProperties() { return UiPropBuilder.this; } 
     public LineGraph build() { return UiPropBuilder.this.build(); } 
    } 

    public class YAxisProperties { 
     // ... 
     public XAxisProperties xAxisProperties() { return xAxisProperties; } 
     public UiPropBuilder uiProperties() { return UiPropBuilder.this; } 
     public LineGraph build() { return UiPropBuilder.this.build(); } 
    } 
} 

Ein komplizierteres Beispiel ist etwas ähnlich wie ein Schritt Builder arbeitet so zu schreiben. Wir definieren Schnittstellen für jeden der "Schritte" und implementieren sie alle in einer einzigen Klasse. Jede der Methoden, die die Eigenschaften "umschaltet", gibt tatsächlich this zurück.

public interface BuildStep  { LineGraph  build();   } 
public interface UiSwitchStep { UiPropBuilder uiProperties(); } 
public interface XAxisSwitchStep { XAxisPropBuilder xAxisProperties(); } 
public interface YAxisSwitchStep { YAxisPropBuilder yAxisProperties(); } 

public interface UiPropBuilder 
extends XAxisSwitchStep, YAxisSwitchStep, BuildStep { 
    // UI property setters 
    // ... 
} 

public interface XAxisPropBuilder 
extends YAxisSwitchStep, UiSwitchStep, BuildStep { 
    // X-axis property setters 
    // ... 
} 

public interface YAxisPropBuilder 
extends XAxisSwitchStep, UiSwitchStep, BuildStep { 
    // Y-axis property setters 
    // ... 
} 

private static class UiBuilderImpl 
implements UiPropBuilder, XAxisPropBuilder, YAxisPropBuilder { 
    // implement ALL property setters 
    // ... 

    @Override 
    public XAxisProperties xAxisProperties() { 
     return this; 
    } 
    @Override 
    public YAxisProperties yAxisProperties() { 
     return this; 
    } 
    @Override 
    public UiPropBuilder uiProperties() { 
     return this; 
    } 
    @Override 
    public LineGraph build() { 
     return new LineGraph(..., ..., ..., ...); 
    } 
} 

// create new builders through a static method 
// which returns the interface type 
public static UiPropBuilder builder() { 
    return new UiBuilderImpl(); 
}