2013-10-02 35 views
5

Jakie są zalety między używaniem wzorca budowniczego wewnątrz i poza klasą?Builder Pattern inside vs outside class?

Wewnątrz klasy:

public class Person { 
    private String name; 
    private String eyeColor; 
    private String hairColor; 

    public Person setName(String name) { 
     this.name = name; 
     return this; 
    } 

    public Person setEyeColor(String eyeColor) { 
     this.eyeColor = eyeColor; 
     return this; 
    } 

    public Person setHairColor(String hairColor) { 
     this.hairColor = hairColor; 
     return this; 
    } 
} 

// Example usage: 
Person p = new Person() 
       .setName("Bob") 
       .setHairColor("Black") 
       .setEyeColor("Brown") 

klasa zewnętrzna:

public class Person { 
    private String name; 
    private String eyeColor; 
    private String hairColor; 

    public Person(String name, String eyeColor, String hairColor) { 
     this.name = name; 
     this.eyeColor = eyeColor; 
     this.hairColor = hairColor; 
    } 
} 

public class PersonBuilder { 
    private String name; 
    private String eyeColor; 
    private String hairColor; 

    public Person build() { 
     return new Person(name, eyeColor, hairColor); 
    } 

    public PersonBuilder with(String name) { 
     this.name = name; 
     return this; 
    } 

    public PersonBuilder setEyeColor(String eyeColor) { 
     this.eyeColor = eyeColor; 
     return this; 
    } 

    public PersonBuilder setHairColor(String hairColor) { 
     this.hairColor = hairColor; 
     return this; 
    } 
} 

// Example usage: 
Person p = new PersonBuilder() 
       .setName("Bob") 
       .setHairColor("Black") 
       .setEyeColor("Brown") 
       .build(); 
+0

To jest oparte na opiniach ... Ale myślę, że posiadanie tego w środku obniża poziom bałaganu. Możesz mieć MyClass.Builder, MyClass2.Builder, itd. - i nie mieć całej gamy klas MyClassBuilder, MyClass2Builder, itp. – ppeterka

+0

Dla prostych rzeczy to naprawdę nie ma znaczenia, jednak możesz chcieć użyć typów zwrotnych ustawiających dla innych wskazanie (w kompleksowych ustawieniach), w którym to przypadku zewnętrzna oferowałaby większą elastyczność. Osobiście pójdę z zewnętrznym. – Thihara

+0

IMHO, Builder powinien być wewnętrzną klasą, ponieważ ma być używany wyłącznie przez budowaną klasę. Z tego powodu nie ma prawdziwej korzyści z uczynienia z niego regularnej klasy. – hfontanez

Odpowiedz

7

To zależy.

Często łączę wzory Builder i Factory, więc warto mieć Buildera jako klasę zewnętrzną, ponieważ "zbudowany" obiekt może być jedną z wielu implementacji. Dodatkową korzyścią jest to, że implementacje mogą być pakietami prywatnymi, a nawet prywatnymi klasami wewnętrznymi Buildera.

Jeśli używasz Konstruktora, aby uczynić konstruktora klasy publicznej bardziej intencjonalnie odkrywczą lub mniej zagraconą niż to jest naprawdę osobiste preferencje. Można rozważyć zalety i wady posiadania dodatkowej klasy w interfejsie API, co może spowodować dezorientację użytkowników.

Zalecam jednak wybranie jednej z opcji i trzymanie się jej za pośrednictwem interfejsu API. Sprawia, że ​​ogólna architektura systemu jest łatwiejsza do zrozumienia, jeśli wszyscy budowniczowie są albo klasami wewnętrznymi, albo klasami zewnętrznymi; nie mieszaj ich.

Nie mieszać wewnętrznego i zewnętrznego Builders tak:

Foo foo = new Foo.Builder(...) 

Bar bar = new BarBuilder(...) 
1

The 2nd realizacja zapewniam cię że dostaniesz gotowego obiektu, a tym samym uczynić go bardziej niezawodne wdrożenie podczas gdy pierwsza jest niejawnym aż u zakończ konfigurowanie wszystkich pól.

na ogół nie chcesz, aby nieużywany obiekt był dostępny do użytku.