13
January
2007

Паттерн Builder (Строитель)

Posted in: Паттерны проектирования |

Паттерн Builder является паттерном создания объектов (creational pattern). Суть его заключается в том, чтобы отделить процесс создания некоторого сложного объекта от его представления. Таким образом, можно получать различные представления объекта, используя один и тот же “технологический” процесс.
Паттерн Строитель иногда путают с паттерном проектирования Factory. И не удивительно, так как они действительно во многом схожи.
В этой статье я опишу небольшой пример реализации Builder’a на языке Java, а так же попробую коротко объяснить разницу между Builder и Factory.

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

class Computer {
  private String display = null;
  private String systemBlock = null;
  private String manipulators = null;

  public void setDisplay(String display) {
    this.display = display;
  }
  public void setSystemBlock(String systemBlock) {
    this.systemBlock = systemBlock;
  }
  public void setManipulators(String manipulators) {
    this.manipulators = manipulators;
  }
}

abstract class ComputerBuilder {
  protected Computer computer;

  public Computer getComputer() {
    return computer;
  }

  public void createNewComputer() {
    computer = new Computer();
  }

  public abstract void buildSystemBlock();
  public abstract void buildDisplay();
  public abstract void buildManipulators();
}

Теперь, нам нужно предоставить хотя бы одну имплементацию построителя (иными словами, нам нужен конкретный Builder):

class CheapComputerBuilder extends ComputerBuilder {
  public void buildSystemBlock() {
    computer.setSystemBlock("Everest");
  }
  public void buildDisplay() {
    computer.setDisplay("CRT");
  }
  public void buildManipulators() {
    computer.setManipulators("mouse+keyboard");
  }
}

Далее, еще одна важная часть нашей программы - класс Director:

class Director {
  private ComputerBuilder computerBuilder;

  public void setComputerBuilder(ComputerBuilder computerBuilder) {
    this.computerBuilder = computerBuilder;
  }

  public Computer getComputer() {
    return computerBuilder.getComputer();
  }

  public void constructComputer() {
    computerBuilder.createNewComputer();
    computerBuilder.buildSystemBlock();
    computerBuilder.buildDisplay();
    computerBuilder.buildManipulators();
  }
}

Вы наверное спросите, а зачем вообще создавать этот класс, ведь можно сразу вызывать методы Builder’a из клиента. Класс Director делает комплексное построение продукта (в нашем случае компьютера) и не заботиться о том, как именно создаются его части.
Те, кто читал предыдущие статьи о паттернах проектирования, наверняка увидят в классе Director использование паттерна Strategy. Множество построителей компьютера - ComputerBuilder - это и есть стратегии.
Ну и наконец, класс-клиент:

class BuilderExample {
  public static void main(String[] args) {
    Director director = new Director();
    ComputerBuilder cheapComputerBuilder = new CheapComputerBuilder();

    director.setComputerBuilder(cheapComputerBuilder);
    director.constructComputer();

    Computer computer = director.getComputer();
  }
}

Преимущества использования паттерна Builder:

  • дает больший контроль над процессом создания объектов;
  • позволяет варьировать внутреннее представление объекта;
  • отделяет процесс конструирования объекта от его внутреннего представления

На последок несколько слов о разнице между паттерном Factory и паттерном Строитель. Factory сосредотачивается на том, что именно создается, а Builder - на том, как оно создается.

12 Comments »

RSS feed for comments on this post.



gdwz
May 7, 2007 #

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

May 7, 2007 #

Обрати внимание на этот текст из статьи:

Класс Director делает комплексное построение продукта (в нашем случае компьютера) и не заботится о том, как именно создаются его части.

Может на этом примере будет понятнее: ты строишь дом, у тебя есть бригада строителей разных специализаций (каждая специализация - это метод из класса Builder). Director - это ты :). Что ты скажешь строителям, то они и будут делать. Если скажешь им сначала стены построить, а только потом залить фундамент, то они так и сделают. Но ты, как настоящий Director, знаешь последовательность, в которой строить дом. С другой стороны, тебя не сильно интересует сам процесс, например, возведения стен (кирпичи будут класть слева направо или наоборот).

TRicK
August 15, 2007 #

А где в языке Java используется паттерн Builder?

Ress
February 26, 2008 #

Ну вообще много где используется. Зачастую с паттерном Factory. Builder+Director помогает инкапсулировать наши действия.

Raman
April 29, 2008 #

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

illyge
June 14, 2008 #

Правильно ли я понимаю, что Директор - это фактически Фасад (Facade)? Или есть принципиальная разница?

ElKa
July 16, 2008 #

супер! спасибо за пример!!
как раз искала что-нибудь подобное

voodoosaveworld
September 22, 2008 #

а не проще было бы сделать класс Computer и класс Director? тоже самое было бы

Evgenic
October 12, 2008 #

Господа, чувствеется путаница между кислым и мягким. Сложность объектов тут ни при чем, это как частный случай. Тут главное следующий момент. Вот вы написали код креейта некого объекта. Со временем объект поменялся или добавились его вариации. Что, переписывать получение и последующее использование? Используя данный паттерн креейт и юзание объектов будет обно и тоде на все времена, а вам остается тока дописывать вновь требуемые классы. Очень удобно при использовании SpringFrameWork.

Zorkus
January 2, 2009 #

На самом деле в яве это часто используется поблизости от XML.
Cмотри классы javax.xml.parsers.DocumentBuilder и им подобные.

FcUK
August 19, 2009 #

возможно это детали…но я б сделал для Director слудующий конструктор

public Director(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}

losaped
February 23, 2010 #

Пишу комент, только, чтобы помочь автору статью лучше. Так как, Вы описываете именно паттерн, а не реализацию сборщика компа, то вначале статьи опишите границу паттерна, т.е.: someclass - делает то-то; …
В общем, как в остальных ваших статьях. Тут тоже все понять удалось, но немножко сложнее статья на мозг легла.
А вообще, очень полезный сайт. Спасибо большое. Буду читать :)

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> <pre>