Рубрики
Без рубрики

Вступает в силу со вторника! Шаблон Строителя!

Погружение во вторую главу книги “Эффективная Java”. С тегами java, effective, design, architecture.

Пришло время для второго эпизода серии эффективных обзоров Java. Тема сегодняшнего дня – шаблон builder. Как и в нашей предыдущей главе, это еще одна модель творения.

Когда мы сталкиваемся с классом, который имеет значительное количество необязательных членов, каков наилучший способ создания этих объектов? Три метода, подробно описанные в Effective Java, – это телескопические конструкторы, шаблон JavaBean и шаблон builder. Давайте пройдемся по этим методам и посмотрим, где первые два терпят неудачу и как шаблон builder может блистать.

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

public Burger(String bunType)
public Burger(String bunType, List condiments)
public Burger(String bunType, List condiments, String meat)
public Burger(String bunType, List condiments, String meat, String temperature)

Глядя на эти конструкторы, вы можете увидеть, откуда он получил свое название. Телескопические конструкторы страдают от проблемы, о которой говорилось в моем предыдущем посте в этой серии. С несколькими параметрами одного и того же типа может быть легко запутаться в том, что представляет собой каждый параметр. (Хотя советую снять шляпу с моей любимой IDE Intellij для предоставления небольших подсказок с указанием имени параметра). В приведенном выше примере проблема может заключаться в том, чтобы задаться вопросом, является ли четвертым или пятым параметром мясо. Лучше не испортить это, иначе вы можете получить редкое мясо, приготовленное из говядины 😕 . Еще одна неловкость, которую можно увидеть выше, заключается в том, что, если я хочу только одну приправу? Ну, мне все равно нужно создать коллекцию с помощью чего-то вроде Collection.Синглтонлист("Кетчуп") (Эй, смотрите, фабричный метод !). Одной из идей было бы использовать varargs, но вы можете использовать только один аргумент varargs в функции, и он должен быть в конце, что в данном случае ограничивает его использование. Преимущество этого метода заключается в том, что вы можете создавать неизменяемые объекты, что действительно хорошо. Если у вас есть только один или два необязательных параметра, он может работать, но, как мы видим, у него есть некоторые проблемы.

Вариант 2: JavaBeans Метод JavaBeans довольно прост. Вы начинаете с создания конструктора без аргументов, а затем создаете установщики для каждой переменной-члена. Что-то вроде:

Burger burger = new Burger();
burger.setBread("Sour dough");
burger.setMeat("Beef");

Это довольно просто, но имеет свои проблемы. Одна из самых больших проблем для меня заключается в том, что ваш объект может находиться в противоречивом состоянии, когда вы его создаете. Здесь гораздо меньше контроля, что не очень хорошо. Это также кажется немного беспорядочным и многословным. Еще одним недостатком этого подхода является отсутствие возможности создавать неизменяемые объекты. Эффективная Java использует метод, в котором некоторые люди “замораживают” свой объект, но это кажется довольно подверженным ошибкам и беспорядочным. Если нет риска создания наполовину созданного объекта и неизменяемость нежелательна, этот метод может работать нормально но мы также должны рассмотреть, о чем эта глава.

Вариант 3: Шаблон построения Это подводит нас к тому, о чем идет речь в этой главе, – к шаблону builder. Эта модель дает нам лучшее из обоих миров. Мы получаем безопасность телескопического конструктора, но также получаем значительно улучшенную читаемость, такую как метод JavaBeans (я бы сказал, даже лучше, чем JavaBeans). В этом шаблоне мы создаем статический класс, внутренний для объекта, который мы хотим создать, традиционно называемый просто Builder . Методы объекта builder позволяют пользователю устанавливать значения объекта, а затем он возвращает объект builder обратно. Это позволяет использовать чистый fluent API. Как только все вызовы выполнены, пользователь вызывает метод build без параметров, в этот момент объект фактически создается. Метод build позволяет на мгновение убедиться, что объект находится в твердом состоянии. Лично, когда у меня есть требуемые атрибуты с шаблоном builder, я помещаю их в начальный вызов build .

Что это нам дает? Во-первых, возможность неизменности. Хотя это не всегда используется в своих интересах, это атрибут, который я лично считаю полезным иметь. Однако самое большое преимущество заключается в том, что благодаря fluent API у нас есть гораздо более удобная в обслуживании кодовая база. Это также значительно упрощает обработку дополнительных параметров. Если потребителю класса не нужно устанавливать атрибут, он просто не вызывает метод. Мы также видим, что мы могли бы вызывать методы для создания нескольких атрибутов со списками и не сталкиваться ни с какими проблемами с varargs, которые могут возникнуть при использовании вышеуказанных методов.

В других языках есть способы справиться с этим с помощью именованных параметров и необязательных параметров. Это одна из причин, по которой мне нравится Kotlin. Но без этой опции шаблон builder является сплошным. Должен быть более простой способ, и он действительно есть. Одним из инструментов, который, я думаю, должен быть у каждого разработчика Java, является Lombok. Этот процессор требует тонны шаблонного написания Java, и это здорово. У них также есть аннотация @Builder , которая сделает это очень чистым для нас. Есть некоторые люди которые думают, что Ломбок – плохая идея, но я определенно не один из них.

Итак, вот оно у вас есть. Шаблон строителя. Добились ли вы какого-нибудь успеха с этим шаблоном? Есть ли какие-то подводные камни, с которыми вы столкнулись? Дайте нам знать в комментариях ниже.

Оригинал: “https://dev.to/kylec32/effective-java-tuesday-the-builder-pattern-2k5f”