Иногда возникает необходимость создать сложный объект в приложении. Одним из решений для этого является шаблон Factory, а другим — шаблон проектирования Builder. В некоторых ситуациях вы даже можете объединить эти две модели. Но в этой статье я хочу изучить шаблон проектирования Builder . Первое, что мне нужно сказать, что это творческий паттерн. В каких ситуациях вы должны использовать шаблон проектирования Builder? Определенно, когда создание объекта требует много других независимых объектов. Когда вы хотите скрыть процесс создания от пользователя. Когда вы можете иметь различное представление объекта в конце процесса строительства.
Давайте продолжим с примером кода. UML схема шаблона:
Как я уже упоминал, шаблон «Строитель» — это шаблон творчества. Это обстоятельство подразумевает создание какого-либо объекта (продукта) в конце процесса. Продукт создается с помощью конкретного конструктора, в свою очередь, у него есть некоторый родительский класс или интерфейс конструктора. Конечная точка шаблона — это класс директора, он отвечает за создание конкретного конструктора для соответствующего продукта.
Пример будет основан на знаменитой и эпичной компьютерной игре — StarCraft. Роль продукта будет играть Зилот — это простой боевой протосс. Роль режиссера сыграет Гейтвей. А бетоностроитель — это ZealotBuilder. Весь код я приведу ниже:
Абстрактный класс для игровых блоков:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public abstract class Unit { protected int hitPoints; protected int armor; protected int damage; public int getHitPoints() { return hitPoints; } public void setHitPoints( int hitPoints) { this .hitPoints = hitPoints; } public int getArmor() { return armor; } public void setArmor( int armor) { this .armor = armor; } public int getDamage() { return damage; } public void setDamage( int damage) { this .damage = damage; } } |
Класс фанатиков (товар):
01
02
03
04
05
06
07
08
09
10
|
public class Zealot extends Unit { public String toString() { return "Zealot is ready!" + "\nHitPoints: " +getHitPoints()+ "\nArmor: " +getArmor()+ "\nDamage: " +getDamage(); } } |
Интерфейс застройщика:
1
2
3
4
5
6
7
8
|
public interface UnitBuilder { public void buildHitPoints(); public void buildArmor(); public void buildDamage(); public Unit getUnit(); } |
Реализация интерфейса строителя:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class ZealotBuilder implements UnitBuilder { private Unit unit; public ZealotBuilder() { unit = new Zealot(); } @Override public void buildHitPoints() { unit.setHitPoints( 100 ); } @Override public void buildArmor() { unit.setArmor( 50 ); } @Override public void buildDamage() { unit.setDamage( 8 ); } @Override public Unit getUnit() { return unit; } } |
Класс Gateway (Director):
01
02
03
04
05
06
07
08
09
10
|
public class Gateway { public Unit constructUnit(UnitBuilder builder) { builder.buildHitPoints(); builder.buildArmor(); builder.buildDamage(); return builder.getUnit(); } } |
А теперь давайте посмотрим, как все это работает вместе:
01
02
03
04
05
06
07
08
09
10
|
... public static void main(String[] args) { UnitBuilder builder = new ZealotBuilder(); Gateway director = new Gateway(); Unit product = director.constructUnit(builder); System.out.println(product); } ... |
Результат последнего фрагмента кода:
1
2
3
4
|
Zealot is ready! HitPoints: 100 Armor: 50 Damage: 8 |
Итак, как вы можете видеть, шаблон проектирования Builder действительно полезен в ситуации, когда вам нужно создавать сложные объекты. Пример в руководстве не был действительно сложным, но теперь вы можете представить, в какой ситуации вы можете применить этот подход. Другие статьи о шаблонах дизайна вы можете найти здесь .