Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- https://jlordiales.me/2012/12/13/the-builder-pattern-in-practice/
- http://www.journaldev.com/1425/builder-design-pattern-in-java
- По этим линкам - по моему мнению - неплохо и несложно разъяснено про паттерн Builder
- по второй линке - вообще пошагово
- еще и это пригодится
- вот неплохие линки - про использование this
- https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
- http://stackoverflow.com/questions/2411270/when-should-i-use-this-in-a-class
- буду иносказательной и я)
- У нас будет класс = то, что мы строим
- и его внутренний класс (а если точнее - nested static class) = builder = как мы это строим
- мы хотим строить пошагово -
- сначала описать - что мы строим = рассказать в сколь угодно много шагов(любая их комбинация)
- а потом - по собранной в шагах информации - построим наш объект
- и поскольку - чтобы строить объект - мы применяем класс-строитель
- то - конструктор для нашего объекта - не нужно делать public
- Допустим, мы делаем некий напиток
- мы можем добавлять
- воду
- сахар
- красители
- алкоголь
- фрукты
- паковать это в некую тару
- ну и вот это все в комплексе - и есть создание напитка
- вот и создаем класс Drink = т к делаем мы напиток
- и у него внутри - реализуем и класс-строитель = Barman
- public class Drink {
- private int water;
- private int sugar;
- private List<Colour> colours;
- private List<Alcohol> alcohols;
- private List<Fruit> fruits;
- private Bottle bottle;
- /*
- все свойства конечного объекта=напитка - описываем как private поля объекта
- */
- private Drink(Barman barman) {
- water = barman.water;
- sugar = barman.sugar ;
- colours = barman.colours;
- alcohols = barman.alcohols;
- fruits = barman.fruits;
- bottle = barman.bottle;
- ...
- }
- /*
- конструктор этого класса = тоже private (выше писала - почему так)
- и в качестве параметра он получает как раз объекта-строителя
- в конструкторе - переносим данные из строителя - в поля нашего объекта
- и далее - (см "..." в коде) при необходимости как-то работаем с данными
- как-то = как нам нужно
- */
- public static class Barman {
- private int water;
- private int sugar;
- private List<Colour> colours;
- private List<Alcohol> alcohols;
- private List<Fruit> fruits;
- private Bottle bottle;
- /*
- у класса-строителя - такой же набор полей,
- и они тоже private
- все методы этого класса, кроме одного(build()) -
- как раз и будут собирать эти свойства
- */
- public Barman(Bottle bottle) {
- this.bottle = bottle;
- colours = new ArrayList<Colours> ();
- ...
- }
- /*
- конструктор класса-строителя - объявляем как public
- здесь мы инициализируем все поля этого класса
- если это необходимо - можно реализовать конструктор с параметрами
- цель - передать то, что будет обязательным для заполнения
- */
- public Barman addWater(int water) {
- this.water += water;
- return this;
- }
- /*
- каждый из методов, заполняющих какое-либо из свойств - это public метод
- и возвращает такой метод самого объекта-строителя
- */
- public Barman addFruits(Fruit... fruits) {
- for (Fruit fruit:fruits) {
- this.fruits.add(fruit);
- }
- return this
- }
- /*
- заметь - такие методы не заново заполняют соответствующие поля - а лишь дополняют то,
- что мы изначально задали в конструкторе
- цель - иметь возможность многократно и в любой последовательности вызывать методы строителя
- для каждого из свойств - реализуем такого плана метод
- */
- public Drink build() {
- return new Drink(this);
- }
- /*
- а этот метод класса-строителя - возвращает новый объект - который мы как раз строим
- и передаем в конструктор - this = наш объект-строитель
- собственно - фактически это и будет создание нашего объекта Drink
- (вспомни - что мы делали в конструкторе класса Drink)
- */
- }
- }
- /*
- если минимально - то это все)
- теперь мы можем создать нашего строителя
- new Drink.Barman(bottle)
- а чтоб эту часть кода сделать нагляднее - можем в классе Drink
- реализовать static метод, возвращающий новый объект типа строитель
- например
- */
- public class Drink {
- ....
- public static Barman composeDrink(Bottle bottle) {
- return new Barman(bottle);
- }
- public static class Barman {
- ...
- }
- }
- /*
- и далее в коде
- применив import static для composeDrink -
- писать
- */
- composeDrink(bottle)
- а не
- new Drink.Barman(bottle)
- /*
- ну и далее - начинается самое интересное
- composeDrink(bottle) - возвращает объект-строитель
- у которого много методов, "доливающих" наш напиток = уточняющих наш рецепт
- а т к каждый из этих методов - возвращает тот же объект
- мы можем строить любые цепочки вызовов
- и заканчивать такую цепочку - вызовом build
- только в вызове build - и будет построен объект
- согласно тому - что мы уточнили ранее
- */
- composeDrink(bottle).addWater(...).addAlcohol(...).addFruits(...).addColor(...).addFruits(...).build(); - некий коктейль )
- ...
- composeDrink(bottle).addWater(...).build(); - просто бутылка с водой
- ...
- composeDrink(bottle).build(); - вообще пустая бутылка )
- теперь вспоминаем - о чем это мы
- мы собирались делать вот что
- given().build() - ни одной таски
- given().activeTasks("a","b","c").completedTasks("d", "e").atAllFilter().build() - разные таски на таком-то фильтре
- given()......build() - можно разные делать - в зависимости от потребностей
- Видишь сходство? )
- Если это все сложно - то пока просто сохрани себе это
- Во второй части курса прокачаем скиллы, которые и это позволят осилить
- как и писала ранее - экономически не оправдано в задаче такого уровня применять этот паттерн
- тут можно прекрасно реализовать несколько гивен-методов
- и этого будет - с головой достаточно)
- постаралась иносказательно ответить на все твои вопросы из слека
- если это сложно - значит пока рановато)
Advertisement
Add Comment
Please, Sign In to add comment