2013-10-02 3 views
5

В чем преимущества использования шаблона построителя внутри класса вне класса?Builder Pattern внутри vs вне класса?

Внутри класса:

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") 

Вне класса:

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

Это мнение основано ... Но я думаю, что его внутри понижает беспорядок. Вы можете иметь MyClass.Builder, MyClass2.Builder и т. Д. - и не иметь целую кучу классов MyClassBuilder, MyClass2Builder и т. Д. – ppeterka

+0

Для простых вещей это не имеет особого значения, однако вы можете использовать типы возвращаемых значений setter для некоторых других (в сложных сеттерах), и в этом случае внешняя была бы более гибкой. Лично я пойду с внешним. – Thihara

+0

ИМХО, Строитель должен быть внутренним классом, потому что он предназначен исключительно для построенного класса. Из-за этого нет никакой реальной выгоды в том, чтобы сделать его обычным классом. – hfontanez

ответ

7

Это зависит от многого.

Я часто совмещаю модели Builder и Factory, поэтому имеет смысл иметь Builder как внешний класс, поскольку «встроенный» объект может быть одной из многих реализаций. Это дает дополнительное преимущество, позволяя реализациям быть приватными частными частями или даже частными внутренними классами Builder.

Если вы используете Builder, чтобы сделать конструктор открытого класса более умышленным, раскрывающим или менее загроможденным, чем это действительно личное предпочтение. Можно было взвесить плюсы и минусы наличия дополнительного класса в API, который может сделать его запутанным для пользователей.

Однако я рекомендую выбрать один из вариантов и придерживаться его в API. Это упрощает понимание общей архитектуры системы, если все строители являются либо внутренними, либо внешними классами; не смешивайте их.

Не смешивать внутреннее и внешние Строителей так:

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

Bar bar = new BarBuilder(...) 
1

2-я реализация уверяет вас, что вы получите готовый объект и тем самым сделать его более надежная реализация в то время как первый является неустановленным недом у завершите настройку всех полей.

В общем, вы не хотите, чтобы объект не был доступен для использования.