Atenção: por essa edição ser muito antiga não há arquivo PDF para download.Os artigos dessa edição estão disponíveis somente através do formato HTML. Mais Patterns Aplicados Comportamento e Estruturação de Aplicações Aumente o nível de reutilização e a flexibilidade dos seus sistemas com os padrões Command,Composite,Decorator e Template Method No artigo “Patterns aplicados” da edição anterior, vimos como incorporar padrões de projeto (design patterns) a código existente,criando a camada de acesso a dados de uma aplicação. Usamos os padrões Data Acess Obejct (DAO), Factory Method,Abstract Factory e Singleton. Mas nem só de acesso a dados vivem as aplicações. É necessário lidar com requisições de usuários, processamento da lógica de negócio e questão como logging,auditoria e segurança,entre muitos outros aspectos. Neste artigo, são mostrados os padrões Command.Template Method,Composite e Decorator. Como na edição 20,vamos começar com um exemplo simples e acrescentar requisitos que sugiram a introdução dos padrões num contexto de evolução do sistema. Nos quadros “Patterns explicado” são mostrados abordagens alternativas e conseqüências de se adotar cada padrão. Usaremos como exemplo um sistema web de reservas de uma agência de viagens, em que os clientes podem reservar vôos e hotéis e alugar carros no destino. Você notará aqui dois aspectos importantes do uso de padrões de projeto: como eles auxiliam na comunicação entre desenvolvedores, formando um vocabulário expressivo (embora seus nomes, normalmente mantidos em inglês, possam levar ao “portungles”); e como colaboram formando rede de valor agregado que traz flexibilidade e facilidade de manutenção às aplicações. ü Não há dependências entre este e o artigo da edição anterior. Além de ser usado um exemplo completamente diferente, os padrões aqui mostrados podem ser aplicados de forma independente dos apresentados na Edição 20. Basta conhecer os conceitos essenciais de padrões para acompanhar este artigo. Versão inicial Vamos começar com um servlet que atende a todas as solicitações de reserva, sendo os detalhes da solicitação submetidos como parâmetros do request por um formulário web. Esses parâmetros devem incluir o tipo de reserva e o item a ser reservado. Se ocorrer um erro no processamento da reserva, será retornada uma mensagem ao usuário. Em nome da simplicidade as artes do programa que não forem relevantes ao nosso exemplo são resolvidos por métodos estáticos da classe Util,numa classe “mágica que vai nos permitir focar nos aspectos essenciais do sistema (em uma aplicação “real”,esta funcionalidade estaria distribuída em varias classes). Além disso, trechos poucos importantes ou repetidos serão substituídos por reticências. O código inicial do servlet de reservas é mostrado na Listagem 1. Nele a interface Reserva é implementada pelas classes ReservaCarro,ReservaVoo,ReservaHotel. O método agendar() dessas classes faz a reserva do tipo correspondente numa determinada data. Se ocorrer um erro a mensagem poderá ser obtida pelo método getErro() da própria reserva (esta é uma simplificação - em uma aplicação “real” deveriam ser lançadas exceções de negócio”. Veja a organização das classes no diagrama da Figura 1. Figura 1. Classes Iniciais Listagem 1. versão 1:servlet de processamento de reservas public class ServletReservas extends HttpServlet { private static final String PARAM_TIPO = “PARAM_TIPO_RESERVA”; //... Outros parâmetros private static final String ATTR_ERRO = “ATTR_ERRO”; private static final String TIPO_RESERVA_VOO = “RESERVA_VOO”; //... Outros tipos public void doGet(HttpservletRequest request. HttpServletResponse response) throws ServletException. IOException { String erro = null; Cliente cliente = Util.encontractClientePorId( request.getParameter(PARAM_CLIENTEID)); String tipoReserva = request.getParameter(PARAM_TIPO); /* Verificar tipo de reserva */ if (tipoReserva.equals(TIPO_RESERVA_VOO)) { reserva = new ReservaVoo () ; } else if (tipoReserva.equals(TIPO_RESERVA_HOTEL)) { reserva = new ReservaHotel () ; } else if (tipoReserva.equals(TIPO_RESEVA_CARRO)) { if (idade.intValue () >= 18) { reserva = new ReservaCarros () ; }else { erro = “Apenas maiores de 18 anos podem alugar carros.”; } } Calendar data = Util.converteParaCalendar(request.getParameter(PARAM_DATA)); if ( ! reserva,agendar (data) ) { Request.setAttribute(ATTR_ERRO.reserva.getERRO()); } RequestDispatcher rd = request.getRequestDispatcher(“/reservas.jsp”); rd.forward(request.response); } } Versão 2: usando Commend para encapsular operações Como sabemos, grande parte do trabalho das aplicaçoes comerciais é lidar com requisições de usuários. No nosso primeiro exemplo isso é feito usando lógica condicional, o que pode dificultar a codificação de novos requisitos à medida que o sistema cresce. Imagine que, com o crescimento da agência, comecem a surgir novas parcerias,e que toda semana o sistema precise atender a um tipo de reserva como a de restaurantes,passeios turísticos,congressos... Se continuarmos crescendo a árvore de decisão dessa maneira, em pouco tempo teremos uma classe com milhares de linhas. E como a lógica de reservas pode ser arbitrariamente complexa, imagine se as reservas de restaurantes, vôos e hotéis precisassem simultaneamente de correções. Mesmo tendo um bom sistema de controle de versões o sistema se tornaria cada vez mais difícil de manter com essa abordagem. Vamos então encapsular cada solicitação do usuario em um objeto separado, usando o padrão de projeto Command. Depois de separar os tipos de reserva em “comandos”,usaremos uma fábrica para escolher qual comando criar,retirando esta decisão do servlet¹. Assim, conseguimos isolar o servlet que atende aos pedidos dos usuários da lógica envolvida em cada tipo de reserva. A solução é apresentada na Figura 2. O código do servlet (Listagem 2) fica mais simples e não precisará mais ser alterado se forem adicionados novos tipos de reservas. O método extrairParametros() de ServletReservas,omitido na listagem,apenas copia parâmetros do request para o Map de parâmetros do comando a ser executado. Veja mais sobre o usso desse padrão no quadro “Patterns explicado: Command”. ü As referências entre colchetes nos quadros, como [GoF] e [J2EE] indicam catálogos de padrões de projetos. A maioria desses padrões está documenatada, com exemplos, em vários websites (veja links).
Integer idade = cliente.getIdade () ;
Artigo Java Magazine 21 - Mais Patterns Aplicados
Artigo publicado pela Java Magazine edição 21.
Confira outros conteúdos:
Perguntas frequentes
Nossos casos de sucesso
Eu sabia pouquíssimas coisas de programação antes de começar a estudar com vocês, fui me especializando em várias áreas e ferramentas que tinham na plataforma, e com essa bagagem consegui um estágio logo no início do meu primeiro período na faculdade.
Estudo aqui na Dev desde o meio do ano passado!
Nesse período a Dev me ajudou a crescer muito aqui no trampo.
Fui o primeiro desenvolvedor contratado pela minha
empresa. Hoje eu lidero um time de desenvolvimento!
Minha meta é continuar estudando e praticando para ser um
Full-Stack Dev!
Economizei 3 meses para assinar a plataforma e sendo sincero valeu muito a pena, pois a plataforma é bem intuitiva e muuuuito didática a metodologia de ensino. Sinto que estou EVOLUINDO a cada dia. Muito obrigado!
Nossa! Plataforma maravilhosa. To amando o curso de desenvolvimento front-end, tinha coisas que eu ainda não tinha visto. A didática é do jeito que qualquer pessoa consegue aprender. Sério, to apaixonado, adorando demais.
Adquiri o curso de vocês e logo percebi que são os melhores do Brasil. É um passo a passo incrível. Só não aprende quem não quer. Foi o melhor investimento da minha vida!
Foi um dos melhores investimentos que já fiz na vida e tenho aprendido bastante com a plataforma. Vocês estão fazendo parte da minha jornada nesse mundo da programação, irei assinar meu contrato como programador graças a plataforma.
Wanderson Oliveira
Comprei a assinatura tem uma semana, aprendi mais do que 4 meses estudando outros cursos. Exercícios práticos que não tem como não aprender, estão de parabéns!
Obrigado DevMedia, nunca presenciei uma plataforma de ensino tão presente na vida acadêmica de seus alunos, parabéns!
Eduardo Dorneles
Aprendi React na plataforma da DevMedia há cerca de 1 ano e meio... Hoje estou há 1 ano empregado trabalhando 100% com React!
Adauto Junior
Já fiz alguns cursos na área e nenhum é tão bom quanto o de vocês. Estou aprendendo muito, muito obrigado por existirem. Estão de parabéns... Espero um dia conseguir um emprego na área.