Creational pattern – Builder


A pattern Builder tem por finalidade isolar a construção de um objeto complexo da sua representação, levando em consideração que o mesmo processo de construção possa criar diferentes representações. Sendo assim, o algoritmo para a construção de um objeto deve ser independente das partes que realmente compõem o objeto e também de como eles são montados.

Utilizando esta pattern, o que temos a fazer é criar uma classe, qual especifica uma interface abstrata para a criação das partes de um objeto-produto. Esta classe abstrata deverá ser herdada pelos objetos concretos que implementaram os métodos de construção para aquele objeto. Esta classe concreta nos fornecerá uma forma de recuperarmos o produto, retornando-o de alguma forma para o cliente que o solicitou.

Vejamos abaixo os participantes envolvidos nesta pattern:

  • Director: Constrói um determinado objeto, utilizando a interface de Builder (classe abstrata).
  • Builder: Define uma interface abstrata para a criação das partes de um objeto-produto.
  • ConcreteBuilder: Implementa os métodos de construção da classe abstrata e também mantém a representação do objeto que cria. Fornece ao cliente um método para a recuperação do produto.
  • Product: Representa o objeto complexo em construção, incluindo as interfacces para a montagem das partes no resultado final.

O diagrama abaixo ilustrará estes participantes:

Figura 1 – Participantes da Pattern Builder.

Antes de começarmos a analisar o código da pattern, vamos primeiramente entender o cenário: Teremos dois tipos de objetos complexos, um chamado “Apartamento” e outro chamado “Casa”, pois cada um desses objetos tem particularidades em sua criação, ou seja, implementam diferentemente os métodos de sua construção. Abaixo a classe ConstrucaoBuilder que define a interface necessária para os objetos concretos:

1
2
3
4
5
6
7
8
9
 
Public MustInherit Class ConstrucaoBuilder
 
    Protected _dados As Hashtable
 
    Public MustOverride Sub ConstroiParedes()
    Public MustOverride Sub ConstroiJanelas()
    Public MustOverride Sub DefineNumero()
 
End Class
 
Código 1 – Classe Base que contém a Interface para a criação dos objetos.

Confrontando o código acima com o modelo estrutural da pattern, esta classe é a que chamamos de “Builder”, que define a interface abstrata. Depois disso, o que temos à fazer é criar uma classe (“Director”) que terá receberá como parâmetro em um método construtor um objeto do tipo da classe abstrata, e internamente será invocado seus métodos para a construção do objeto. O código abaixo ilustra a classe “Director”:

1
2
3
4
5
6
7
8
9
 
Public Class Construtora
 
    Public Sub Construir(ByVal construcao As ConstrucaoBuilder)
        construcao.ConstroiJanelas()
        construcao.ConstroiParedes()
        construcao.DefineNumero()
    End Sub
 
End Class
 
Código 2 – Classe “Director”.

Como podemos ver, recebemos no parâmetro do método “Construir” um objeto do tipo “ConstrucaoBuilder”, que é o nosso objeto “Builder”. Podemos ver que internamente são invocados os métodos de criação do objeto, definindo assim uma ordem de criação do objeto que está sendo informado e reutilizando o algoritmo (os passos) de criação para todos os objetos.

Feito isso, nos resta implementarmos os nossos objetos complexos (Casa e Apartamento), que obrigatóriamente devem derivar da classe “ConstrucaoBuilder”, implementando os seus métodos de criação e retorno para o cliente. Abaixo o código relacionado ao nosso objeto “Apartamento”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
Public Class Apartamento
 
    Inherits ConstrucaoBuilder
 
    Public Overrides Sub ConstroiJanelas
        _dados = New Hashtable
        _dados.Add(“Janelas”, “2”)
    End Sub
 
    Public Overrides Sub ConstroiParedes
        _dados.Add(“Paredes”, “12”)
    End Sub
 
    Public Overrides Sub DefineNumero
        _dados.Add(“Número”, “A-56”)
    End Sub
 
    Public Sub VisualizarConstrucao
        Console.WriteLine(“APARTAMENTO:”)
        For Each d As DictionaryEntry In _dados
            Console.WriteLine(“{0}: {1}”, d.Key, d.Value)
        Next
        Console.WriteLine()
    End Sub
 
End Class
 
Código 3 – Classe Apartamento (“ConcreteBuilder”).

Vemos que ao herdar a classe “ConstrucaoBuilder” os métodos “ConstroiJanelas”, “ConstroiParedes”, “DefineNumero” e criamos um método chamado “VisualizarConstrucao” para devolver ao cliente o resultado gerado. Por questões de exemplo, a classe “Casa” tem a mesma estrutura interna em seus métodos de construção e sendo assim, vamos ocultá-la aqui por questões de espaço, mas pode consultá-la no código fonte do artigo.

E finalmente, a chamada no cliente fica:

1
2
3
4
5
6
7
8
9
10
11
12
13
 
Sub Main()
    
    Dim construtora As New Construtora
    Dim apto As New Apartamento
    Dim casa As New Casa
    
    construtora.Construir(apto)
    construtora.Construir(casa)
    
    apto.VisualizarConstrucao()
    casa.VisualizarConstrucao()
    
End Sub
 
Código 4 – Consumindo as classes no cliente.

Vemos que criamos/configuramos a instância de uma classe do tipo “Construtora” que é o nosso “Director”, que envia as solicitações ao Builder, que este por sua vez fará o seu trabalho de construção de uma determinada parte do objeto concreto. Criamos também mais dois objetos, sendo um do tipo “Apartamento” e outro do tipo “Casa”, quais são posteriormente passados para o método “Construir” do nosso Director, e este executa os métodos de construção respectivos do objeto em questão.

Pode-se reparar, que independentemente do objeto passado para o método construtor de nosso “Director”, o processo de criação do objeto será executado – baseando-se na instância do mesmo – e assim percebemos que separamos a criação dos objetos complexos da sua representação mas utilizando o mesmo processo, ou melhor, os mesmo passos, possibilitando diferentes representações.

Aplica-se esta pattern quando o algoritmo de criação de um objeto complexo deve ser independente das partes que o compõem das quais são montadas e também quando deverá permitir diferentes representações para o objeto que é construído.

CONCLUSÃO: Apesar de ser uma pattern de utilização 3 em uma escala de 0 à 5, é útil quando necessitamos separar a construção de um objeto complexo da sua representação, criando assim, diversas representações deste objeto.

OOBuilder.zip (17.17 kb)

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s