Design Patterns Aplicados: Padrões e Refactorings Passo a Passo

Mesmo após estudar e entender padrões de projeto resta um desafio: como aplicá-los em projetos reais, em tempo hábil e sem prejudicar o código legado?

Esse artigo faz parte da revista Java Magazine edição 20. Clique aqui para ler todos os artigos desta edição

Clique aqui para ler esse artigo em PDF.

Design Patterns Aplicados

Padrões e Refactorings Passo a Passo

Mesmo após estudar e entender padrões de projeto resta um desafio: como aplicá-los em projetos reais, em tempo hábil e sem prejudicar o código legado?

Definir da melhor forma padrões de projeto (design patterns) tem sido alvo de debate constante desde a década de 80, quando surgiu o movimento de padrões de projeto de software. A definição original do arquiteto e professor Christopher Alexander no seu livro A Timeless Way Of Building (Oxford University Press, 1979) nos serve bem: “Cada padrão é uma regra de três partes que expressa a relação entre um contexto, um problema e uma solução”.

Sendo assim, para entender um padrão precisamos estudar suas partes: o problema, a solução e o contexto onde é aplicável. Resumidamente, os padrões apresentam soluções para problemas que ocorrem de maneira semelhante, mesmo para projetos em áreas completamente diferentes. No caso de padrões de software orientado a objetos, tais problemas costumam ser a criação de objetos, estruturação de classes, modos de acesso a dados, formas de troca de mensagens e outros que enfrentamos de maneira similar em diversos sistemas. Tendo o problema definido, precisamos analisar o contexto em que ele se manifesta; alguns fatores relacionados ao ambiente, como requisitos não-funcionais, podem determinar se um dado padrão de projeto é aplicável.

Os padrões costumam ser encontrados em catálogos voltados para os contextos e o tipo de problema aos quais se aplicam. Por exemplo, o clássico livro Design Patterns [GoF] fornece um catálogo geral de padrões de projeto orientados a objetos; Patterns of Enterprise Application Architecture [PoEAA] traz padrões para aplicações corporativas, enquanto Core J2EE Patterns [J2EE] tem enfoque nos mecanismos e tecnologias do J2EE.

Padrões via refactoring

Escolher os padrões a serem usados em um projeto no seu início requer conhecimento dos principais catálogos, uma boa definição dos requisitos e algum tempo para montar uma arquitetura de avaliação. Não é fácil balancear esse trabalho, que pode representar o investimento em uma boa base para a construção, ou mesmo levar a atrasos que ameacem o projeto. Cada processo de desenvolvimento tem sua maneira de lidar com tais questões, seja numa “fase de elaboração” preliminar, ou através de alterações constantes e controladas ao longo do projeto. Neste artigo, abordaremos a segunda alternativa.

Introduzir padrões de projeto no código existente pode significar uma longa “cirurgia” no sistema, usando tempo e recursos que poderiam ser gastos na implantação de novas funcionalidades ou correção de erros. Entretanto, evitá-los pode deixar o sistema inflexível ou com defeitos de projeto. Uma solução para esse impasse são os refactorings ("refatorações"), que são melhorias na arquitetura existente, desde alterações de nível mais alto como uma reestruturação de pacotes, até "micro-mudanças" como alterações de nomes de atributos.

As refatorações têm sempre um objetivo claro e uma seqüência de passos bem definida, o que em vários casos possibilita a sua execução automática por IDEs e plug-ins. Refatorações costumam ser registradas em catálogos similares aos de padrões de projetos. O mais famoso e um dos pioneiros é o livro Refactoring – Improving the design of Existing Code, por Martin Fowler [Refactoring]. Há também catálogos que misturam padrões e refatorações, como [J2EE] e [RtP].srrigindo os errros existenesacado agressivo.____________________________________________________

Aplicabilidade de patterns

Patterns geralmente fazem parte dos mecanismos centrais de uma aplicação, e estão diretamente ligados a seus requisitos não-funcionais como performance, escalabilidade, manutenibilidade e segurança. Por exemplo, usar o pattern Flyweight [GoF] pode reduzir muito a quantidade de objetos em memória através do compartilhando eficaz de instâncias, melhorando a performance e a escalabilidade; já a utilização do padrão Bridge [GoF] isola a interface de uma classe da sua implementação, permitindo que as duas evoluam independentemente, aumentando assim a manutenibilidade.

Devemos também considerar os custos da solução adotada. Ao escolher um padrão que aumente a flexibilidade do sistema, pode-se deixar o sistema mais complexo ou mais lento. Algumas perdas geralmente valem a pena, mas subestimar os efeitos colaterais da adoção de patterns é um erro comum ao projetar software (veja um caso extremo no quadro "Arruinado por patterns").

Como regra geral, podemos dizer que o esforço para se aplicar uma solução é proporcional à sua generalidade. Os catálogos trazem uma lista de conseqüências comuns da aplicação de cada padrão, baseando-se na experiência dos autores, o que torna a decisão de adotá-los ou não mais fácil e segura.

Exemplo

Para demonstrar a aplicação de padrões de projeto, abordaremos a criação da parte de acesso a dados de um sistema hipotético de pedidos. Nosso exemplo foca na arquitetura e não em questões como controle de transações, pooling de conexões ou performance de consultas. E os testes de unidade, apesar de essenciais para garantir a segurança dos refactorings, foram propositalmente negligenciados para manter o foco nas decisões de projeto. " [...] continue lendo...

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados