2013-07-30 2 views
34

Я очень новичок в разработке шаблонов, и у меня возникают проблемы с разницей между fluent interfaces и рисунком Builder.В чем разница между свободным интерфейсом и шаблоном Builder?

Я понимаю концепцию плавных интерфейсов. Но шаблон строителя немного запутан. Я не могу понять использование директора в шаблоне Builder.

Могу ли я использовать шаблон Builder и Fluent Interface вместе? Если да, то как мне это сделать с Директором и конкретным строителем?

Мой вопрос: не о преимуществах конструкции строителя. Но цель этого вопроса состоит в том, чтобы знать связь между шаблоном строителя и свободным интерфейсом.


Edit с порядковым UML диаграммы Builder из GoF:

Sequence diagram with director

+1

* Могу ли я использовать шаблон Builder и свободный интерфейс вместе? * Да, вы можете, есть отличный пример, размещенный [здесь] (http://stackoverflow.com/q/1673841/1065197) –

+0

Другие примеры находятся на странице http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern/. –

+3

Могу ли я узнать, как этот вопрос дублирует упомянутый выше вопрос? Поскольку речь идет о связи между свободным интерфейсом и шаблоном строителя. – Sagar

ответ

28

Идея позади Fluent интерфейса является то, что можно применить несколько свойств объекта, соединив их с точками, не имея каждый раз обрабатывать объект. Идея шаблона-застройщика заключается в том, что с нестандартными изменчивыми объектами часто легче работать, чем с неразделенными неизменяемыми, но гораздо проще рассуждать об общих неизменяемых объектах, чем разделяемые изменчивые. Таким образом, код может использовать простой в работе с изменяемым объектом для создания «модели» желаемого экземпляра, а затем использовать это, чтобы сделать объект, который легко переносится неизменным, который содержит одни и те же данные.

Две идеи могут хорошо работать вместе, но несколько ортогональны. Обратите внимание, что существует, по крайней мере, три способа, с помощью которых может работать свободный интерфейс: если каждый член экземпляра возвращает новый экземпляр с соответствующим измененным применением, каждый член мутирует экземпляр, на который он вызывается, и возвращает его, или каждый элемент возвращает экземпляр объекта с легким патчем, который содержит ссылку либо на измененную вещь, либо на предыдущий патч. В последнем стиле требуется, чтобы было применено какое-либо действие для применения всех патчей, но если изменяемый объект является большим и требуется много изменений, он может свести к минимуму требуемое количество копий.

+5

Не уверен, что согласен с вашим определением Свободный интерфейс. Это звучит только как метод Chaining. Я не буду понижать, но, пожалуйста, см. Мой ответ для объяснения того, чего достигли Fluent Interfaces. – Gordon

+0

-1 из-за неправильного/неполного описания свободного интерфейса, вряд ли релевантных неизменяемых/изменяемых объектов с рисунком строителя и неправильным требованием ортогональности. ИМО, конечно. – Creynders

+2

Не знаю, почему люди критиковали ваш ответ, вы на месте. Fluent - это шаблон для добавления метода каскадирования на языки, которые его не имеют, и объединение каскадов с цепочкой. Я также не вижу критики строителя, изменчивость/неизменность - один из основных вариантов использования. Хотя его можно использовать для большего количества вещей, например, для агрегирования параметров по методам и выполнения валидации и т. Д. –

110

Fluent Interfacesсемантические фасады. Вы помещаете их поверх существующего кода, чтобы уменьшить синтаксический шум и более четко выразить то, что делает код на вездесущем языке. Это шаблон, используемый при создании внутреннего домена. Речь идет о читаемости.

Директор/строитель организует строительство чего-то. То есть, если вы строите машину для выпечки пиццы, Директор будет следить за тем, чтобы шаги от заказа до пиццы выполнялись в правильном порядке с правильными данными с помощью правильного строителя. Речь идет о валидации и делегировании.

Вы можете, конечно, установить Fluent Interface поверх шаблона Director/Builder, чтобы он читал больше - хорошо и подчеркивал концепцию домена (по сравнению с техническим процессом построения и делегирования). Тогда это будет Expression Builder.

Я хотел бы подчеркнуть, что Fluent Interfaces - это не только Method Chaining. Это распространенное заблуждение. Метод Chaining - это один из подходов к реализации Fluent Interface, но это не одно и то же, поскольку в нем отсутствуют семантические качества, например.это не является Свободным Интерфейсом:

SomeObject.setFoo(1).setBar(2).setBaz(3); 

Вышеупомянутое не выражает ничего о SomeObject. Это не фасад над некоторой семантической моделью. Это всего лишь несколько методов. Примером Fluent Interface может быть построитель запросов SQL, например.

SQLBuilder.select('foo').from('bar').where('foo = ?', 42).prepare(); 

Под капотом этого API лежит код для создания инструкции SQL. Он может включать в себя несколько объектов, и показанные вызовы могут очень хорошо создать объект Select, вызвать его установщик, создать объект условия и применить его к объекту Select и, наконец, вернуть объект Statement. Но все, что скрыто от нас. Это также подчеркивает еще один аспект Свободных интерфейсов: они могут нарушать SOLID и Law of Demeter. Но так как это фасад поверх кода, который, надеюсь, следует этим принципам дизайна, это не имеет большого значения, потому что вы локализуете нарушения в Fluent Interface.

+1

Что было бы семантикой, если бы код выполнял 'var foo = SQLBuilder.select ('foo'). From ('bar'); var bar = foo.where (expr1,42); foo.where (exp2,42) .prepare(); bar.prepare() '? Что говорят интерфейсы Fluent о изменчивости или неизменности промежуточных результатов? Я понимаю, что на самом деле нет никаких жестких соглашений, но, возможно, я ошибаюсь? – supercat

+1

@supercat Мне не известны такие соглашения. Вы можете разделить различные вызовы, как показано в вашем примере. – Gordon

+0

Будет ли второй вызов 'foo.where' ожидать изменения объекта, который идентифицируется' bar'? – supercat

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