Skip to content

Criacionais

Histórico de Versão

Data Versão Descrição Autor(es)
16.03.2022 0.1 Adição Prototype Peniel Etèmana
16.03.2022 0.1.1 Adição do singleton Natanael Filho
16.03.2022 0.1.2 Adição do multiton Natanael Filho
17.03.2022 0.2 Adição do Builder Jonathan Jorge
18.03.2022 0.2.1 Adição GOF Absract Factory Nilvan Peres
19.03.2022 0.2.2 Revisão do singleton Jonathan Jorge
20.03.2022 0.3 Revisão Builder Nilvan Peres
20.03.2022 0.4 Revisão Prototype Nilvan Peres
21.03.2022 0.5 Adição do Factory Method Henrique Melo
21.03.2022 0.6 Revisão Factory Method Nilvan Peres
21.03.2022 0.7 Adição Introdução Peniel Etèmana

Participantes

Introdução

  Segundo o livro Design Patterns: Elements of Reusable Object-Oriented Software, os padrões de projetos criacionais fazem a abstração do processo de instanciação, tornando um sistema independente de como seus objetos são criados, compostos e representados.

  Os padrões de projeto Criacionais se preocupam basicamente com a maneira como os objetos são criados, buscando reduzir a instabilidade e complexidade, criando objetos de maneira controlada.

  O novo operador é considerado prejudicial, principalmente por espalhar objetos por todo o aplicativo. Podendo com o tempo gerar problemas ao alterar uma implementação devido ao fato das classes estarem fortemente acopladas.

  Os Padrões de Criação buscam resolver esse problema separando o cliente do processo de inicialização real.

  Fazendo uma analogia com uma situação real, quando um mecânico realiza o conserto de um carro ele faz a terceirização das peças, solicitando elas a um fornecedor, para então realizar a instalação, não se preocupando com todo o processo envolvido na criação desses componentes.

Abstract Factory

   Esse padrão permite que uma interface seja responsável pela criação de famílias de objetos que possuem um "tema" em comum, sem a necessidade de especificar a classe concreta.

   O abstract factory deve ser aplicado quando:

  • Um sistema que deveria ser ser independente em como os produtos são criados, associados e representados.
  • Um sistema que deveria ser configurado com múltiplas famílias de produtos.
  • Quando é desejado implementar uma classe de produtos, e você deseja que tenham acesso apenas a interface, e não a implementação.[2]
  •   

  • Vantagens:
    1. Há o isolamento das classes concretas. A factory ajuda a encapsular a responsabilidade e o processo de criar ojetos e isola o cliente da classes de implemtações.
    2. As mudanças nas classes concretas ficam unitárias, tendo que alterar o código em apenas um lugar, caso haja alguma mudança de configuração na classe de fábrica concreta.
    3. Permite maior consistências dos produtos, permitindo que aplicação use uma família por vez.
  • Desvantagens:
    1. A extensão de novos produtos não ocorre de forma fácil, pois é necessário a alteração de diferentes trechos de códigos em múltiplos arquivos, a classe da fábrica abstrata e toda as suas subclasses.

       Os principais participantes desse padrão são AbstractFactory(interface para criação de produtos), ConcreteFactory(uma fabrica que "produz" novos produtos), Products(a instância do produto criado pela factory), AbstractProduct (Interface para os produtos que serão criados). Para aplicar esse conceito no projeto, será feito um exemplo-TOY. Lembrando que são necessárias adaptações, pois o projeto está sendo desenvolvido em JavaScript, dessa forma, não é suportado herança de classes, por isso as classes concretas receberão mesmos métodos e propriedades para garantir que tenham as mesmas definições [3].

    Figura 2: Aplicação do padrão AbstractFactory - ToyExample
    Autor: Nilvan Peres, 2022.

    Factory Method

      O Factory Method é um padrão bastante adotado por diversas linguagens. Consiste basicamente na definição de uma interface comum para criação de objetos, deixando para as subclasses a responsabilidade de instanciá-los. Essa estrutura é composta pelas interfaces Product, ConcreteProduct, Creator e ConcreteCreator.

    • Product: Se caracteriza como a interface comum dos produtos a serem criados;

    • ConcreteProduct: Responsável pela implementação da interface Product, definindo produtos concretos;

    • Creator: É uma classe abstrata sendo responsável pela declaração da operação factoryMethod, que retorna um objeto Product. Podendo ainda definir uma implementação padrão e assim retornar um ConcreteProduct específico ou também pode definir alguns métodos que invocam FactoryMethod;

    • ConcreteCreator: Basicamente estende a classe Creator, realiza a redefinição do factoryMethod para retornar uma instância de um ConcreteProduct criado;

      Em nosso projeto, é possível utilizar o Factory Method na classe "UsuarioControlador", onde pode ser implementado uma interface com os atributos e métodos necessários, uma ConcreteProduct que realize a implementação dos métodos, e por meio de uma ConcreteCreater realizar a redefinição específica para cada tipo de usuário.


    Figura 1: Factory Method
    Autor: Henrique Melo, 2022.

    Prototype

       GoFs Criacionais são padrões que fornecem vários mecanismos de criação de objetos, que aumentam a flexibilidade e a reutilização do código existente. Permitem, nesse caso, usar mecanismos/recursos para facilitar tanto a incorporação de novos algoritmos para novos contextos quanto a seleção de qual algoritmo usar dado um contexto. Entre os principais GoFs criacionais temos o Prototype,é um padrão de design criacional que permite copiar objetos existentes sem tornar seu código dependente de suas classes

       O padrão prototype deve ser aplicado quando:

  • Quando o sistema deve ser independente de como os produtos são criados e representados.
  • Quando as classes que serão instanciadas são especificadas no tempo de execucação do código.[2]
  •    O padrão Prototype(protótipo), da forma como foi descrito no livro Design Patterns: Elements of Reusable Object-Oriented Software, contém os seguintes elementos:

    • prototype — uma classe que declara uma interface para objetos capazes de clonar a si mesmo.

    • prototype concreto — implementação de um prototype;

    • cliente — cria um novo objeto através de um prototype que é capaz de clonar a si mesmo.

    Figura 1: Diagrama descrevendo prototype design pattern.
    Fonte: Wikipédia.

    Uso desse padrão no nosso projeto, será represetado na figura 5

    Figura 5: Aplicação do padrão Prototype - ToyExample
    Autor: Nilvan Peres, 2022.

       Esse padrão pode ser observado no produto, que quando é criado, ele possui uma estrutura com valores pré-definidos, que não sao necessários serem especificados no momento de criação.

  • Vantagens:
    1. Adição e remoção de produtos em tempo de exucação, melhorando significamente o desempenho da aplicação.
    2. Especificando novos objetos a partir de alterações de valores.
    3. Especificando novos objetos a partir da variação de estruturas.
  • Desvantagens:
    1. Cada subclasse do Prototype deverá implementar uma operação de clone, o que é um processo complexo, pois os objetos internos podem não suportar o clone, ou possuir referências circulares.

       Podemos concluir que, o Prototype faz a criação de novos objetos, mas ao invés de criar objetos com valores não inicializados, ele cria objetos através da cópia dos valores de um protótipo. Esse padrão nos permitirá copiar objetos existentes sem que essa parte do código tenha dependência em classes. Quando quisermos criar um objeto igual, não precisamos acionar essas classes, basta fazer a exata cópia do objeto já criado.

    Builder

       O Builder é um padrão de projeto de software criacional quer permite a construção de objetos passo a passo. Permite a produção e representação de objetos complexos usando o mesmo código de construção, baseado em regras e parâmetros que sejam informados ao objeto responsável pela construção.

       A estrutura desse padrão pode ser visualizado abaixo, na figura 3:

    Figura 3: Estrutura do padrão Builder
    Fonte: GAMMA et al., 1995

       Esse padrão deve ser aplicado quando:

  • O algoritmo resposável pela criação do objeto é complexo e deve ser independente das partes e da forma que serão montadas.
  • O processo de construção deve permitir diferentes representações para os ojetos que foram construídos.[2]
  •    O padrão Builder poderia ser aplicado caso a aplicação tivesse a funcionalidade de baixar os dados do dashboard em diversos formatos, como por exemplo CSV, JSON, XML, etc. Para a aplicação da funcionalidade citada a cima, o padrão seria aplicado com a seguinte estrutura que será representada na figura 4:

    Figura 4: Estrutura da aplicação do padrão Builder
    Autor: Jonathan Jorge, 2022.

       Os participantes dessa estrutura são:

    • Builder (ConverterDashboard)
      1. Especifica uma interface abstrata para criar partes de um objeto de Product.
    • ConcreteBuilder (ConversorJson, ConversorCsv, ConversorXml)
      1. Constrói e monta partes do produto através da implementação da interface Builder.
      2. Define e mantém um registo da representação que cria.
      3. Fornece uma interface para a recuperação do produto (ex., ObterCsv, ObterJSON, etc.).
    • Director (ExportaDashboard)
      1. Constrói um objeto usando a interface Builder.
    • Product ( Arquivo CSV, Arquivo JSON, Arquivo XML)
      1. Representa o objeto complexo em construção. O ConcreteBuilder constrói a representação interna do produto e define o processo pelo qual este é montado.
      2. Inclui classes que definem as partes constituintes, incluindo interfaces para a montagem das peças no resultado final.

       De acordo com GAMMA, a aplicação do builder tem as seguintes vantagens:

    1. Permite variar a representação interna de um produto;
    2. Isola o código de construção e representação;
    3. Proporciona um melhor controle sobre o processo de construção.

      Dessa forma, podemos concluir que, o padrão Builder facilita na separação de toda a lógica de criação dos objetos, evitando que as classes que representam esses objetos finais fiquem muito extensas e de pouca manutenibilidade, além de prover a implementação de múltiplos builders especializados, onde tem-se objetos construídos em cima de uma interface.

    Singleton

      Vemos que no Design Pattern o padrão Singleton possui uma peculiaridade, a qual seria a existência de um atributo estático  na classe que instância a própria classe, mas quais as vantagens para está pratica? Simplificando, classes públicas podem ser instâncias N vezes, logo é possível criar inúmeros objetos. Então, para aplicar o Singleton declaramos o construtor de uma classe como pública, e adicionamos uma variável estática, a qual limitará a criação de instâncias da classes.

      Portanto, Singleton será usado quando a aplicação exigir a existência de uma única instância de uma classe, além disso, o acesso desta instância deverá ser através de um ponto bem conhecido.

      Algumas vantagens da aplicação do Singleton:

    • Acesso controlado a uma instância única.
    • Menos variáveis globais para armazenar instâncias únicas.
    • Permite um número variável de instâncias (alterando o padrão para controlar esse número).

      Atualmente em nosso projeto esse padrão poderá ser aplicado na classe Gerente. Para a aplicação é interessante exista apenas uma instância de gerente, pois assim evita-se a instância vários gerentes externos que não sejam o próprio gerente.

      Segue um exemplo simplificado em Java de uma estrutura no padrão Singleton:

    class Gerente{
        protected Gerente instanceGerente;
    
        private Gerente() {}
    
        public static getInstanceGerente() {
            if (!instanceGerente) {
                this.instanceGerente = new Gerente();
            }
            return this.instanceGerente;
        }
    }
    
    

    Multiton

      O Multiton é um padrão que pouco se difere do Singleton. Basicamente, enquanto no Singleton a instância da classe está delimitada na criação de apenas um objeto, o Multiton delimita um número de múltiplos objetos, limitado a uma quantidade especificada, que serão criados,  fornecendo vários objetos para serem usados em caráter global para todo o projeto.

      Como exemplo trago uma classe ProdutoLimpeza, nela queremos instanciar 4 produtos diferentes, sendo eles, cera automotiva, sabão para carro,  limpa vidros e espuma multiúso, a partir de uma estrutura de HashMap, podemos instanciar cada objeto de forma única possuindo valores conhecidos e diferentes. A estrutura se mantêm bem semelhante à utilizada no Singleton.

      A situação atual em que se encontra o projeto não há classe que se beneficiária do uso de Multiton, já que não há limitações de N objetos. Além disso, mesmo usando o exemplo dos produtos de limpeza, a plataforma atualmente não possui  o objetivo de gerenciar produtos de limpezas, por isso não se torna viável. 

    Referências

    [1] SERRANO, Milene. Módulo Padrões de Projeto GoF(s) Criacionais. Disponível em : https://aprender3.unb.br/course/view.php?id=11018&section=4. Acesso em 16, mar de 2022.

    [2] GAMMA, E. et al. Design Patterns: Elements of Reusable Object-Oriented Software. USA: Addison-Wesley Longman Publishing Co., Inc., 1995. ISBN 0201633612.

    [3] Design Patterns - Abstract Factory, DO FACTORY. Disponível em: https://www.dofactory.com/javascript/design-patterns/abstract-factory, Acesso em 18, mar de 2022.

    [4] Builder Disponível em: https://refactoring.guru/pt-br/design-patterns/builder. Acesso em 17, Mar de 2022.

    [5] 007 – Padrão de Projeto BUILDER – Padrão GoF de Criação – Curso de Design Patterns Disponível em: http://davesbalthazar.com.br/007-padrao-de-projeto-builder-padrao-gof-de-criacao-curso-de-design-patterns/. Acesso em 17, Mar de 2022.

    [6] Desing Patterns na prática - Desvendando o Builder (parte 2) Disponível em: http://www.linhadecodigo.com.br/artigo/2576/desing-patterns-na-pratica-desvendando-o-builder-parte-2.aspx. Acesso em 17, Mar de 2022.

    [7] Refactoring Guru. Prototype. Disponível em: https://refactoring.guru/design-patterns/prototype. Acesso em: 16 mar. 2022.

    [8] Wikipédia. Disponível em: https://en.wikipedia.org/wiki/Prototype_pattern. Acesso em: 16 mar. 2022.

    [9] Single Pattern. Departamento de Informática, UFMA, Maranhão. Disponível em: http://www.deinf.ufma.br/~vidal/singleton.pdf. Acesso em 16, mar de 2022.

    [10] GOFs Criacionais. Disponível em: https://unbarqdsw2021-1.github.io/2021.1_G6_Curumim/padroes-de-projeto/gofs-criacionais/#multiton. Acesso em 16, mar de 2022.