Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da...

48

Transcript of Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da...

Page 1: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a
Page 2: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

MerMergulho nogulho noss

PPADRADRÕEÕESSDEDE PPRROOJEJETTOO

v2020-1.1

VERSÃO DEMONSTRATIVA

Compre o livro completo:

https://refactoring.guru/pt-br/design-patterns/book

Page 3: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Algumas poucas palavrassobre direitos autoraisOi! Meu nome é Alexander Shvets. Sou

o autor do livro Mergulho nos Padrões

de Projeto e o curso online Mergulho

na Refatoração.

Este livro é apenas para seu uso pes-

soal. Por favor, não compartilhe-o com

terceiros exceto seus membros da família. Se você gostaria de

compartilhar o livro com um amigo ou colega, compre e envie

uma nova cópia para eles.

Toda a renda das vendas de meus livros e cursos é gasta no de-

senvolvimento do Refactoring.Guru. Cada cópia vendida ajuda

o projeto imensamente e faz o momento do lançamento de um

novo livro ficar cada vez mais perto.

Alexander Shvets, Refactoring.Guru, 2019

[email protected]

Ilustrações: Dmitry Zhart

Tradução: Fernando Schumann

Edição: Gabriel Chaves

Page 4: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Eu dedico este livro para minha esposa, Maria.

Se não fosse por ela, eu provavelmente teria

terminado o livro só daqui a uns 30 anos.

Page 5: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

ÍndiceÍndice ....................................................................................................................... 4

Como ler este livro ................................................................................................ 6

INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETOS..............................7

Básico da Programação Orientada a Objetos.............................8

Pilares da POO ................................................................................... 13

Relações entre objetos.................................................................... 21

INTRODUÇÃO AOS PADRÕES DE PROJETO ..................................................... 27

O que é um padrão de projeto? ................................................... 28

Por que devo aprender padrões?................................................. 33

PRINCÍPIOS DE PROJETO DE SOFTWARE........................................................ 34

Características de um bom design.............................................. 35

Princípios de projeto..................................................................................... 40

§ Encapsule o que varia ................................................................. 41

§ Programe para uma interface, não uma implementação 46

§ Prefira composição sobre herança .......................................... 51

Princípios SOLID ............................................................................................ 55

§ S: Princípio de responsabilidade única.................................. 56

§ O: Princípio aberto/fechado ...................................................... 58

§ L: Princípio de substituição de Liskov ................................... 62

§ I: Princípio de segregação de interface ................................. 69

§ D: Princípio de inversão de dependência ............................. 72

4 Índice

Page 6: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

CATÁLOGO DOS PADRÕES DE PROJETO .......................................................... 76

Padrões de projeto criacionais................................................................... 77

§ Factory Method.............................................................................. 79

§ Abstract Factory............................................................................. 96

§ Builder.............................................................................................112

§ Prototype........................................................................................133

§ Singleton........................................................................................149

Padrões de projeto estruturais ................................................................ 159

§ Adapter ...........................................................................................162

§ Bridge ..............................................................................................176

§ Composite ......................................................................................193

§ Decorator........................................................................................207

§ Facade.............................................................................................227

§ Flyweight .......................................................................................238

§ Proxy ................................................................................................253

Padrões de projeto comportamentais.................................................... 267

§ Chain of Responsibility .............................................................271

§ Command .......................................................................................291

§ Iterator ............................................................................................312

§ Mediator .........................................................................................328

§ Memento ........................................................................................344

§ Observer .........................................................................................361

§ State.................................................................................................377

§ Strategy...........................................................................................394

§ Template Method ........................................................................409

§ Visitor ..............................................................................................423

Conclusão .......................................................................................................... 440

5 Índice

Page 7: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Como ler este livro

Este livro contém as descrições de 22 padrões de projeto clás-

sicos formulados pela “Gangue dos Quatro” (ing. “Gang of Four”,

ou simplesmente GoF) em 1994.

Cada capítulo explora um padrão em particular. Portanto, você

pode ler de cabo a rabo ou escolher aqueles padrões que você

está interessado.

Muitos padrões são relacionados, então você pode facilmente

pular de tópico para tópico usando numerosos links. O fim de

cada capítulo tem uma lista de links entre o padrão atual e ou-

tros. Se você ver o nome de um padrão que você não viu ainda,

apenas continue lendo—este item irá aparecer em um dos pró-

ximos capítulos.

Os padrões de projeto são universais. Portanto, todos os exem-

plos de código neste livro são em pseudocódigo que não

prendem o material a uma linguagem de programação em

particular.

Antes de estudar os padrões, você pode refrescar sua memó-

ria indo até os termos chave da programação orientada a obje-

tos. Aquele capítulo também explica o básico sobre diagramas

UML, que são úteis porque o livro tem um monte deles. É claro,

se você já sabe de tudo isso, você pode seguir direto para

aprender os padrões patterns.

6 How to read this book

Page 8: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

INTRODUÇÃO ÀPROGRAMAÇÃO

ORIENTADA AOBJETOS

Page 9: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Básico da POOA Programação Orienteda à Objetos é um paradigma baseado no

conceito de envolver pedaços de dados, e comportamentos re-

lacionados aqueles dados, em uma coleção chamada objetos,

que são construídos de um conjunto de “planos de construção”,

definidos por um programador, chamados de classes.

Objetos, classes

Você gosta de gatos? Espero que sim, porque vou tentar expli-

car os conceitos da POO usando vários exemplos com gatos.

Este é um diagrama UML da classe. UML é a sigla do inglês Unified

Modeling Language e significa Linguagem de Modelagem Unificada.

Você verá muitos desses diagramas no livro.

8 Introdução à Programação Orientada a Objetos / Básico da POO

Page 10: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Digamos que você tenha um gato chamado Tom. Tom é um ob-

jeto, uma instância da classe Gato . Cada gato tem uma por-

ção de atributos padrão: nome, gênero, idade, peso, cor, etc.

Estes são chamados os campos de uma classe.

Todos os gatos também se comportam de forma semelhante:

eles respiram, comem, correm, dormem, e miam. Estes sãos

os métodos da classe. Coletivamente, os campos e os métodos

podem ser referenciados como membros de suas classes.

Dados armazenados dentro dos campos do objeto são

referenciados como estados, e todos os métodos de um

objeto definem seu comportamento.

Objetos são instâncias de classes.

9 Introdução à Programação Orientada a Objetos / Básico da POO

Page 11: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Nina, a gata do seu amigo também é uma instância da classe

Gato . Ela tem o mesmo conjunto de atributos que Tom. A di-

ferença está nos valores destes seus atributos: seu gênero é

fêmea, ela tem uma cor diferente, e pesa menos.

Então uma classe é como uma planta de construção que define

a estrutura para objetos, que são instâncias concretas daquela

classe.

Hierarquias de classe

Tudo é uma beleza quando se trata de apenas uma classe. Na-

turalmente, um programa real contém mais que apenas uma

classe. Algumas dessas classes podem ser organizadas em hi-

erarquias de classes. Vamos descobrir o que isso significa.

Digamos que seu vizinho tem um cão chamado Fido. Acontece

que cães e gatos têm muito em comum: nome, gênero, idade,

e cor são atributos de ambos cães e gatos. Cães podem respi-

rar, dormir, e correr da mesma forma que os gatos. Então pa-

rece que podemos definir a classe base Animal que listaria os

atributos e comportamentos em comum.

Uma classe mãe, como a que recém definimos, é chamada

de uma superclasse. Suas filhas são as subclasses. Subclas-

ses herdam estado e comportamento de sua mãe, definindo

apenas atributos e comportamentos que diferem. Portanto, a

classe Gato teria o método miado e a classe Cão o mé-

todo latido .

10 Introdução à Programação Orientada a Objetos / Básico da POO

Page 12: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Diagrama UML de uma hierarquia de classe. Todas as classes neste

diagrama são parte da hierarquia de classe Animal .

Assumindo que temos um requesito de negócio parecido, po-

demos ir além e extrair uma classe ainda mais geral de todos

os Organismos que será a superclasse para Animais e

Plantas . Tal pirâmide de classes é uma hierarquia. Em tal

hierarquia, a classe Gato herda tudo que veio das classes

Animal e Organismos .

11 Introdução à Programação Orientada a Objetos / Básico da POO

Page 13: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Classes em um diagrama UML podem ser simplificadas se é mais

importante mostrar suas relações que seus conteúdos.

Subclasses podem sobrescrever o comportamento de métodos

que herdaram de suas classes parentes. Uma subclasse pode

tanto substituir completamente o comportamento padrão ou

apenas melhorá-lo com coisas adicionais.

12 Introdução à Programação Orientada a Objetos / Básico da POO

Page 14: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

21 páginas

do livro completo são omitidas na versão demonstrativa

Page 15: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

PRINCÍPIOS DEPROJETO DESOFTWARE

Page 16: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Características de um bom projeto

Antes de prosseguirmos para os próprios padrões, vamos dis-

cutir o processo de arquitetura do projeto de software: coisas

que devemos almejar e coisas que devemos evitar.

Reutilização de código

Custo e tempo são duas das mais valiosas métricas quando de-

senvolvendo qualquer produto de software. Menos tempo de

desenvolvimento significa entrar no mercado mais cedo que os

competidores. Baixo custo de desenvolvimento significa que

mais dinheiro pode ser usado para marketing e uma busca

maior para clientes em potencial.

A reutilização de código é um dos modos mais comuns para se

reduzir custos de desenvolvimento. O propósito é simples: ao

invés de desenvolver algo novamente e do zero, por que não

reutilizar código já existente em novos projetos?

A ideia parece boa no papel, mas fazer um código já existente

funcionar em um novo contexto geralmente exige esforço adi-

cional. O firme acoplamento entre os componentes, depen-

dências de classes concretas ao invés de interfaces, operações

codificadas (hardcoded)—tudo isso reduz a flexibilidade do có-

digo e torna mais difícil reutilizá-lo.

35 Características de um bom projeto

Page 17: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Utilizar padrões de projeto é uma maneira de aumentar a flexi-

bilidade dos componente do software e torná-los de mais fácil

reutilização. Contudo, isso às vezes vem com um preço de tor-

nar os componentes mais complicados.

Eis aqui um fragmento de sabedoria de Erich Gamma1, um dos

fundadores dos padrões de projeto, sobre o papel dos padrões

de projeto na reutilização de código:

Eu vejo três níveis de reutilização.

No nível mais baixo, você reutiliza classes: classes de biblio-

tecas, contêineres, talvez “times” de classes como o contêiner/

iterator.

Os frameworks são o mais alto nível. Eles realmente tentam

destilar suas decisões de projeto. Eles identificam abstrações

importantes para a solução de um problema, representam eles

por classes, e definem relações entre eles. O JUnit é um pe-

queno framework, por exemplo. Ele é o “Olá, mundo” dos fra-

meworks. Ele tem o Test , TestCase , TestSuite e

relações definidas.

Um framework é tipicamente mais bruto que apenas uma única

classe. Também, você estará lidando com frameworks se fizer

subclasses em algum lugar. Eles usam o chamado princípio

Hollywood de “não nos chamem, nós chamaremos você”. O

framework permite que você defina seu comportamento cus-

1. Erich Gamma e a Flexibilidade e Reutilização: https://refactoring.guru/

gamma-interview

36 Características de um bom projeto / Reutilização de código

Page 18: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Extensibilidade

Mudança é a única constante na vida de um programador.

• Você publicou um vídeo game para Windows, mas as pessoas

pedem uma versão para macOS.

• Você criou um framework de interface gráfica com botões qua-

drados, mas, meses mais tarde, botões redondos é que estão

na moda.

• Você desenhou uma arquitetura brilhante para um site de e-

commerce, mas apenas um mês mais tarde os clientes pedem

tomizado, e ele irá chamar você quando for sua vez de fazer al-

guma coisa. É a mesma coisa com o JUnit, não é? Ele te chama

quando quer executar um teste para você, mas o resto acontece

dentro do framework.

Há também um nível médio. É aqui que eu vejo os padrões. Os

padrões de projeto são menores e mais abstratos que os fra-

meworks. Eles são uma verdadeira descrição de como um par

de classes pode se relacionar e interagir entre si. O nível de

reutilização aumenta quando você move de classes para pa-

drões e, finalmente, para frameworks.

O que é legal sobre essa camada média é que os padrões ofe-

recem reutilização em uma maneira que é menos arriscada que

a dos frameworks. Construir um framework é algo de alto risco

e investimento. Os padrões podem reutilizar ideias e conceitos

de projeto independentemente do código concreto. „

37 Características de um bom projeto / Extensibilidade

Page 19: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

por uma funcionalidade que permita que eles aceitem pedidos

pelo telefone.

Cada desenvolvedor de software tem dúzias de histórias pare-

cidas. Há vários motivos porque isso ocorre.

Primeiro, nós entendemos o problema melhor quando come-

çamos a resolvê-lo. Muitas vezes, quando você termina a pri-

meira versão da aplicação, você já está pronto para

reescrevê-la do nada porque agora você entende muito bem

dos vários aspectos do problema. Você também cresceu profis-

sionalmente, e seu código antigo é horrível.

Algo além do seu controle mudou. Isso é porque muitos das

equipes de desenvolvimento saem do eixo de suas ideias ori-

ginais para algo novo. Todos que confiaram no Flash para

uma aplicação online estão reformulando ou migrando seu có-

digo para um navegador após o fim do suporte ao Flash pelos

navegadores.

O terceiro motivo é que as regras do jogo mudam. Seu cliente

estava muito satisfeito com a versão atual da aplicação, mas

agora vê onze “pequenas” mudanças que ele gostaria para que

ele possa fazer outras coisas que ele nunca mencionou nas

sessões de planejamento inicial. Essas não são modificações

frívolas: sua excelente primeira versão mostrou para ele que

algo mais era possível.

38 Características de um bom projeto / Extensibilidade

Page 20: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Há um lado bom: se alguém pede que você mude algo

em sua aplicação, isso significa que alguém ainda se im-

porta com ela.

Isso é porque todos os desenvolvedores veteranos tentam se

precaver para futuras mudanças quando fazendo o projeto da

arquitetura de uma aplicação.

39 Características de um bom projeto / Extensibilidade

Page 21: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Princípios de projetoO que é um bom projeto de software? Como você pode medi-

lo? Que práticas você deveria seguir para conseguir isso? Como

você pode fazer sua arquitetura flexível, estável, e fácil de se

entender?

Estas são boas perguntas; mas, infelizmente, as respostas são

diferentes dependendo do tipo de aplicação que você está

construindo. De qualquer forma, há vários princípios universais

de projeto de software que podem ajudar você a responder

essa perguntas para seu próprio projeto. A maioria dos padrões

de projeto listados neste livro são baseados nestes princípios.

40 Princípios de projeto

Page 22: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Encapsule o que varia

Identifique os aspectos da sua aplicação que variam e

separe-os dos que permanecem os mesmos.

O objetivo principal deste princípio é minimizar o efeito cau-

sado por mudanças.

Imagine que seu programa é um navio, e as mudanças são ter-

ríveis minas que se escondem sob as águas. Atinja a mina e o

navio afunda.

Sabendo disso, você pode dividir o casco do navio em com-

partimentos independentes que podem ser facilmente selados

para limitar os danos a um único compartimento. Agora, se o

navio atingir uma mina, o navio como um todo vai continuar

à tona.

Da mesma forma, você pode isolar as partes de um programa

que variam em módulos independentes, protegendo o resto

do código de efeitos adversos. Dessa forma você gasta menos

tempo fazendo o programa voltar a funcionar, implementando

e testando as mudanças. Quanto menos tempo você gasta

fazendo mudanças, mais tempo você tem para implementar

novas funcionalidades.

41 Princípios de projeto / Encapsule o que varia

Page 23: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Encapsulamento à nivel de método

Digamos que você está fazendo um website de e-commerce.

Em algum lugar do seu código há um método

obterTotalPedido que calcula o total final de um pedido, in-

cluindo impostos. Nós podemos antecipar que o código relaci-

onado aos impostos precisa mudar no futuro. O rateio da taxa

depende do país, estado, ou até mesmo cidade onde o cliente

reside, e a fórmula atual pode mudar com o tempo devido a

novas leis ou regulamentações. Como resultado, você irá preci-

sar mudar o método obterTotalPedido com certa frequência.

Mas até mesmo o nome do método sugere que ele não se im-

portanta como os impostos são calculados.

ANTES: código de cálculo de impostos misturado com o resto do código

do método.

methodmethod getOrderTotal(order) isis1

total = 02

foreachforeach item in order.lineItems3

total += item.price * item.quantity4

5

ifif (order.country == "US")6

// Imposto das vendas nos EUA.7

total += total * 0.078

elseelse ifif (order.country == "EU"):9

// Imposto sobre o valor acrescentado.10

total += total * 0.2011

12

returnreturn total13

42 Princípios de projeto / Encapsule o que varia

Page 24: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Você pode extrair a lógica do cálculo do imposto em um mé-

todo separado, escondendo-o do método original.

DEPOIS: você pode obter o rateio de impostos chamando o método

designado para isso.

As mudanças relacionadas aos impostos se tornaram isoladas

em um único método. E mais, se o cálculo da lógica de im-

postos se tornar muito complexo, fica agora mais fácil movê-lo

para uma classe separada.

methodmethod getOrderTotal(order) isis1

total = 02

foreachforeach item in order.lineItems3

total += item.price * item.quantity4

5

total += total * getTaxRate(order.country)6

7

returnreturn total8

9

methodmethod getTaxRate(country) isis10

ifif (country == "US")11

// Imposto das vendas nos EUA.12

returnreturn 0.0713

elseelse ifif (country == "EU")14

// Imposto sobre o valor acrescentado.15

returnreturn 0.2016

elseelse17

returnreturn 018

43 Princípios de projeto / Encapsule o que varia

Page 25: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Encapsulamento a nível de classe

Com o tempo você pode querer adicionar mais e mais respon-

sabilidades para um método que é usado para fazer uma coisa

simples. Esses comportamentos adicionais quase sempre vem

com seus próprios campos de ajuda e métodos que eventual-

mente desfocam a responsabilidade primária da classe que o

contém. Extraindo tudo para uma nova classe pode tornar as

coisas mais claras e simples.

ANTES: calculando impostos em uma classe Pedido .

44 Princípios de projeto / Encapsule o que varia

Page 26: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Objetos da classe Pedido delegam todo o trabalho relacio-

nado a impostos para um objeto especial que fará isso.

DEPOIS: cálculo dos impostos está escondido da classe do Pedido .

45 Princípios de projeto / Encapsule o que varia

Page 27: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

30 páginas

do livro completo são omitidas na versão demonstrativa

Page 28: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

CATÁLOGO DOSPADRÕES DE

PROJETO

Page 29: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Padrões de projetocriacionaisOs padrões criacionais fornecem vários mecanismos de criação

de objetos, que aumentam a flexibilidade e reutilização de có-

digo já existente.

FactoryMethod

Fornece uma interface para criar objetos em uma superclasse,

mas permite que as subclasses alterem o tipo de objetos que

serão criados.

AbstractFactory

Permite que você produza famílias de objetos relacionados sem

ter que especificar suas classes concretas.

77 Padrões de projeto criacionais

Page 30: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

BuilderPermite construir objetos complexos passo a passo. O padrão per-

mite produzir diferentes tipos e representações de um objeto

usando o mesmo código de construção.

PrototypePermite que você copie objetos existentes sem fazer seu código

ficar dependente de suas classes.

SingletonPermite a você garantir que uma classe tem apenas uma instân-

cia, enquanto provê um ponto de acesso global para esta instân-

cia.

78 Padrões de projeto criacionais

Page 31: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

FACTORY METHODTambém conhecido como: Método fábrica, Construtor virtual

O Factory Method é um padrão criacional de projeto que

fornece uma interface para criar objetos em uma superclasse,

mas permite que as subclasses alterem o tipo de objetos que

serão criados.

79 Padrões de projeto criacionais / Factory Method

Page 32: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Problema

Imagine que você está criando uma aplicação de gerencia-

mento de logística. A primeira versão da sua aplicação pode

lidar apenas com o transporte de caminhões, portanto a maior

parte do seu código fica dentro da classe Caminhão .

Depois de um tempo, sua aplicação se torna bastante popular.

Todos os dias você recebe dezenas de solicitações de empresas

de transporte marítimo para incorporar a logística marítima na

aplicação.

Adicionar uma nova classe ao programa não é tão simples se o restante do

código já estiver acoplado às classes existentes.

Boa notícia, certo? Mas e o código? Atualmente, a maior parte

do seu código é acoplada à classe Caminhão . Adicionar

Navio à aplicação exigiria alterações em toda a base de có-

digo. Além disso, se mais tarde você decidir adicionar outro

tipo de transporte à aplicação, provavelmente precisará fazer

todas essas alterações novamente.

80 Padrões de projeto criacionais / Factory Method

Page 33: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Como resultado, você terá um código bastante sujo, repleto de

condicionais que alteram o comportamento da aplicação, de-

pendendo da classe de objetos de transporte.

Solução

O padrão Factory Method sugere que você substitua chamadas

diretas de construção de objetos (usando o operador new )

por chamadas para um método fábrica especial. Não se preo-

cupe: os objetos ainda são criados através do operador new ,

mas esse está sendo chamado de dentro do método fábrica.

Objetos retornados por um método fábrica geralmente são

chamados de “produtos”.

As subclasses podem alterar a classe de objetos retornados pelo

método fábrica.

À primeira vista, essa mudança pode parecer sem sentido: ape-

nas mudamos a chamada do construtor de uma parte do pro-

grama para outra. No entanto, considere o seguinte: agora

você pode sobrescrever o método fábrica em uma subclasse

81 Padrões de projeto criacionais / Factory Method

Page 34: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

e alterar a classe de produtos que estão sendo criados pelo

método.

Porém, há uma pequena limitação: as subclasses só podem re-

tornar tipos diferentes de produtos se esses produtos tiverem

uma classe ou interface base em comum. Além disso, o método

fábrica na classe base deve ter seu tipo de retorno declarado

como essa interface.

Todos os produtos devem seguir a mesma interface.

Por exemplo, ambas as classes Caminhão e Navio devem

implementar a interface Transporte , que declara um método

chamado entregar . Cada classe implementa esse método

de maneira diferente: caminhões entregam carga por terra,

navios entregam carga por mar. O método fábrica na classe

LogísticaViária retorna objetos de caminhão, enquanto o

método fábrica na classe LogísticaMarítima retorna navios.

82 Padrões de projeto criacionais / Factory Method

Page 35: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Desde que todas as classes de produtos implementem uma interface

comum, você pode passar seus objetos para o código cliente

sem quebrá-lo.

O código que usa o método fábrica (geralmente chamado de

código cliente) não vê diferença entre os produtos reais re-

tornados por várias subclasses. O cliente trata todos os pro-

dutos como um Transporte abstrato. O cliente sabe que

todos os objetos de transporte devem ter o método entregar ,

mas como exatamente ele funciona não é importante para o

cliente.

83 Padrões de projeto criacionais / Factory Method

Page 36: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Estrutura

1. O Produto declara a interface, que é comum a todos os objetos

que podem ser produzidos pelo criador e suas subclasses.

2. Produtos Concretos são implementações diferentes da inter-

face do produto.

3. A classe Criador declara o método fábrica que retorna novos

objetos produto. É importante que o tipo de retorno desse mé-

todo corresponda à interface do produto.

Você pode declarar o método fábrica como abstrato para for-

çar todas as subclasses a implementar suas próprias versões

do método. Como alternativa, o método fábrica base pode re-

tornar algum tipo de produto padrão.

84 Padrões de projeto criacionais / Factory Method

Page 37: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Observe que, apesar do nome, a criação de produtos não é a

principal responsabilidade do criador. Normalmente, a classe

criadora já possui alguma lógica de negócio relacionada aos

produtos. O método fábrica ajuda a dissociar essa lógica das

classes concretas de produtos. Aqui está uma analogia: uma

grande empresa de desenvolvimento de software pode ter

um departamento de treinamento para programadores. No en-

tanto, a principal função da empresa como um todo ainda é

escrever código, não produzir programadores.

4. Criadores Concretos sobrescrevem o método fábrica base para

retornar um tipo diferente de produto.

Observe que o método fábrica não precisa criar novas instân-

cias o tempo todo. Ele também pode retornar objetos existen-

tes de um cache, um conjunto de objetos, ou outra fonte.

Pseudocódigo

Este exemplo ilustra como o Factory Method pode ser usado

para criar elementos de interface do usuário multiplataforma

sem acoplar o código do cliente às classes de UI concretas.

85 Padrões de projeto criacionais / Factory Method

Page 38: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Exemplo de diálogo de plataforma cruzada.

A classe base diálogo usa diferentes elementos da UI do usuá-

rio para renderizar sua janela. Em diferentes sistemas opera-

cionais, esses elementos podem parecer um pouco diferentes,

mas ainda devem se comportar de forma consistente. Um

botão no Windows ainda é um botão no Linux.

Quando o método fábrica entra em ação, você não precisa re-

escrever a lógica da caixa de diálogo para cada sistema opera-

cional. Se declararmos um método fábrica que produz botões

dentro da classe base da caixa de diálogo, mais tarde podemos

criar uma subclasse de caixa de diálogo que retorna botões no

estilo Windows do método fábrica. A subclasse herda a maior

parte do código da caixa de diálogo da classe base, mas, gra-

ças ao método fábrica, pode renderizar botões estilo Windows

na tela.

86 Padrões de projeto criacionais / Factory Method

Page 39: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Para que esse padrão funcione, a classe base da caixa de diá-

logo deve funcionar com botões abstratos: uma classe base ou

uma interface que todos os botões concretos seguem. Dessa

forma, o código da caixa de diálogo permanece funcional, in-

dependentemente do tipo de botão com o qual ela trabalha.

Obviamente, você também pode aplicar essa abordagem a ou-

tros elementos da UI. No entanto, com cada novo método

fábrica adicionado à caixa de diálogo, você se aproxima do pa-

drão Abstract Factory. Não se preocupe, falaremos sobre esse

padrão mais tarde.

// A classe criadora declara o método fábrica que deve retornar1

// um objeto de uma classe produto. As subclasses da criadora2

// geralmente fornecem a implementação desse método.3

classclass DialogDialog isis4

// A criadora também pode fornecer alguma implementação5

// padrão do Factory Method.6

abstractabstract methodmethod createButton():Button7

8

// Observe que, apesar do seu nome, a principal9

// responsabilidade da criadora não é criar produtos. Ela10

// geralmente contém alguma lógica de negócio central que11

// depende dos objetos produto retornados pelo método12

// fábrica. As subclasses pode mudar indiretamente essa13

// lógica de negócio ao sobrescreverem o método fábrica e14

// retornarem um tipo diferente de produto dele.15

methodmethod render() isis16

// Chame o método fábrica para criar um objeto produto.17

Button okButton = createButton()18

87 Padrões de projeto criacionais / Factory Method

Page 40: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

// Agora use o produto.19

okButton.onClick(closeDialog)20

okButton.render()21

22

23

// Criadores concretos sobrescrevem o método fábrica para mudar24

// o tipo de produto resultante.25

classclass WindowsDialogWindowsDialog extendsextends Dialog isis26

methodmethod createButton():Button isis27

returnreturn newnew WindowsButton()28

29

classclass WebDialogWebDialog extendsextends Dialog isis30

methodmethod createButton():Button isis31

returnreturn newnew HTMLButton()32

33

34

// A interface do produto declara as operações que todos os35

// produtos concretos devem implementar.36

interfaceinterface ButtonButton isis37

methodmethod render()38

methodmethod onClick(f)39

40

// Produtos concretos fornecem várias implementações da41

// interface do produto.42

classclass WindowsButtonWindowsButton implementsimplements Button isis43

methodmethod render(a, b) isis44

// Renderiza um botão no estilo Windows.45

methodmethod onClick(f) isis46

// Vincula um evento de clique do SO nativo.47

48

classclass HTMLButtonHTMLButton implementsimplements Button isis49

methodmethod render(a, b) isis50

88 Padrões de projeto criacionais / Factory Method

Page 41: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

// Retorna uma representação HTML de um botão.51

methodmethod onClick(f) isis52

// Vincula um evento de clique no navegador web.53

54

55

classclass ApplicationApplication isis56

fieldfield dialog: Dialog57

58

// A aplicação seleciona um tipo de criador dependendo da59

// configuração atual ou definições de ambiente.60

methodmethod initialize() isis61

config = readApplicationConfigFile()62

63

ifif (config.OS == "Windows") thenthen64

dialog = newnew WindowsDialog()65

elseelse ifif (config.OS == "Web") thenthen66

dialog = newnew WebDialog()67

elseelse68

throwthrow newnew Exception("Error! Unknown operating system.")69

70

// O código cliente trabalha com uma instância de um criador71

// concreto, ainda que com sua interface base. Desde que o72

// cliente continue trabalhando com a criadora através da73

// interface base, você pode passar qualquer subclasse da74

// criadora.75

methodmethod main() isis76

thisthis.initialize()77

dialog.render()78

89 Padrões de projeto criacionais / Factory Method

Page 42: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Aplicabilidade

Use o Factory Method quando não souber de antemão os tipos

e dependências exatas dos objetos com os quais seu código

deve funcionar.

O Factory Method separa o código de construção do produto

do código que realmente usa o produto. Portanto, é mais fácil

estender o código de construção do produto independente-

mente do restante do código.

Por exemplo, para adicionar um novo tipo de produto à apli-

cação, só será necessário criar uma nova subclasse criadora e

substituir o método fábrica nela.

Use o Factory Method quando desejar fornecer aos usuários

da sua biblioteca ou framework uma maneira de estender seus

componentes internos.

Herança é provavelmente a maneira mais fácil de estender o

comportamento padrão de uma biblioteca ou framework. Mas

como o framework reconheceria que sua subclasse deve ser

usada em vez de um componente padrão?

A solução é reduzir o código que constrói componentes no fra-

mework em um único método fábrica e permitir que qualquer

pessoa sobrescreva esse método, além de estender o próprio

componente.

90 Padrões de projeto criacionais / Factory Method

Page 43: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Vamos ver como isso funcionaria. Imagine que você escreva

uma aplicação usando um framework de UI de código aberto.

Sua aplicação deve ter botões redondos, mas o framework

fornece apenas botões quadrados. Você estende a classe pa-

drão Botão com uma gloriosa subclasse BotãoRedondo . Mas

agora você precisa informar à classe principal UIFramework

para usar a nova subclasse no lugar do botão padrão.

Para conseguir isso, você cria uma subclasse

UIComBotõesRedondos a partir de uma classe base do fra-

mework e sobrescreve seu método criarBotão . Enquanto

este método retorna objetos Botão na classe base, você faz

sua subclasse retornar objetos BotãoRedondo . Agora use a

classe UIComBotõesRedondos no lugar de UIFramework . E

é isso!

Use o Factory Method quando deseja economizar recursos do

sistema reutilizando objetos existentes em vez de recriá-los

sempre.

Você irá enfrentar essa necessidade ao lidar com objetos gran-

des e pesados, como conexões com bancos de dados, sistemas

de arquivos e recursos de rede.

Vamos pensar no que deve ser feito para reutilizar um objeto

existente:

1. Primeiro, você precisa criar algum armazenamento para man-

ter o controle de todos os objetos criados.

91 Padrões de projeto criacionais / Factory Method

Page 44: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

2. Quando alguém solicita um objeto, o programa deve procurar

um objeto livre dentro desse conjunto.

3. ...e retorná-lo ao código cliente.

4. Se não houver objetos livres, o programa deve criar um novo

(e adicioná-lo ao conjunto de objetos).

Isso é muito código! E tudo deve ser colocado em um único

local para que você não polua o programa com código

duplicado.

Provavelmente, o lugar mais óbvio e conveniente onde esse

código deve ficar é no construtor da classe cujos objetos esta-

mos tentando reutilizar. No entanto, um construtor deve sem-

pre retornar novos objetos por definição. Não pode retornar

instâncias existentes.

Portanto, você precisa ter um método regular capaz de criar

novos objetos e reutilizar os existentes. Isso parece muito com

um método fábrica.

Como implementar

1. Faça todos os produtos implementarem a mesma interface.

Essa interface deve declarar métodos que fazem sentido em

todos os produtos.

92 Padrões de projeto criacionais / Factory Method

Page 45: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

2. Adicione um método fábrica vazio dentro da classe criadora.

O tipo de retorno do método deve corresponder à interface

comum do produto.

3. No código da classe criadora, encontre todas as referências aos

construtores de produtos. Um por um, substitua-os por chama-

das ao método fábrica, enquanto extrai o código de criação do

produto para o método fábrica.

Pode ser necessário adicionar um parâmetro temporário ao

método fábrica para controlar o tipo de produto retornado.

Neste ponto, o código do método fábrica pode parecer bas-

tante feio. Pode ter um grande operador switch que escolhe

qual classe de produto instanciar. Mas não se preocupe, resol-

veremos isso em breve.

4. Agora, crie um conjunto de subclasses criadoras para cada tipo

de produto listado no método fábrica. Sobrescreva o método

fábrica nas subclasses e extraia os pedaços apropriados do có-

digo de construção do método base.

5. Se houver muitos tipos de produtos e não fizer sentido criar

subclasses para todos eles, você poderá reutilizar o parâmetro

de controle da classe base nas subclasses.

Por exemplo, imagine que você tenha a seguinte hierarquia

de classes: a classe base Correio com algumas subclasses:

CorreioAéreo e CorreioTerrestre ; as classes Transporte

93 Padrões de projeto criacionais / Factory Method

Page 46: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

são Avião , Caminhão e Trem . Enquanto a classe

CorreioAéreo usa apenas objetos Avião , o

CorreioTerrestre pode funcionar com os objetos Caminhão

e Trem . Você pode criar uma nova subclasse (por exemplo,

CorreioFerroviário ) para lidar com os dois casos, mas há

outra opção. O código do cliente pode passar um argumento

para o método fábrica da classe CorreioTerrestre para con-

trolar qual produto ele deseja receber.

6. Se, após todas as extrações, o método fábrica base ficar vazio,

você poderá torná-lo abstrato. Se sobrar algo, você pode tor-

nar isso em um comportamento padrão do método.

Prós e contras

Você evita acoplamentos firmes entre o criador e os produtos

concretos.

Princípio de responsabilidade única. Você pode mover o código

de criação do produto para um único local do programa, facili-

tando a manutenção do código.

Princípio aberto/fechado. Você pode introduzir novos tipos de

produtos no programa sem quebrar o código cliente existente.

O código pode se tornar mais complicado, pois você precisa in-

troduzir muitas subclasses novas para implementar o padrão.

O melhor cenário é quando você está introduzindo o padrão

em uma hierarquia existente de classes criadoras.

94 Padrões de projeto criacionais / Factory Method

Page 47: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

Relações com outros padrões

• Muitos projetos começam usando o Factory Method (menos

complicado e mais customizável através de subclasses) e evo-

luem para o Abstract Factory, Prototype, ou Builder (mais fle-

xíveis, mas mais complicados).

• Classes Abstract Factory são quase sempre baseadas em um

conjunto de métodos fábrica, mas você também pode usar o

Prototype para compor métodos dessas classes.

• Você pode usar o Factory Method junto com o Iterator para

permitir que uma coleção de subclasses retornem diferentes

tipos de iteradores que são compatíveis com as coleções.

• O Prototype não é baseado em heranças, então ele não tem

os inconvenientes dela. Por outro lado, o Prototype precisa de

uma inicialização complicada do objeto clonado. O Factory

Method é baseado em herança mas não precisa de uma etapa

de inicialização.

• O Factory Method é uma especialização do Template Method.

Ao mesmo tempo, o Factory Method pode servir como uma

etapa em um Template Method grande.

95 Padrões de projeto criacionais / Factory Method

Page 48: Mergulho nos PADRÕESrefactoring.guru/files/design-patterns-pt-br-demo.pdf · car os conceitos da POO usando vários exemplos comgatos. Este é um diagrama UML da classe. UML é a

345 páginas

do livro completo são omitidas na versão demonstrativa