Как называется идиома, использующая цепочку методов для построения объекта?


21

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

Пример:

new Menu().withItem("Eggs").withItem("Hash Browns").withStyle("Diner");

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


3
Свободный интерфейс - это вопрос стиля. Если вы пишете API, предоставьте ему альтернативные формы.
— Одед

1
Для дальнейшего обсуждения взгляните на этот вопрос: programmers.stackexchange.com/questions/69519/…
— Эрик Кинг,

@Oded Можно использовать такой API без цепочки, просто сделав каждый вызов отдельным оператором, или у вас была другая идея для альтернативы?
— Гаррет Холл

@GarrettHall - Конечно, это возможно, но тогда вы в конечном итоге называете вещи menu.withStyle("")без контекста. Вам нужно два API в таком случае.
— Одед

2
@GarrettHall Точкой «свободного интерфейса» является цепочка методов, которая должна читаться как предложение. В этом смысле длинная цепочка методов не считается плохой. Но, и здесь я согласен с Одедом, было бы лучше также обеспечить ту же функциональность в более обычном синтаксисе. Таким образом, разработчик может выбрать, какой метод использовать.
— Эрик Кинг,

Ответы:


37

Свободный интерфейс

Я всегда слышал о том, чтобы этот метод назывался « беглым интерфейсом », как его придумали Эрик Эванс (из известной доменно-управляемой разработки ) и Мартин Фаулер (из известной гибкой манифесты ).

Основными недостатками являются удобочитаемость (которую некоторые люди любят, а некоторые ненавидят), а также тот факт, что в некоторых случаях отладку может быть сложнее, потому что вся цепочка действий может рассматриваться как одно утверждение при ее прохождении.

Я, конечно, не считаю это анти-паттерном, хотя сам использовал эту технику всего несколько раз.


4
Обратите внимание, что сторонники довольно настаивают на том, что свободный интерфейс включает в себя гораздо больше, чем просто цепочку методов, хотя часто неясно, что еще подразумевается под этим термином.
— Килиан Фот

Принято ли считать всю цепочку одним утверждением? Это звучит как плохо продуманная проблема отладчика для меня.
— черничные

Я не сталкивался с отладчиком, который рассматривает цепочки как одно утверждение, но он все еще может быть болезненным, если вас интересует только один из методов в конце цепочки, в одной конкретной цепочке.
— vaughandroid

1
Я работаю в C #, и отладчик .NET позволяет мне шагать в отдельные методы. На других языках я не так уверен.
— Эрик Кинг,

1
@KilianFoth Как отмечалось в комментариях к вопросу, цепочечные методы в свободном интерфейсе должны читаться почти как предложение. Иногда это означает, что отдельные методы должны иметь имена, отличные от тех, которые считаются хорошей практикой
— Izkata

5

Подобный метод цепочки обычно называется плавным интерфейсом, когда в цепочке есть какой-то поток или обнаруживаемость. В качестве альтернативы, вы можете думать о API, подобном jQuery, который в значительной степени опирается на цепочку методов, как о «не беглом», потому что акцент не делается на обнаружении - он больше для удобства.

Для вашего примера (с использованием withx, withy) вы можете рассматривать это как вариант шаблона Builder, потому что у вас есть специализированный класс, который, учитывая некоторое состояние (вызовы методов), знает, как вернуть правильно сконфигурированный объект.

Это не анти-паттерн, если используется правильно.


Что такое открытость? Возможность найти нужные вам методы через автозаполнение API?
— Иосия Йодер

Я не знаком с JQuery. Как их метод цепочки только для удобства, а не для обнаружения? Потому что есть так много способов связать, что это подавляет даже с автозаполнением?
— Джозия Йодер

3

считается ли это анти-паттерном,

определенно не анти-шаблон. JQuery, вероятно, наиболее хорошо используемая реализация этого.

потому что, хотя он может читать более бегло, это может привести к длинным цепочкам методов

Да, может, но какова альтернатива? Вы можете закончить почти простым английским предложением, с api, направляющим вас к тому, что доступно и уместно.


... и вы получаете то, что вы хотите в 1 строке вместо 8 - 10. Что хорошо, если вы пишете только один вкладыш в терминале. Проще вызвать 1 команду, чем 10. Поскольку она свободно и методы имеют описательные имена, ее также легче читать. К сожалению, многое из этого в Python2 больше не может быть сделано в Python3 / Python4.
— mckenzm

-3

Это называется «крушение поезда».

(Это анти-шаблон и против чистого кода)

Паттерн «крушение поезда» нарушает закон Деметры .


3
Это не то же самое, что метод цепочки в статье, на которую вы ссылаетесь, где пример a.getB().getC().doSomething(). Этот пример плох, потому что «Ваш метод может вызывать методы непосредственно в своих собственных полях (но не в полях полей)». Здесь есть только 1 объект, который создается, и «вы можете играть с игрушками, которые вы сделали сами».
— Nic
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.