29 июн. 2015 г.

Классы. Практика: паттерн проектирования Builder.

Паттерн проектирования – это некий шаблон который можно использовать при решении однотипных задач. По словам Кристофера Александра, «любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип ее решения, причем таким образом, что это решение можно потом использовать миллион раз, ничего не изобретая заново». Именно поэтому уже существует великое множество паттернов проектирования в ООП. И каждому программисту хорошо бы знать хотя бы некоторые из них. И вообще иметь понятие о паттернах.

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

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

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

B0001

Допустим у нас есть класс Contact представленный слева. В нем несть несколько однотипных строковых полей.

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

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

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

Для этого класса создание объекта будет выглядеть так:

Contact c = new Contact("Петров", "Вася", "p@v.ru", "1234", "Уфа");

Здесь я намеренно допустил ошибку, перепутав имя и фамилию местами.

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

Потом вы можете сравнить эту строчку с тем как мы будем создавать новый контакт при использовании паттерна Builder.

Полный код трех классов, демонстрирующих паттерн Builder, можно посмотреть тут. А для общего понимания в статье я приведу отрывки из этого кода.

B0002

B0003

B0004

И вывод данной программы:

B0005

Сразу обратите внимание на то, что в классе Contact все поля final, а в классе ContactBuilder все поля не имеют этого модификатора. Это является общераспространённой практикой при создании паттерна Builder, хотя это можно и изменить исходя из нужд вашего приложения.

Кроме того можете увидеть по классу Classes01, что в случае применения паттерна Bulder, можно даже пропустить задание значений для некоторых полей и тогда они получат значения по умолчанию. Или же поменять порядок полей при задании их значений.

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

Это мы рассмотрели самый простой вариант данного паттерна. Как видно из приведенного выше примера, используя данную реализацию паттерна, можно создать такой объект Contact все поля которого могут получить значения по умолчанию, то есть null. Но можно создать такую реализацию данного паттерна, что некоторые поля будут обязательны к заполнению, а некоторые опциональные могут получать значения по умолчанию, которые мы для них определим.

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

Сделаем поле surname обязательным, а остальные как и было опциональными, но присвоим им наши значения по умолчанию. Для  этого нам надо изменить класс ContactBuilder и, соответственно, его применение в  Classes014.

B0006

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

А использование ContactBuilder выглядит теперь вот так:

B0009

И вывод у программы следующий:

B0008

На этом с паттерном Builder мы не прощаемся. Мы еще встретимся с ним на практике после изучения абстрактных и внутренних классов.

Комментариев нет:

Отправить комментарий