2015-01-09 8 views
8

Ich habe viele Wertobjekte in meinem Projekt.Java BuilderTestPattern - Wie vermeidet man den Standard?

I Projekt lombok bin mit etwas Textvorschlag zu beseitigen, so sehen meine Wertobjekte wie die folgenden:

@Value 
@Accessors(fluent = true) 
public class ValueObject { 

    private final String firstProp; 
    private final int secondProp; 

} 

Nicht schlecht, so gut wie keine vorformulierten.

Und jetzt benutze ich den All-Args-Konstruktor ziemlich oft in meinen Tests. Es sieht ziemlich chaotisch, so dass ich dachte, dass ich stattdessen Builder Pattern Variante vorstellen:

public class ValueObjectBuilder { 

    private static final int DEFAULT_VALUE_FOR_SECOND_PROP = 666; 

    private String firstProp = "default value for first prop; 
    private int secondProp = DEFAULT_VALUE_FOR_SECOND_PROP; 

    private ValueObjectBuilder() {} 

    public static ValueObjectBuilder newValueObject() { 
     return new ValueObjectBuilder(); 
    } 

    public ValueObjectBuilder withFirstProp(String firstProp) { 
     this.firstProp = firstProp 
     return this; 
    } 

    public ValueObjectBuilder withFirstProp(int secondProp) { 
     this.secondProp = secondProp; 
     return this; 
    } 

    public ValueObject build() { 
     return new ValueObject(
       firstProp, secondProp 
     ); 
    } 
} 

und der Code sieht ganz nett jetzt:

ValueObjectBuilder 
.newValueObject() 
.withFirstProp("prop") 
.withSecondProp(15) 
.build(); 

Nun das Problem ist - wie ich bereits erwähnt, ich habe um viele ähnliche Klassen zu schreiben ... Ich bin schon müde mit dem Kopieren-Einfügen von ihnen.

Wonach ich suche, ist ein Black-Magic-Smart-Tool, das diesen Code irgendwie für mich generieren wird.

Ich weiß, es gibt eine @Builder Annotation in Lombok, aber es erfüllt nicht meine Anforderungen. Hier ist warum:

1) Ich kann keine Standardwerte in Lombok Builder bereitstellen. Nun, eigentlich ist es möglich - durch die Implementierung von Builder-Klasse Vorlage selbst wie

@Builder 
public class Foo { 
    private String prop; 

    public static class FooBuilder() { 
     private String prop = "def value"; 
     ... 
    } 

} 

, die einige Boilerplate zu generieren.

2) Ich kann keine Möglichkeit finden, Präfix auf jedem Feld Accessor in Lombok Builder zu setzen. Vielleicht könnte @Wither hier helfen? Aber ich weiß nicht, wie man es richtig benutzt.

3) Der wichtigste Grund: Ich erschaffe keinen "natürlichen" Erbauer. Soweit ich verstehe, ist Lombok entworfen, um Builder für eine bestimmte, annotierte Klasse zu erstellen - ich weiß nicht, ob es eine Möglichkeit gibt, ein anderes Objekt aus der Methode build() zurückzugeben.

Also, um zusammenzufassen: Kennen Sie irgendein Werkzeug, das mir möglicherweise helfen könnte? Oder sind all die Dinge, die ich erwähnt habe, tatsächlich mit Lombok möglich?

EDIT

Ok, so finde ich wahrscheinlich eine Lösung zu diesem speziellen Fall. Mit lombok können wir verwenden:

@Setter 
@Accessors(chain = true, fluent = true) 
@NoArgsConstructor(staticName = "newValueObject") 
public class ValueObjectBuilder { 
    private String firstProp = "default"; 
    private int secondProp = 666; 

    public ValueObject build() { 
     return new ValueObject(firstProp, secondProp); 
    } 
} 

Cheers, Slawek

Antwort

1

Versuchen Bob-the-builder für Eclipse. Hmm .. Ich denke, das funktioniert am besten, wenn du Eclipse benutzt! Wenn Sie Eclipse nicht verwenden, werden unten auf der Seite, die hier nützlich sein kann, einige verwandte Projekte erwähnt.

+0

Danke: Erstens benutze ich IDEA - hast du sie damit ausprobiert? Zweitens suche ich eigentlich nach etwas was könnte meinen Code in der Art erzeugen, wie Lombok es tut - ohne all diese Unordnung. – slnowak

+0

Ich habe leider nicht. Ich höre IDEA ist ausgezeichnet und ich glaube es, weil ich RubyMine vorher benutzt habe und das ist fantastisch für Ruby Arbeit! Ich weiß, dass diese Generatoren nicht sind ziemlich s o glatt wie Lombok ... (gelöscht und ersetzt, um die korrekte Schreibweise von Lombok zu korrigieren!) – unigeek

5

Ich weiß, dass das alt ist, aber wenn irgendjemand anderes dazu kommt, fand ich eine alternative Lösung für die Bereitstellung von Standardwerten für einen Builder.

Überschreiben Sie die Builder-Methode und geben Sie die Standardwerte ein, bevor Sie einen Builder zurückgeben. So im obigen Fall:

@Builder 
public class Foo { 
    private String prop; 

    public static FooBuilder builder() { 
     return new FooBuilder().prop("def value"); 
    } 
} 

Es ist keine ideale Lösung, aber schlage mit der ganzen Baumeister selbst außer Kraft zu setzen oder einen benutzerdefinierten Konstruktor hat (die schmerzhafte IMHO ist, wenn es eine Menge von Variablen Es wäre immer noch schön sein. etwas in der Form einer @With- oder @Default-Annotation zu haben

+0

Danke, ich werde es später überprüfen! – slnowak

+1

@mikea Welche Version verwenden Sie? Ich versuche, aber erhalte eine Kompilierung Fehler 'FooBuilder ist nicht öffentlich und kann nicht von außen Paket zugegriffen werden – nKognito

+0

@nKognito 1.16.4 – mikea

Verwandte Themen