[Delphi] Design Patterns GoF – Abstract Factory

Olá, leitores, como vão?
Conforme prometido, hoje inicio a temporada de artigos sobre Design Patterns! Não serão sequenciais, já que eventualmente postarei artigos sobre outros assuntos. Mesmo assim, é com grande satisfação que dou este primeiro passo.
Para inaugurar, apresento-lhes o Abstract Factory! Confira o artigo e aprenda um pouco mais sobre este padrão!

Introdução

Pessoal, para evitar que o artigo fique extenso, vou dispensar a explicação sobre o que são Design Patterns e seus benefícios, ok? Acredito que a maioria (senão todos) já conhecem ou ao menos já ouviram falar destes padrões. No entanto, caso for necessário, posso elaborar um artigo abordando o conceito de Design Patterns de forma geral. Basta deixar um comentário! 🙂

Pois bem, sabemos que uma das características que “poluem” o código é o excesso de estruturas condicionais, como o IF. Não digo que um projeto não deve ter essas estruturas, mas afirmo que muitas delas são desnecessárias, uma vez que podem ser substituídas pelo padrão que vou apresentar neste artigo, mantendo o código mais limpo.

Desvantagens de estruturas condicionais

Considere um sistema de loja de eletrônicos, no qual o usuário seleciona uma marca (como Dell ou Apple) e consulta os produtos, como notebooks, desktops e servidores.

O código executado para exibir os dados dos produtos é listado abaixo:

Notou as estruturas condicionais? Sei que podemos aproveitar o mesmo IF para exibir os dados de todos os produtos, mas o código acima é só um exemplo. Na prática, estes IFs podem estar em métodos separados.

Imagine, agora, que essa mesma loja venderá também produtos da Lenovo. Cada método receberá um novo IF:

E vou mais além. Suponha também que servidores começarão a ser comercializados. Um novo bloco de código (ou método) terá de ser criado com todos esses IFs, um para cada marca.

Em suma, quanto mais marcas e produtos a loja trabalhar, maior será a quantidade de estrutura condicionais. O que aconteceria, por exemplo, se os desenvolvedores esquecessem de adicionar um IF em um destes blocos? Ruim, não?

Abstract Factory

Certa vez, quando eu estava participando de um treinamento sobre Design Patterns, o ministrante mencionou que cada estrutura IF deveria se “transformar” em uma nova classe. Para isso, teríamos um mecanismo que nos retornaria os dados que precisamos naquele momento sem utilizarmos estruturas condicionais. Chamamos este mecanismo de fábrica, pois, analogicamente, é capaz de “criar” e disponibilizar um “produto”.

Bom, mas nada disso parece fazer sentido se não houver uma aplicação prática, não é?

Usando o mesmo exemplo da loja, o primeiro passo é criar 3 Interfaces: duas para cada produto (notebooks e desktops) e outra para as marcas. Ah, uma observação: Interfaces são recursos extremamente indispensáveis para a implementação de Design Patterns.

Agora, codificaremos a classe concreta de duas marcas que comercializam notebooks e desktops:

  • Dell, que possui o Vostro e Inspiron;
  • Apple, que possui o MacBook e iMac.

Vale lembrar que, como elas implementam IFactoryMarca, devem obrigatoriamente declarar os métodos assinados nessa Interface.

Em seguida, vamos criar as classes referentes aos notebooks:

E, finalmente, as classes relacionadas aos desktops:

Nossa, André, quanto código!!!
Sim, foi a mesma coisa que pensei enquanto estudava Design Patterns, porém, acredite: se um desenvolvedor continuar insistindo na forma como apresentei no início do artigo (com estruturas condicionais), em pouco tempo o seu código ficará bem maior do que a implementação apresentada acima. O nível de abstração que alcançamos com esse padrão (criando Interfaces e classes com responsabilidade única), permitirá com o que a nossa arquitetura se torne bastante desacoplada, reduzindo as linhas de código a longo prazo.

Bom, pessoal, com tudo já pronto, é hora de conferirmos toda a mágica do padrão. Veja abaixo como ficou o método MostrarDadosProdutos. O único IF aparece somente nas primeiras linhas para instanciar a marca selecionada.

Ué, onde estão os  outros IFs? 🙂

Com um pouco mais de implementação, é possível remover até o IF no início do método, mas isso é assunto para outro artigo.

Conclusão

Com o Abstract Factory, reduzimos as estruturas condicionais, facilitamos a manutenção do código e, acima de tudo, mantemos a escalabilidade da arquitetura, ou seja, se a loja passar a vender uma nova marca e/ou um novo produto, basta criar apenas novas classes e alterar a nossa fábrica. O Abstract Factory “se vira” com o resto.

Agora, olhando o código novamente, tente imaginar o quão fácil seria se precisássemos adicionar a marca “Lenovo”. Esse é o objetivo! 🙂

Caso você tenha ficado com alguma dúvida, baixe um exemplo no link abaixo (com alguns aprimoramentos) ou deixe um comentário!

 

Abraço, pessoal!


 

André Celestino