Buscar

Padrões Comportamentais

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 22 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 22 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 22 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

ESTADO DE MINAS GERAIS 
UNIVERSIDADE ESTADUAL DE MONTES CLAROS 
CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS 
CURSO DE BACHARELADO EM SISTEMAS DE 
INFORMAÇÃO 
 
 
Acadêmicos: Alexandre Ferreira Barbosa; Caroline de Abreu e Silva; Gabriel Vinícius Souto 
Abreu; Leandro Augusto Barbosa Leite; Yan Gabriel Silva dos Santos. 
 
 
 
PADRÕES COMPORTAMENTAIS 
 
 
 
A início convém lembrar que, padrões de projetos são soluções já testadas que são dis- 
ponibilizadas no intuito de sua reutilização. Porém, para que esta reutilização ocorra, é neces- 
sário identificar as características de um padrão para visualizar se ele é adequado para soluci- 
onar um devido problema em um projeto. Por isso existem três categorias de padrões, cada 
uma com suas devidas características: a de padrões estruturais, a de padrões criacionais, e, a 
que será aqui explanada, a de padrões comportamentais. 
Os padrões categorizados como comportamentais tratam da responsabilidade entre ob- 
jetos, ou seja, este tipo de padrão designa qual será o nível de interação e divisão da responsa- 
bilidade de cada um dos objetos, fazendo assim com que exista uma comunicação mais fácil e 
flexível entre todas as entidades existentes em um projeto. E dentro destas características, 
compondo a categoria de Padrões Comportamentais estão inseridos os seguintes padrões já 
existentes: Chain Of Responsibility, Command, Iterator, Mediator, Memeto, Observer, State, 
Strategy, Template Method e Visitor. 
 
 
Chain Of Responsibility (Corrente de Responsabilidade) 
 
 
 
O padrão de projeto comportamental Chain Of Responsibility, que também pode ser 
chamado de CoR ou Corrente de Responsabilidade, basicamente possui como intuito a dimi- 
nuição da dependência entre classes e objetos. 
Esta diminuição de dependência é conseguida com o encadeamento de objetos recep- 
tores, de maneira que estes, ao receber objetos de solicitação, decidem se processarão ou se o 
enviarão a solicitação a diante na corrente para o próximo receptor que esteja apto atendê-la. 
Sendo que nesta corrente existe a ocultação de informações entre os objetos, de forma que um 
objeto não conhece as características do outro e assim, quando um objeto a enviar a solicita- 
ção a outro, não sabe qual receptor irá recebê-la e nem qual irá atendê-la. 
 
 
Imagem 1: representação dos objetos encadeados no padrão CoR. 
 
 
Um exemplo aplicado ao dia-a-dia, de como é o funcionamento proposto pelo padrão 
Corrente de Responsabilidade, é a realização de uma ligação ao telemarketing para resolver 
um problema x. Se o primeiro atendente com o qual se é conectado não pode dar uma solução, 
a ligação é transferida adiante para um outro, que pode ou não estar apto a ter uma resolução, 
e caso este não esteja, novamente a ligação será transferida, e assim por diante, até que seja 
encontrado um atendente que possa solucionar o problema. 
Já em vias de algoritmo, o padrão de projeto Chain of Responsibility, propõe e permite 
a aplicação de uma lógica seqüencial, por meio dos encadeamentos de objetos, na resolução 
de problemáticas. Onde será substituída a necessidade e dependência entre IFs e ELSEs den- 
tro dos algoritmos, pela corrente de objetos e classes, que podem então ser menores e mais en- 
xutas, pois serão executadas em sequência. 
Para tanto, se tem então que o CoR é aplicável quando mais de um objeto está apto a 
dar uma solução. Porém, por seu fraco acoplamento, é necessário se ater ao ponto de que a es- 
trutura de encadeamento não tem acesso à informação sobre os objetos que compõem a cor- 
rente, e também os objetos da corrente não possuem informações sobre outros objetos presen- 
tes na corrente. Então sua aplicabilidade está diretamente ligada a quando se possui um proje- 
to onde as classes e objetos podem ter uma regra comum aplicada quando colocadas em cor- 
rente para processarem solicitações e assim darem soluções a elas. 
Command 
 
O Command é um padrão de projeto comportamental que transforma um pedido em 
um objeto independente que contém toda a informação sobre o pedido. Essa transformação 
permite que você parametrize métodos com diferentes pedidos, atrase ou coloque a execução 
do pedido em uma fila, e suporte operações que não podem ser feitas. 
 
 
 
• Problema 
 
Imagine que você está trabalhando em uma nova aplicação de editor de texto. Sua ta- 
refa atual é criar uma barra de tarefas com vários botões para várias operações do editor. Você 
criou uma classe Button que pode ser usada para botões na barra de tarefas, bem como para 
botões genéricos de diversas caixas de diálogo. 
Embora todos esses botões pareçam similares, eles todos devem fazer coisas diferen- 
tes. Aonde você deveria colocar o código para os vários handlers de cliques desses botões? A 
solução mais simples é criar um monte de subclasses para cada local que o botão for usado. 
Essas subclasses conteriam o código que teria que ser executado em um clique de botão. 
 
Não demora muito para perceber que essa abordagem é falha. Teríamos um enorme 
número de subclasses, e isso seria bom caso não arriscasse quebrar o código dentro dessas 
subclasses cada vez que você modificar a classe base Button. 
 
 
 
 
 
 
 
 
 
 
 
 
 Algumas opera- ções, tais como copiar/colar texto, precisariam ser invocadas de 
diversos lugares. Por exem- plo, um usuário poderia criar um pequeno botão “Copiar” na 
barra de ferramentas, ou copiar alguma coisa através do menu de contexto, ou apenas 
apertando ctrl+c no teclado. 
Inicialmente, quando sua aplicação só tinha a barra de ferramentas, tudo bem colocar a 
implementação de várias operações dentro das subclasses do botão. Em outras palavras, ter o 
código de cópia de texto dentro da subclasse ButtonCopy parecia certo. Mas então, quando 
você implementou menus de contexto, atalhos, e outras coisas, você teve que ou duplicar o 
código da operação em muitas classes ou fazer menus dependentes de botões, o que é uma op- 
ção ainda pior. 
 
• Solução 
 
Um bom projeto de software quase sempre se baseia no princípio da separação de inte- 
resses, o que geralmente resulta em dividir a aplicação em camadas. A camada GUI é respon- 
sável por renderizar uma imagem na tela, capturando quaisquer dados e mostrando resultados 
do que o usuário e a aplicação estão fazendo. Contudo, quando se trata de fazer algo impor- 
tante a camada GUI delega o trabalho para a camada inferior da lógica do negócio. 
Dentro do código: um objeto GUI chama um método da lógica do negócio, passando 
alguns argumentos. Este processo é geralmente descrito como um objeto mandando um pedi- 
do para outro. 
O padrão Command sugere que os objetos GUI não enviem esses pedidos diretamente. 
Ao invés disso, você deve extrair todos os detalhes do pedido, tais como o objeto a ser chama- 
do, o nome do método, e a lista de argumentos em uma classe command separada que tem 
apenas um método que aciona esse pedido. 
 
 
O próximo passo é fazer seus comandos implementarem a mesma interface. Essa in- 
terface permite que você use vários comandos com o mesmo remetente do pedido, sem aco- 
plá-lo com as classes concretas dos comandos. 
É suficiente colocar apenas um campo na classe Button base que armazena a referên- 
cia para um objeto command e faz o botão executar aquele comando com um clique. Será im- 
plementado várias classes command para cada possível operação e ligá-los aos seus botões 
em particular, dependendo do comportamento desejado para os botões. 
Os elementos relacionados a mesma operação serão ligados aos mesmos comandos, 
prevenindo a duplicação de código. Como resultado, os comandos se tornam uma camada in- 
termédia conveniente que reduz o acoplamento entre as camadas GUI e de lógica do negócio. 
 
• Analogia com o mundo real 
 
Após uma longa caminhada pela cidade, você chega a um restaurante bacana e senta 
numa mesa perto da janela. Um garçom amigável seaproxima e rapidamente recebe seu pedi- 
do, escrevendo-o em um pedaço de papel. O garçom vai até a cozinha e prende o pedido em 
uma parede. Após algum tempo, o pedido chega até o chef, que o lê e cozinha a refeição de 
acordo. O cozinheiro coloca a refeição em uma bandeja junto com o pedido. O garçom acha a 
bandeja, verifica o pedido para garantir que é aquilo que você queria, e o traz para sua mesa. 
O pedido no papel serve como um comando. Ele permanece em uma fila até que o 
chef esteja pronto para servi-lo. O pedido contém todas as informações relevantes necessárias 
para cozinhar a refeição. Ele permite ao chef começar a cozinhar imediatamente ao invés de 
ter que ir até você para clarificar os detalhes do pedido pessoalmente. 
• Estrutura 
 
1. A classe Remetente (também conhecida como invocadora) é responsável por iniciar os 
pedidos. Essa classe deve ter um campo para armazenar a referência para um objeto 
comando. O remetente aciona aquele comando ao invés de enviar o pedido diretamen- 
te para o destinatário. Observe que o remetente não é responsável por criar o objeto 
comando. Geralmente ele é pré-criado através de um construtor do cliente. 
 
2. A interface Comando geralmente declara apenas um único método para executar o co- 
mando. 
 
3. Comandos Concretos implementam vários tipos de pedidos. Um comando concreto 
não deve realizar o trabalho por conta própria, mas passar a chamada para um dos ob- 
jetos da lógica do negócio. Contudo, para simplificar o código, essas classes podem 
ser fundidas. Os parâmetros necessários para executar um método em um objeto desti- 
natário podem ser declarados como campos no comando concreto. Você pode tornar 
os objetos comando imutáveis ao permitir que apenas inicializem esses campos através 
do construtor. 
 
4. A classe Destinatária contém a lógica do negócio. Quase qualquer objeto pode servir 
como um destinatário. A maioria dos comandos apenas lida com os detalhes de como 
um pedido é passado para o destinatário, enquanto que o destinatário em si executa o 
verdadeiro trabalho. 
 
5. O Cliente cria e configura objetos comando concretos. O cliente deve passar todos os 
parâmetros do pedido, incluindo uma instância do destinatário, para o construtor do 
comando. Após isso, o comando resultante pode ser associado com um ou múltiplos 
destinatários. 
 
 
• Aplicabilidade 
 
• parametrizar objetos com operações. 
• colocar operações em fila, agendar sua execução, ou executá-las remotamente. 
• implementar operações reversíveis. 
 
• Prós e contras 
 
Prós: 
 
• Princípio de responsabilidade única. Você pode desacoplar classes que invocam opera- 
ções de classes que fazem essas operações. 
• Princípio aberto/fechado. Você pode introduzir novos comandos na aplicação sem 
quebrar o código cliente existente. 
• Você pode implementar desfazer/refazer. 
• Você pode implementar a execução adiada de operações. 
• Você pode montar um conjunto de comandos simples em um complexo. 
 
Contras: 
 
• O código pode ficar mais complicado uma vez que você está introduzindo uma 
nova camada entre remetentes e destinatários. 
Visitor 
 
O Visitor é um padrão de projeto comportamental que permite que você separe algo- 
ritmos dos objetos nos quais eles operam. 
 
 
• Problema 
 
Imagine uma equipe que desenvolve uma aplicação que funciona com informações ge- 
ográficas estruturadas em um grafo muito grande. Cada vértice do gráfico pode representar 
uma entidade complexa como uma cidade, mas também coisas mais granulares como indústri- 
as, lugares turísticos, etc. Os vértices estão conectados entre si se há uma estrada entre os ob- 
jetos reais que eles representam. Cada tipo de vértice é representado por sua própria classe, 
enquanto que cada vértice específico é um objeto. Em 
algum momento você tem uma tarefa de implementar a exportação do grafo para o formato 
XML. A solução foi simples: graças ao polimorfismo, não se estava acoplando o código que 
chamava o método de exportação com as classes concretas dos nós. 
Mas não é vantajosa a implementação dessa, pois o código já estava em produção e se- 
ria arriscado quebrá-lo por um possível bug devido às mudanças. 
 
 
 
Além disso, existe o questionamento se faria sentido ter um código de exportação 
XML dentro das classes nó. O trabalho primário dessas classes era somente trabalhar com da- 
dos geográficos. E Após essa funcionalidade ser implementada, talvez fosse necessário ex- 
portar para um formato diferente. Isso forçaria a mudanças das classes novamente. 
 
• Solução 
 
O padrão Visitor sugere que você coloque o novo comportamento em uma classe sepa- 
rada chamada visitante, ao invés de tentar integrá-lo em classes já existentes. O objeto origi- 
nal que teve que fazer o comportamento é agora passado para um dos métodos da visitante 
como um argumento, desde que o método acesse todos os dados necessários contidos dentro 
do objeto. 
Se o comportamento puder ser executado sobre objetos de classes diferentes, exemplo: 
como o caso da exportação XML, a verdadeira implementação vai provavelmente ser um pou- 
co diferente nas variadas classes nó. Portanto, a classe visitante deve definir não um, mas um 
conjunto de métodos, cada um capaz de receber argumentos de diferentes tipos. 
O padrão Visitor usa uma técnica chamada Double Dispatch, que ajuda a executar o 
método apropriado de um objeto sem precisarmos de condicionais pesadas. Ao invés de dei- 
xar o cliente escolher uma versão adequada do método para chamar, delegamos essa escolha 
para os objetos que estamos passando para a visitante como argumentos, já que os objetos sa- 
bem suas próprias classes, eles serão capazes de escolher um método adequado na visitante 
de forma simples. 
Agora, se extrairmos uma interface comum para todas as visitantes, todos os nós exis- 
tentes podem trabalhar com uma visitante que você introduzir na aplicação. Se se depararmos 
mais tarde com a adição de um novo comportamento relacionado aos nós, tudo que precisa- 
mos fazer é implementar uma nova classe visitante. 
https://refactoring.guru/pt-br/design-patterns/visitor-double-dispatch
• Analogia com o mundo real 
 
Imagine um agente de seguros experiente que está ansioso para obter novos clientes. 
Ele pode visitar cada prédio de uma vizinhança, tentando vender apólices para todos que en- 
contra. Dependendo do tipo de organização que ocupa o prédio, ele pode oferecer apólices de 
seguro especializadas: 
• Se for um prédio residencial, ele vende seguros médicos. 
• Se for um banco, ele vende seguro contra roubo. 
• Se for uma cafeteria, ele vende seguro contra incêndios e enchentes. 
• Estrutura 
 
 
1. A interface Visitante declara um conjunto de métodos visitantes que podem receber 
elementos concretos de uma estrutura de objetos como argumentos. Esses métodos po- 
dem ter os mesmos nomes se o programa é escrito em uma linguagem que suporta so- 
brecarregamento, mas o tipo dos parâmetros deve ser diferente. 
 
2. Cada Visitante Concreto implementa diversas versões do mesmo comportamento, fei- 
tos sob medida para diferentes elementos concretos de classes. 
 
3. A interface Elemento declara um método para “aceitar” visitantes. Esse método deve 
ter um parâmetro declarado com o tipo da interface do visitante. 
 
4. Cada Elemento Concreto deve implementar o método de aceitação. O propósito desse 
método é redirecionar a chamada para o método visitante apropriado que corresponde 
com a atual classe elemento. Esteja atento que mesmo se uma classe elemento base 
implemente esse método, todas as subclasses devem ainda sobrescrever esse método 
em suas próprias classes e chamar o método apropriado no objeto visitante. 
 
5. O Cliente geralmente representa uma coleção de outros objetos complexos. Geralmen- 
te, os clientes não estão cientes de todos as classes elemento concretas porque eles tra- 
balham com objetos daquela coleção através de uma interfaceabstrata. 
 
 
• Aplicabilidade 
 
• fazer uma operação em todos os elementos de uma estrutura de objetos complexa 
• limpar a lógica de negócio de comportamentos auxiliares. 
• quando um comportamento faz sentido apenas dentro de algumas classes de uma 
hie- rarquia de classe, mas não em outras. 
 
• Prós e contras 
 
• Princípio aberto/fechado. Você pode introduzir um novo comportamento que pode 
funcionar com objetos de diferentes classes sem mudar essas classes. 
• Princípio de responsabilidade única. Você pode mover múltiplas versões do mesmo 
comportamento para dentro da mesma classe. 
• Um objeto visitante pode acumular algumas informações úteis enquanto trabalha 
com vários objetos. Isso pode ser interessante quando você quer percorrer algum 
objeto de estrutura complexa, tais como um objeto árvore, e aplicar o visitante para 
cada objeto da estrutura. 
• Você precisa atualizar todos os visitantes a cada vez que a classe é adicionada ou re- 
movida da hierarquia de elementos. 
• Visitantes podem não ter seu acesso permitido para campos e métodos privados dos 
elementos que eles deveriam estar trabalhando. 
 
Strategy 
 
 
O Strategy é um padrão de projeto comportamental que permite que você defina uma 
família de algoritmos, incluindo cada algoritmo como uma classe, permitindo que eles possam 
ser trocados e que o algoritmo possa variar independente dos clientes que o utilizam. 
 
• Problema 
 
Quando são criadas muitas funcionalidades para um determinado software, vai 
tornando o software mais complexo e de difícil manutenção, pois necessita mudanças nas 
classes, com isso conflita com os códigos já criados. 
• Solução 
 
O padrão de projeto Strategy propõe que utilize uma classe que faz qualquer coisa es- 
pecífica em diversas maneiras diferentes e retira todos esses algoritmos para classes separadas 
chamadas estratégias. 
 
• Aplicabilidade 
 
• Quando muitas classes relativas diferem apenas no seu comportamento; 
• Quando precisa de variantes de um algoritmo; 
• Prós e contras 
Prós 
• Pode trocar algoritmos usados dentro de um objeto na sua execução. 
• Pode excluir os detalhes de um algoritmo do código que ele usa. 
• Pode trocar a herança por composição. 
 
 
 
Contras 
• Aumento do número de classes no projeto. 
• Os usuários devem saber as diferenças entre as estratégias para selecionar a correta. 
 
 
 
Template Method 
O Template Method é um padrão de projeto comportamental que determina o esquele- 
to de um algoritmo na superclasse, mas permite que as subclasses sobrescrevam em momen- 
tos específicos do algoritmo sem alterar a sua estrutura. 
 
• Problema 
 
 
Quando um software tem muitas classes com códigos parecidos, mesmo eles sendo 
diferentes em todas as classes, seria melhor retirar a duplicação do código, deixando a sua 
estrutura melhor. 
• Solução 
 
 
O padrão de projeto Template Method propõe que parta um algoritmo em uma ordem 
de etapas, modificando essas etapas em métodos, e coloque uma série de chamadas para um 
único método padrão, as etapas podem ser tanto abstratas, ou ter implementação padrão. 
 
 
• Aplicabilidade 
 
 
• Quando o comportamento comum entre subclasses deve ser dividido e concentrado 
numa classe comum para evitar duplicação de código. 
• Quando tem várias classes que contém algoritmos parecidos, pode querer modificar 
todas as classes quando o algoritmo muda. 
 
• Prós e contras 
 
 
Prós: 
• Facilidade de alteração do algoritmo principal. 
• Fundamental para a reutilização de código 
Contras: 
• Se for preciso alterar muitas operações nas subclasses, é necessário reescrever o 
código. 
• Quando mais etapas eles tiverem mais difíceis de manter. 
Iterator 
O Iterator fornece um meio de acessar, sequencialmente, os elementos de um objeto agrega- 
do sem expor a sua representação subjacente . Ele faz composição de um padrão de projeto 
comportamental alguns exemplos claros desse padrão seria lista, pilhas, árvore entre outras, 
sendo que essas possuem certa semelhança estruturalmente. O Iterator é também conhecido 
como cursor. 
 
• Problema: 
O tipo estrutural de dados mais utilizados na programação de modo geral é ape- 
nas contêineres para um certo grupo de objetos. Apesar de parecer simples como um 
lista que nada mais é que uma sequência de objetos representada e armazenada em se- 
quência por isso o nome, em que primeiro elemento na primeira célula, o segundo na 
segunda, e assim por sucessivamente há também coleções mais complexas que possu- 
em um certo grau de nível de armazenamento mais complexo como as pilhas, grafos, 
árvores, pilhas entre algumas outras inúmeras estruturas de dados. 
Porém apesar da complexidade a funçam dessas estruturas mais complexas de- 
vem fornecer de alguma certa maneira os dados armazenados seja como for para que 
possa ser usado de alguma maneira. Como a velocidade e eficiência é levada em conta 
essa estrutura tem que de alguma forma percorrer a estrutura e de preferência de modo 
que não se acesse os elementos já percorridos novamente. 
A alguns casos em que o código cliente que deveria trabalhar com várias cole- 
ções pode não se importar com a maneira que elas armazenam seus elementos. Contu- 
do, uma vez que todas as coleções fornecem diferentes maneiras de acessar seus ele- 
mentos, você não tem outra opção além de acoplar seu código com as classes de cole- 
ções específicas. 
Isso parece uma tarefa fácil se você tem uma coleção baseada numa lista: um 
loop é realizado em todos os elementos da mesma. Mas como fazer a travessia dos ele- 
mentos de uma estrutura de dados complexas sequencialmente, tais como uma árvore? 
Pois em uma determinada situação, você pode apenas precisar percorrer uma árvore 
em profundidade. Em outra, pode haver a necessidade de a percorrer na amplitude ou 
contar com um acesso aleatório aos seus elementos. 
• Solução: 
A ideia principal do 
padrão Iterator é extrair o 
comportamento de travessia 
de uma coleção para um ob- 
jeto separado chamado um 
iterador. 
Além de implemen- 
tar o algoritmo em si, um 
objeto iterador encapsula to- 
dos os detalhes da travessia, 
tais como a posição atual e 
quantos elementos faltam 
para chegar ao fim. Por cau- 
sa disso, alguns iteradores 
podem averiguar a mesma 
coleção ao mesmo tempo, 
independentemente um do 
outro. 
Iteradores implemen- 
tam vários algorítimos de 
travessia. Alguns objetos 
iterador podem fazer a tra- 
vessia da mesma coleção ao 
mesmo tempo. Geralmente, 
os iteradores fornecem um 
método primário para pegar 
elementos de uma coleção. 
Ocliente pode manter 
esse método funcionando até 
que ele não retorne mais 
nada, o que significa que o 
iterador atravessou todos os 
elementos. 
Criando uma nova 
classe iterados , sem mudar 
a coleção você cria de ma- 
neira especial uma travessia 
em uma coleção. Todos os 
iteradores devem implemen- 
tar a mesma interface.Isso 
faz que o código cliente seja 
compatível com qualquer 
tipo de coleção ou qualquer 
algoritmo de travessia desde 
que haja um iterador apro- 
priado. 
 
 
 
• Analogia como o mundo real 
Uma analogia simples a se fazer seria um caso de como percorrer um lugar. 
Como exemplo a cidade de Roma, você pretente visitar alguns pontos turísticos e ou- 
tros pontos de interesse. Para conseguir de uma forma em que você consiga visitar os 
lugares desejados sem que tenha uma perca de tempo e não ande desnecessariamente. 
Por outro lado, você pode comprar um guia virtual na forma de app para seu 
smartphone e usá-lo como navegação. É inteligente e barato, e você pode ficar em lu- 
gares interessantes por quanto tempo quiser. Essa seria uma forma de iteradores já que 
ela faria com que percorrer estruturas complexas de uma forma mais eficiente que no 
caso da visita a cidade de Roma seria os pontos de interesse, percorre-los de forma a 
sanar todos os interesses sem que haja uma percacom tempo, desgaste entre outros fa- 
tores. Há várias maneiras de se percorrer Roma. 
 
• Estrutura 
• Aplicabilidade 
 
 
• Para acessar os conteúdos de um objeto agregado sem expor a sua representa- 
ção interna. 
• Suporte a múltiplos percursos de objetos agregados. 
• O padrão Iterator pode ser usado para que a coleção fique aparentemente sim- 
ples para o usuário final que no caso seria o cliente, no caso de ela estar estru- 
turalmente complexa, essa seria uma aplicabilidade boa para se fazer. 
• Utilize o padrão para reduzir a duplicação de código de travessia em sua apli- 
cação. 
• Utilize o Iterator quando você quer que seu código seja capaz de percorrer di- 
ferentes estruturas de dados ou quando os tipos dessas estruturas são desco- 
nhecidos de antemão. 
• Fornece uma interface uniforme que percorra diferentes estruturas agregadas. 
Interface visualmente mais simples mesmo sendo complexa a estrutura. 
 
 
• Prós e Contras 
Prós: 
• Princípio de responsabilidade única. Você pode limpar o código cliente e as 
coleções ao extrair os pesados algoritmos de travessia para classes separa- 
das. 
• Princípio aberto/fechado. Você pode implementar novos tipos de coleções 
e iteradores e passá-los para o código existente sem quebrar coisa alguma. 
• Você pode iterar sobre a mesma coleção em paralelo porque cada objeto 
iterador contém seu próprio estado de iteração. 
• Pelas mesmas razões, você pode atrasar uma iteração e continuá-la 
quando necessário. 
 
Contras: 
 
 
• Aplicar o padrão pode ser um preciosismo se sua aplicação só trabalha com 
coleções simples. 
• Usar um iterador pode ser menos eficiente que percorrer elementos de 
algumas coleções especializadas diretamente. 
Pattern State 
• Propósito: 
 
Permite um objeto alterar seu comportamento quando o seu estado interno muda. O 
obejto parecerá ter mudado sua classe. No pattern State (padrão de estado) o compor- 
tamento de uma classe muda com base em seu estado, ou seja, a idéia principal do pa- 
drão de Estado é permitir que o objeto altere seu comportamento sem alterar sua clas- 
se. Além disso, ao implementá-lo, o código deve permanecer limpo sem muitas instru- 
ções if / else. 
Para uma codificação prática é composta de três elementos: 
• State: Interface que declara os métodos que poderão ser executados pelos estados 
do objeto; 
• Concrete State: implementa a Interface State para definir cada estado possível 
do objeto; 
• Context: representa o estado atual do objeto, invocando seus métodos. 
 
A melhor maneira de entender este pattern é por meio da exemplificação. Sendo as- 
sim, imagineuma máquina de venda automática, na qual distribui um doce sempre 
que um usuário inserir uma moeda na máquina e pressionar o botão. Sob essa pers- 
pectiva, deduz-se que a máquina terá quatro estados fundamentais: Sem moeda, 
Contém moeda, Dispensar e Sem doces. Esses estados esboçam um situações possí- 
veis para a máquina. Transições de estado moverão a máquina de um estado para 
outro. Por exemplo, se o estado atual da máquina for Sem moeda e, em seguida, um 
usuário digitar uma moeda, uma transição de estado moverá a máquina para o esta- 
do. 
• Problema 
 
 
 
A ideia principal é que, em qualquer dado momento, há um 
número finito de estados que um programa possa estar. Dentro de qualquer estado único, o 
programa se comporta de forma diferente, e o programa pode ser trocado de um estado para 
outro instantaneamente. Contudo, dependendo do estado atual, o programa pode ou não tro- 
car para outros estados. Essas regras de troca, chamadas transições, também são finitas e 
pré determinadas. 
 
 
Máquinas de estado são geralmente implementadas com muitos operadores de condicionais 
(if ou switch) que selecionam o comportamento apropriado dependendo do estado atual do 
objeto. Geralmente esse “estado” é apenas um conjunto de valores dos campos do objeto. 
 
 
• Solução: 
O padrão State sugere que você crie novas classes para todos os estados possíveis de um ob- 
jeto e extraia todos os comportamentos específicos de estados para dentro dessas classes. 
Ao invés de implementar todos os comportamentos por conta própria, o objeto original, 
chamado contexto, armazena uma referência para um dos objetos de estado que representa 
seu estado atual, e delega todo o trabalho relacionado aos estados para aquele objeto. 
O documento delega o trabalho para um objeto de estado. 
 
 
 
 
 
• Analogia com o mundo real 
Um smartphone pode apresentar direfentes estados e funções de acordo com que se 
aciona os seu botão ou sua tela. Alguns desse casos como exemplo pode ser: 
• Quando o telefone está desbloqueado, apertar os botões leva eles a executar várias 
funções. 
• Quando o telefone está bloqueado, apertar qualquer botão leva a desbloquear a t 
• Quando a carga da bateria está baixa, apertar qualquer botão mostra a tela de carrega- 
mento. 
Essa é uma analogia simples do State onde algo é alterado no caso o smartphone por 
algo internamente que nesse caso seria os botões e clicks na tela. 
 
 
• Estrutura: 
 
 
 
• O Contexto armazena uma referência a um dos objetos concretos de estado e 
delega a eles todos os trabalhos específicos de estado. O contexto se comunica 
com o objeto estado através da interface do estado. O contexto expõe um set- 
ter para passar a ele um novo objeto de estado. 
• A interface do Estado declara métodos específicos a estados. Esses métodos de- 
vem fazer sentido para todos os estados concretos porque você não quer alguns 
dos seus estados tendo métodos inúteis que nunca irão ser chamados. 
• Os Estados Concretos fornecem suas próprias implementações para os métodos 
específicos de estados. Para evitar duplicação ou código parecido em múltiplos 
estados, você pode fornecer classes abstratas intermediárias que encapsulam al- 
guns dos comportamentos comuns. Objetos de estado podem armazenar refe- 
rências retroativas para o objeto de contexto. Através dessa referência o estado 
pode buscar qualquer informação desejada do objeto contexto, assim como ini- 
ciar transições de estado. 
• Ambos os estados de contexto e concretos podem configurar o próximo estado 
do contexto e realizar a atual transição de estado ao substituir o objeto estado li- 
gado ao contexto. 
 
• Aplicabilidade 
 
• O comportamento de um objeto depende do seu estado e ele pode mudar seu compor- 
tamento em tempo de execução, dependendo desse estado. 
 
• Operações têm comandos condicionais grandes, de várias alternativas, que dependem 
do estado do objeto. 
• Prós e Contras 
 
Prós: 
 
 
• Organiza o código relacionado a estados particulares em classes separadas. 
• Introduz novos estados sem mudar classes de estado ou contexto existen 
tes. 
• Simplifica o código de contexto ao eliminar condicionais de máquinas de 
estado pesadas. 
 
Contras: 
• Aplicar o padrão pode ser um exagero se a máquina de estado só tem al- 
guns estados ou raramente muda eles.

Continue navegando