2016-07-23 2 views
1

я видел два популярных способов реализации шаблона строитель:Реализация шаблона строитель

// 1. The build() approach 
Product p = builder.part1() 
        .part2() 
        .build(); 

// 2.The constructor approach 
builder.part1() 
     .part2(); 
Product p = new Product(builder); 

Какой из них предпочтительнее?

ответ

6

первый один путь ...

, если вы используете 2-й выбор, то сделать это:

Product p = new Product(builder); 

добавит зависимости от класса продукта ..

это означает, что класс продукта требует, по крайней мере, конструктора с параметром строитель

+0

Я также понял, что подход 2. не будет работать, если 'Product' является интерфейсом. Вам нужно будет ввести метод 'construct()', то есть вы могли бы просто пойти по пути 'Builder.build(). –

1

Я обычно использую комбинацию обоих этих примеров ле.

Я бы определил класс строителя внутри класса Product и дал классу продукта частный конструктор, который принимает ProductBuilder.

+0

Не будет ли доступ к внутренним функциям «Продукта» достаточно, если вы сделаете построитель внутренним классом? –

+1

Я полагаю, что вы могли бы, но мне нравится сохранять состояние компоновщика отдельно от объектов, которые вы создаете с ним, поэтому, как только вы создадите объект, строитель больше не сможет его модифицировать. – simonv

2

Вопрос немного расплывчатый, однако, если у вас есть класс статического строителя, эффективная java-книга joshua bloch предлагает структуру, более похожую на первую с методом построения. Это более чистый и безопасный способ.

Product p= new Product.ProductBuilder("hw", "sw") 
    .version(30) 
    .mac("1234567") 
    .address("Fake address 1234") 
    .build(); 
+0

Я просто поработал над реализацией Джоша Блоха, и мне это действительно нравится! –

1

Это два разных подхода. Сделки разные. Вы должны использовать и адаптировать шаблон в соответствии с вашими потребностями и ваш контекст, а не в соответствии с жестким правилом ...

Используя конструктор, как это:

Product p = new Product(builder); 

позволяет создать построитель и повторно использовать его. Если вам нужно повторно использовать конструктор или создать конструктор в другом классе, это хорошая реализация. Вы открываете свой API, потому что вам это нужно.
Недостатки решения - это не прямой способ создания вашего объекта.
Что касается качества дизайна и зависимости, я думаю, что это ложная проблема. Да с открытым конструктором для Продукта вы создаете общественную зависимость между Продуктом и Строителем, и вы раскрываете конструктор продукта. Но если в конструкторе Product вы отправите экземпляру компоновщика задачу для создания Продукта, будет ли соединение связывать код менее гибким? Никогда.
Кроме того, реальная муфта находится в конструкции продукта, так как строитель использует свойства зеркала для создания объекта Product. Таким образом, реальное и сильное сцепление останется тем, что происходит: эти два класса должны работать вместе и должны выглядеть.

Использование строитель, как это:

Product p = builder.part1() 
       .part2() 
       .build(); 

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

Итак, в фактах, оба решения находятся рядом. Я бы использовал решение с конструктором, если я должен повторно использовать построитель, или мне нужно создать конструктор в другом классе, и я бы использовал решение без конструктора, если это не было необходимо.

Смежные вопросы