Android builder что это такое

Java. Шаблон Builder

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

Если ваш класс содержит большое количество конструкторов и статических методов, то возникает проблема — трудно запомнить порядок и назначение необязательных параметров при вызове класса. В таких случаях рекомендуется использовать шаблон Builder.

Создадим для примера «плохой» класс с двумя обязательными и с четырьмя необязательными параметрами.

Создание экземпляра класса с использованием конструктора со всем набором параметров.

Глядя на набор чисел, трудно понять код. Правда, на данный момент студия выводит подсказку прямо в редакторе, что упростило задачу. Но этот же код, опубликованный на сайте, не будет содержать подобных подсказок, поэтому проблема остаётся. Кроме того, увеличение числа параметров только усложняет сопровождение кода.

Можно прибегнуть к другому варианту — вызвать конструктор без параметров, чтобы создать объект, а затем вызывать сеттеры для установки обязательных и некоторых необязательных параметров.

Количество кода в классе увеличивается, но код стал более читаемым при создании экземпляра класса.

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

Поэтому был придуман третий вариант, который назвали шаблоном Builder. Вместо непосредственного создания объекта класса вызывается конструктор (или статический метод) со всеми необходимыми параметрами, чтобы получить объект Builder. Затем вызываются сеттеры для установки всех необходимых параметров. В завершение, вызывается метод build() для генерации объекта, который будет являться неизменным. Реализуется такой подход через статический внутренний класс.

Создадим уже «хороший» класс с применением Builder.

Класс GoodClass является неизменным и все значения параметров по умолчанию находятся в одном месте. Сеттеры возвращают класс-строитель, поэтому вызовы можно объявлять в цепочку.

При таком подходе код проще писать и легко читать. У шаблона есть и другие преимущества, например, можно задействовать несколько параметров varags.

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

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

Источник

Эволюция паттерна Builder в Android.

Продолжаем тему паттернов проектирования. На этот раз рассмотрим порождающий шаблон проектирования Builder. Мы рассмотрим какую проблему решает Builder в Java, какие у него есть “братья” и как этот паттерн эволюционировал в Android-разработке при использовании Kotlin.

Проблема

В первую очередь хочется поговорить, о проблеме, которую призван решить Builder. Чаще всего Строитель (он же Builder) используется для пошаговой инициализации множества полей и вложенных объектов. Код инициализации таких объектов чаще всего спрятан внутри монструозного конструктора с десятком параметров. Либо ещё хуже — распылён по всему клиентскому коду. Перед тем как перейти непосредственно к самому паттерну — давайте рассмотрим его “младших братьев” которые могут теоретически помочь при решении описанной выше проблемы.

Так себе решение #1. Телескопический конструктор

Традиционно, программисты использовали Telescoping Constructor паттерн. Суть этого паттерна состоит в том, что Вы предоставляете несколько конструкторов: конструктор с обязательными параметрами, конструктор с одним дополнительным параметром, конструктор с двумя дополнительными параметрами, и так далее. Продемонстрируем как это будет выглядеть на практике. Для краткости будем использовать только 4 дополнительных параметра.

Таким образом, когда Вы хотите создать объект данного класса, Вы используете конструктор с необходимым списком параметров:

Обычно для вызова конструктора потребуется передавать множество параметров, которые Вы не хотите устанавливать, но Вы в любом случае вынуждены передать для них значение. В нашем случае, мы установили значение 0 для поля fat . Поскольку мы имеем только шесть параметров, может показаться, что это не так уж и плохо. Но это начинает доставлять огромные проблемы когда число параметров увеличивается.

Минусы такого подхода:

Когда имеется много параметров становится сложно создавать объект, а еще труднее этот код читать. Остается только гадать, что означают все эти значения.

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

Так себе решение #2. JavaBeans паттерн

Видели множество set()-методов для создания сложного объекта? Думаю все видели размазанные по всему коду сетеры — которые оставляют неконсистентное состояние при инициализации объекта:

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

“The JavaBeans pattern has serious disadvantages.” — Joshua Bloch, Effective Java

Минусы такого подхода:

Поскольку строительство разделено между несколькими вызовами, JavaBean может находиться в неустойчивом состоянии частично пройдя через конструирование. Попытка использования объекта, если он находится в неустойчивом состоянии может привести к ошибкам, которые далеки от кода, содержащего ошибку, следовательно, трудными для отладки. Также JavaBeans паттерн исключает возможность сделать класс неизменным(immutable), что требует дополнительных усилий со стороны программиста для обеспечения безопасности в многопоточной среде.

Читайте также:  Usb to ethernet adapter android

Хорошее решение #3. Паттерн Builder

Третья альтернатива, сочетающая в себе безопасность паттерна Telescoping Constructor с читаемостью паттерна JavaBeans — это паттерн Builder.

Вместо непосредственного создания желаемого объекта, клиент вызывает конструктор (или статическую фабрику) со всеми необходимыми параметрами и получает объект строителя. Затем клиент вызывает сеттер-подобные методы у объекта строителя для установки каждого дополнительного параметра. Наконец, клиент вызывает метод build() для генерации объекта, который будет являться неизменным(immutable). Строитель является статическим внутренним классом в классе, который он строит. Вот как это выглядит на практике:

Ну и теперь конструирование объекта сводится к вызову необходимых методов:

Преимущества паттерна:

  • Позволяет создавать продукты пошагово.
  • Позволяет использовать один и тот же код для создания различных продуктов.
  • Изолирует сложный код сборки продукта от его основной бизнес-логики.

Хорошее решение #4. Паттерн Builder в Kotlin

На дворе 2021 год, и программирование под Android развивается семимильными шагами. И если раньше подход №3 считался стандартом, то встаёт вопрос: “А надо ли реализовывать паттерн Builder в Kotlin?” Перед тем, как ответить на данный вопрос, давайте вспомним цели, которые мы хотели достичь, используя Builder:

  • Конструирование сложного объекта с большим количеством аргументов (возможно с одинаковым типом)
  • Возможность создания разных объектов с разным количеством аргументов (часть из аргументов может быть опциональными)
  • Неизменяемость построенного объекта

Теперь, давайте пройдёмся по каждому пункту и посмотрим, что нам может предложить Kotlin.

В Koltin есть 2 крутые фичи: именованныt аргументы и дефолтные аргументы. Таким образом, мы убиваем 2-ух зайцев сразу. Во-первых, используя именнованные аргументы, мы теперь можем передавать в конструктор 100500 различных аргументов и при этом они могут быть одного типа — перепутать их будет достаточно сложно. А использование дефолтных значений для аргументов — избавляет нас постоянно описывать ненужные значения — как это было в подходе с телескопическим конструктором. Ну а неизменяемость построенного объекта очень легко достичь, объявив поля класса через val.

Сконструировать такой объект теперь мы можем так:

Таким образом, Kotlin очень сильно упростил нам задачу. И теперь паттерн Builder является частью языка, и нет необходимости конвертировать его Java-реализацию. Достаточно придерживаться описанных выше правил.

Надеюсь, в этой статье вы уловили суть паттерна Builder, а также теперь знаете врагов в лице парочки антипаттернов и сможете писать более читабельный и эффективный код на Kotlin. Ну а если вы хотите прокачаться в Android-разработке, то приглашаю вас на 3-ий поток интенсива по Android-разработке на Kotlin. До 25 января скидка 15%. Узнать подробности можно по ссылке.

Подписывайся на канал чтобы не пропустить анонс и хлопай внизу если статья был полезная.

Понравилась статья? Не забудь подписаться и поставить лайк, а ещё

Источник

Русские Блоги

Режим Builder и его использование в Android

Режим Builder и его использование в Android

Этот блог в основном знакомит с концепцией режима построения, демонстрации и приложения для Android и т. Д .:

  • концепция
  • Экспериментальная демонстрация
  • Приложение для Android
  • подводить итоги

Концепция строителя

Как разработчик, будь вы новичок на рабочем месте или эксперт в этой области, хороший дизайн особенно важен, когда вы сталкиваетесь со сложными и изменчивыми организационными структурами и частыми требованиями к модификации. Если класс многократно модифицируется, мы используем традиционный способ, мы напишем множество параметров конструкции, если модифицируются, все задействованные должны быть изменены, на этот раз будет очень хлопотно, не будет способствовать обслуживанию и расширению. В настоящее время нам нужен гибкий и изменяемый режим, чтобы справляться с меняющимися потребностями, и режим конструктора — один из них. Builder соответствует нашим потребностям, основная структура и контекст не изменились, но его детали будут изменены (увеличены или уменьшены), что позволит разработчикам быстро поддерживать режим.

Тогда напишите демо.

Идеи (модельное тестирование):

Тип записи: цель — передать данные и получить их отдельно.

Традиционное письмо:
Bean:

Передача параметров выглядит немного запутанной, мы не знаем значения параметров, и это недостаточно ясно. Передаем передачу параметров Строителю в управление.

Результат:

Таким образом, мы можем узнать значение каждого параметра.

Может использоваться для написания диалога в Android:

Источник

Kotlin и “строитель” (он же Builder)

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

Давайте сразу окунемся в пучину кода. Рассмотрим вот такой пример.

В качестве сеттера для свойства nickname мы написали функцию, которая применяет параметр к нашему свойству. Все довольно просто, но после Java не так очевидно.

Однако (!) скажете вы, часто же строитель используется немного по другой схеме. Скажем, строитель может быть для кастомного аккаунта, а может быть для создания диалогового окна. Ты же помнишь, как это описывается по старинке, ну типа AlertDialog.Builder() и так далее?

Читайте также:  Если греется процессор андроида

Если так скажете, отвечу — прям с языка сорвали продолжение истории. Смотрим пример номер два — аккаунт и билдер (мне как-то это привычнее, чем строитель, если честно)

Что мы тут имеем. Объект Account, который создается с помощью билдера и никак иначе (дефолтный конструктор использует параметр только нашего типа). В билдере все как обычно — есть поля, есть сеттеры в которых— о, чудо! — мы избавились от одной лишней строки (я имею в виду return this, как раньше).

Создание нашего объекта выглядет прелестно (я сюда же добавил пару распечаток, ну так, для наглядности вызова)

Источник

Русские Блоги

Режим Builder (фокус на Java, Android)

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

Введение

Режим построителя (builder) — это режим создания, который создает сложный объект, отделяет процесс построения сложного объекта от его компонентов и отделяет процесс построения от представления компонентов.
Для пользователей им нужно заботиться только о модели компонента, который они хотят (некоторые пользователи могут даже не заботиться о модели компонента).

Например, сборка настольного компьютера. Сборка компьютера — это относительно сложный и длительный процесс, включая сборку материнской платы, процессора, жесткого диска, монитора и установку систем. Пользователи не заботятся о том, как собран компьютер. Пользователи заботятся только о комплектации компьютера. Некоторые пользователи также заботятся о модели каждого компонента.

Принцип режима

Диаграмма классов UML

символ

  • Строитель (Abstract Builder):Он определяет абстрактный интерфейс для каждого компонента, который создает объект Product, В этом интерфейсе обычно объявляются два типа методов: один тип метода — buildPartX (), который используется для создания различных частей сложных объектов, другой тип метода — getResult (), который используется для возврата сложных объектов. Builder может быть либо абстрактным классом, либо интерфейсом.
  • ConcreteBuilder (бетоностроитель):Он реализует интерфейс Builder и реализует специфическую структуру и методы сборки каждого компонентаОпределите и уточните сложные объекты, которые он создает, или предоставьте метод для возврата созданных сложных объектов продукта.
  • Продукт (роль продукта):Это сложный строящийся объект, содержащий несколько компонентов, Конкретный строитель создает внутреннее представление продукта и определяет процесс его сборки.
  • Директор: директора также называют директором,Отвечает за организацию последовательности строительства сложных объектов.Существует связь между командиром и абстрактным строителем, Вы можете вызвать методы конструирования и сборки компонента объекта-конструктора в его методе construct (), чтобы завершить построение сложных объектов.Клиенту обычно нужно только взаимодействовать с командиромОпределите тип конкретного строителя на клиенте и создайте экземпляр объекта конкретного строителя, а затем передайте объект в класс commander с помощью метода constructor или Setter класса commander.

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

Пример кода

Абстрактный класс Builder Builder: (либо абстрактный класс, либо интерфейс)

Специфический класс застройщика LenovoBuilder:

Конкретный класс застройщика HuaweiBuilder:

Клиентский класс Клиент:

Клиент несет ответственность за созданиеДиректор и бетонщик объектов, Затем клиент передает конкретный объект компоновщика директору, а директор оперирует конкретным компоновщиком, чтобы начать создавать продукт. Когда продукт завершен, строитель возвращает его клиенту.

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

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

Дальнейшее обсуждение директора

Класс Director директор играет очень важную роль в режиме конструктора: простой класс Director используется для указания конкретным сборщикам о том, как создавать продукты, он вызывает метод buildPartX () строителя в определенном порядке, контролирует последовательность вызовов и отправляет клиентов. Конец возвращает полный объект продукта. Ниже мы обсудим несколько продвинутых методов применения директора:

Пропустить директор

В некоторых случаях, чтобы упростить структуру системы, вы можете объединить Director и абстрактный Builder Builder и предоставить метод construct () для постепенного создания сложных объектов продукта в Builder. Поскольку класс Builder обычно является абстрактным классом, метод construct () можно определить как статический метод.

подводить итоги

преимущество

  • В режиме конструктора клиенту не нужно знать подробности внутреннего состава продукта, и он сам отделяет продукт от процесса создания продукта, так что один и тот же процесс создания может создавать различные объекты продукта.
  • Каждый бетоностроитель относительно независим и не имеет никакого отношения к другим бетоностроителям, поэтому легко заменить бетоностроителей или добавить новых бетоностроителей, и пользователи могут получить различные объекты продукта, используя разных бетоностроителей. Поскольку класс commander запрограммирован для абстрактного компоновщика, добавление новых конструкторов бетона не требует изменения кода исходной библиотеки классов, система легко расширяется и соответствует «принципу открытия и закрытия».
  • Процесс создания продукта можно контролировать более точно. Разбиение этапов создания сложных продуктов на разные методы делает процесс создания более понятным и более удобным для использования программ для управления процессом создания.
Читайте также:  Optimizer pro для android

Недостаток

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

Применимая сцена

  • Объекты продукта, которые необходимо сгенерировать, имеют сложную внутреннюю структуру, и эти объекты продукта обычно содержат несколько атрибутов-членов
  • Атрибуты объектов продукта, которые должны быть сгенерированы, зависят друг от друга, и необходимо указать порядок создания
  • Процесс создания объекта не зависит от класса, который создал объект. В режиме построителя вводится класс лидера, а процесс создания инкапсулируется в классе лидера, а не в классе построителя и клиентском классе.
  • Изолируйте создание и использование сложных объектов и включите один и тот же процесс создания для создания различных продуктов.
  • Изолируйте создание и использование сложных объектов и включите один и тот же процесс создания для создания различных продуктов.

Использование режима Builder в Android

Наиболее распространенное приложение режима конструктора в Android — AlertDialog:

AlertDialog является расширением режима компоновщика. Исходный код системы объясняться не будет. Ниже приведен пример использования режима компоновщика в ситуации.

Введение в сценарий

Предположим, у вас есть класс с множеством свойств, например, следующий класс Computer:

Теперь представьте, что в вашем классе есть некоторые атрибуты, которые являются обязательными, а некоторые необязательными (вы, ребята, больше беспокоитесь о процессоре и видеокарте, поэтому эти два элемента должны быть установлены нами, а другие элементы являются необязательными). Как бы вы создали экземпляр этого класса? Все атрибуты объявлены как окончательные типы, поэтому вы должны установить их в конструкторе, но вы также хотите, чтобы клиент этого класса имел возможность игнорировать необязательные атрибуты.

Одна из первых альтернатив, которая приходит на ум, состоит в том, что существует метод конструирования, который принимает только обязательные атрибуты в качестве параметров, один — получать все обязательные атрибуты и первый необязательный атрибут, а другой — получать два необязательных атрибута и так далее. Как это будет выглядеть?
выглядит так:

Преимущество этого способа построения объектов в том, что он может работать нормально. Однако проблема с этим подходом также очевидна. Это не большая проблема, когда у вас есть только несколько атрибутов, но по мере увеличения количества атрибутов (например, мы хотим выбрать большую емкость жесткого диска), код становится все труднее читать и поддерживать. Что еще более важно, код становится все труднее и труднее использовать для клиента.

Какой конструктор я должен вызывать в клиенте? Какой из них имеет два параметра? Какой из трех параметров? Каковы значения по умолчанию параметров, которые я не показывал? Что если я только хочу установить значение для свойства board, но не хочу устанавливать screenSize и ram? В этом случае мне нужно вызвать конструктор, который может получить все параметры и передать значения по умолчанию необязательным параметрам, которые меня не интересуют. Кроме того, некоторые параметры можно легко спутать с одним и тем же типом. Первый параметр типа String соответствует процессору или видеокарте?

Итак, какие еще варианты мы должны иметь дело с этим сценарием? Мы всегда можем следовать соглашению JavaBeans, есть конструктор по умолчанию без аргументов, и у каждого свойства есть методы getter и setter. как это:

Этот метод легко читается и поддерживается. В клиенте я могу просто создать пустой объект, а затем установить только те свойства, которые меня интересуют. Но состояние экземпляра этого класса не является фиксированным. Если вы хотите создать объект User, для пяти свойств объекта должны быть назначены значения, тогда объект не будет иметь полного состояния, пока не будут вызваны все методы setXX.

К счастью, у нас есть третий вариант для этого сценария, режим конструктора:

Некоторые ключевые моменты стоит отметить:

  • Конструктор User является закрытым, что означает, что класс не может быть создан непосредственно в клиентском коде
  • Теперь класс снова неизменен. Все свойства имеют конечный тип и им присваиваются значения в конструкторе. Кроме того, мы предоставляем только методы получения для них
  • Класс builder использует стиль интерфейса потоковой передачи, чтобы облегчить чтение клиентского кода (скоро мы увидим его пример)
  • Метод конструирования класса построителя принимает только обязательные атрибуты. Чтобы эти атрибуты были назначены в методе конструирования, только эти атрибуты определяются как конечные типы.

Теперь создайте объект Computer в клиенте:

Это похоже на процесс создания AlertDialog? Да, AlertDialog также использует этот режим.

Этот режим построения сравнивается с режимом построения, который мы ввели выше:

  • Нет абстрактного класса строителя, только класс конкретного строителя
  • Класс бетоностроителя — это внутренний класс как класс продукта
  • Нет командирского класса

Конечно, вы также можете изменить текущий режим компоновщика так же, как режим компоновщика, который мы ввели в начале:

Абстрактный конструктор класса Builder:

Бетоностроитель класса ComputerBuilder:

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

Пока я закончил говорить о режиме строителя, спасибо, что поделились!

Источник

Оцените статью