You are on page 1of 10

Avaliando o Nível de Aderência dos Padrões de Projeto

Operacionais e de Extensão
Patrícia Melo Sales1, Antônio César B. G. da Silva1, Glauco Carneiro1
1
Universidade Salvador (UNIFACS)
Salvador –Ba - Brasil

paty1.melo@gmail.com, cesar_dickinson@hotmail.com,
glauco.carneiro@unifacs.br

Abstract. Design patterns are solutions to well known problems in Software


systems and it’s architectures in the context of Software Engineering. They can
be used to improve software architecture as it evolves and reduce costs
associated with software maintenance activities. This work presents a set of
operational and extension pat-terns adherence level evaluation. It is based on
a patterns requisite verification list. This work proposes the use of this
verification list in Java source code to evaluation and to make possible the
employment of restructuring activities to increase pattern adherence level.

Resumo. Padrões de Projeto são soluções comprovadas para problemas


recorrentes em aplicações e sua arquitetura no âmbito da Engenharia de
Software. Sua utilização possibilita melhorar a arquitetura de software e
reduzir custos nas etapas de manutenção. Este trabalho propõe uma forma de
avaliação do nível de aderência um conjunto de padrões de projeto
operacionais e de extensão. A proposta consiste no uso de uma lista de
verificação de requisitos dos padrões analisados na aplicação alvo. Como
resultado, tem-se a possibilidade de propostas para o aumento de seus níveis
de aderência em projeto de software.

1. Introdução

Segundo Christopher Alexander: cada padrão descreve um problema no


nosso ambiente e o núcleo da sua solução, de tal forma que você possa usar
esta solução mais de um milhão de vezes, sem nunca fazê-lo da mesma
maneira [ALEXANDER, 1977].

Em geral, um padrão tem quatro elementos essenciais:

I. O nome do padrão é uma referência que podemos usar para


descrever um problema de projeto, suas soluções e consequências
em uma ou duas palavras. Dar nome a um padrão aumenta
imediatamente o nosso vocabulário de projeto. Isso nos permite
projetar um nível mais alto de abstração. O nome torna mais fácil
pensar sobre projeto e comunicá-los, bem como os custos e
benefícios envolvidos [ALEXANDER, 1977], [GAMMA e outros,
1995].
II. O problema descreve quando aplicar o padrão. Ele explica o
problema e seu contexto. Pode descrever problemas do projeto
específico, tais como representar algoritmos como objeto. Pode
descrever estruturas de classes ou objetos sintomáticos de um
projeto inflexível. Algumas vezes o problema incluirá uma lista de
condições que devem ser satisfeitas para que faça sentido aplicar o
padrão [ALEXANDER, 1977], [GAMMA e outros, 1995].

III. A solução descreve os elementos que compõem o projeto, seus


relacionamentos, suas responsabilidades e colaborações. A solução
não descreve um projeto completo ou uma implementação em
particular porque um padrão é como um gabarito que pode ser
aplicado em muitas situações diferentes. Em vez disso, padrão
fornece uma descrição abstrata de um problema de projeto e de
como um arranjo geral de elementos (classes e objetos)
[ALEXANDER, 1977], [GAMMA e outros, 1995].

IV. As consequências são os resultados e análise das vantagens e


desvantagens (trades-offs) da aplicação do padrão. Embora as
consequências sejam raramente mencionadas quando descrevemos
decisões de projeto, elas são críticas para a avaliação de alternativas
de projeto e para a compreensão dos custos e benefícios da
aplicação do padrão. As consequências para o software
frequentemente envolvem compromissos de espaço-tempo. Elas
também podem abordar aspectos sobre linguagens e
implementação. Uma vez que a reutilização é frequentemente um
fator no projeto orientado a objetos, as consequências de um padrão
incluem o seu impacto sobre a flexibilidade, a extensibilidade ou a
portabilidade de um sistema [ALEXANDER, 1977], [GAMMA e
outros, 1995].

Muitos padrões são embutidos em nossa mente: nós herdamos ações e ralações que
garantem a nossa sobrevivência. Outros padrões devem ser aprendidos. A habilidade
para observar padrões nos dá a vantagem humana tanto de mudar quanto de adaptar
nosso ambiente.

Um padrão de projeto nomeia, abstrai e identifica os aspectos-chave de uma estrutura


de projeto comum para torná-la útil para a criação de um projeto orientado a objetos
reutilizáveis. O padrão de projeto identifica as classes e instâncias participantes, seus
papéis, colaboração e a distribuição de responsabilidade. Cada padrão de projeto
focaliza um problema ou tópico particular de projeto orientado a objeto. Ele descreve
quando pode ser aplicado, se ele pode ser aplicado em função de outras restrições de
projeto e as consequências, custos e benefícios de sua utilização.

Um dos problemas no desenvolvimento de software é que, frequentemente, o software


tem que ser reorganizado ou refatorado [FOWLER, 1999]. Os padrões de projeto
ajudam a determinar como reorganizar um projeto e podem reduzir o volume de
refatoração que você terá que fazer mais tarde.

O ciclo de vida do software orientado a objeto tem várias fases. Brian Foote identifica-
as como prototipação, expansão e consolidação [FOO, 1992].

A fase da prototipação é meio agitada a medida que o software é trazido a vida através
da prototipação rápida em mudanças incrementais, até que satisfaça um conjunto inicial
de requisitos e atinja a adolescência, neste ponto o software normalmente consiste de
hierarquias de classes que refletem aproximadamente as entidades no domínio do
problema inicial. O principal tipo de reutilização é a da caixa branca, usada em herança.

Uma vez que o software atingiu a adolescência e é colocado em serviço, sua evolução é
governada por duas necessidades conflitantes: (1) o software deve satisfazer mais
requisitos, e (2) o software deve ser mais reutilizável. Comumente os novos requisitos
apresentam novas classes e operações e, talvez, novas hierarquias completas de classes.
O software passa por uma fase de expansão para atender aos novos requisitos. Com
tudo, isto não pode continuar por muito tempo. Eventualmente, o software vai se tornar
muito inflexível “endurecido” para permitir mais mudanças.

As hierarquias de classes não mais correspondem a qualquer domínio de problema. Pelo


contrário refletiram muitos domínios de problemas, e as classes definirão muitas
operações e variáveis de instância não-relacionadas.

Para continuar a evoluir, o software deve ser reorganizado por um processo conhecido
como refatoração [FOWLER, 1999]. Esta é a fase na qual frequentemente se detectam
possíveis frameworks. A refatoração envolve separar as classes em componentes
especiais e componentes de finalidades genéricas, movendo as operações para cima e
para baixo ao longo da hierarquia de classes e racionalizando as interfaces das mesmas.
Esta fase de consolidação produz muitos tipos novos de objetos, frequentemente pela
decomposição de objetos existentes e pela utilização da composição de objetos ao invés
de herança. A necessidade contínua de satisfazer mais requisitos, juntamente com a
necessidade de maior reutilização, faz o software passar por repetidas fases de expansão
e consolidação – de expansão à medida que novos requisitos são atendidos, e
consolidação à medida que o software se torna mais genérico.
expansão

mais requisitos mais reutilização

Prototipação Consolidação

Figura 1Ciclo de vida do sistema [FOO, 1992].


Este ciclo é inevitável. Porém, bons projetistas são cientes de tais mudanças que podem
forçar a refatoração. Bons projetistas também conhecem estrutura de classes e objetos
que ajudam a evitar refatoração, seus projetos são robustos face às mudanças de
requisitos. Uma análise abrangente de requisitos destacará aqueles que são suscetíveis à
mudança durante a vida de software.

2. Avaliando o Nível de Aderência de Padrões Operacionais e de Extensão

No ciclo de vida de uma aplicação tem-se que as atividades de manutenção representam


boa parte dos recursos consumidos tanto do ponto de vista de tempo como financeiro.
As modificações podem envolver:

• Mudanças simples aos erros de código,

• Mudanças mais extensivas para corrigir erros do projeto

• Reescritas drásticas para corrigir erros da especificação ou para acomodar exigências


novas [TURSKI 1981].

É impossível desenvolver aplicação, seja qual for o tamanho que não necessitem ser
mantidos. Sobre o ciclo de vida de um sistema, suas exigências originais serão
modificadas ao refletir necessidades de mudança, o ambiente do sistema mudará, e os
erros obscuros, durante a validação do sistema, emergirão. Porque a manutenção é
inevitável, os sistemas devem ser projetados e executados de modo que os problemas da
manutenção sejam minimizados.

Existem quatro categorias de manutenção de software:

a) Manutenção preventiva.

b) Manutenção adaptável.

c) Manutenção corretiva.

d) Manutenção perfectiva.

A manutenção preventiva significa aquelas mudanças exigidas pelo usuário ou pelo


programador do sistema melhorem o sistema de alguma maneira sem mudar sua
funcionalidade [GRUBB e TAKANG, 2003]. A manutenção adaptável tem o objetivo
de adaptar a aplicação a novos ambientes, tais como sistemas operacionais, ferramentas,
sistemas de gerenciamento de banco de dados e componentes de prateleiras A
manutenção corretiva é a correção de erros de sistema inevitável. A manutenção
perfectiva tem objetivo de melhor à aplicação, através de adição de novas
funcionalidades e aumentar o desempenho, usabilidades ou outros atributos da aplicação
[GRUBB e TAKANG, 2003].

[LIENTZ, SWANSON 1980] indicaram que 17.4% do esforço da manutenção estiveram


categorizados como corretivo na natureza (de "reparos, rotina de emergência eliminando
erros"); 18.2% como adaptável ("acomodação das mudanças às entradas, às limas de
dados, à ferragem e ao software de sistema"); 60.3% como preventiva (do "realces
usuário, documentação melhorada, para a eficiência computacional"); e 4.1% foram
categorizados como "perfectiva”.

As técnicas envolvidas em manter um sistema de software são essencialmente aquelas


usadas para construir o sistema. As novas exigências devem ser formuladas e validadas,
os componentes do sistema devem ser redesenhados e executados, parte ou todo o
sistema devem ser testados. As técnicas usadas nestas atividades são as mesmas que
aquelas usadas durante o desenvolvimento. Não há nenhum truque técnico especial que
devem ser aplicados à manutenção do software.

O mundo real está em constante mudança, e sistemas são feitos para refletir
comportamentos do mundo real [GALL, 1997], logo é necessário que o software
acompanhe as mudanças de requisitos impostas pelo ambiente na qual ele está inserido.
Uma falha em acompanhar essas mudanças pode implicar em perda de qualidade por
parte do software ou até mesmo no fim da sua vida útil.

O envelhecimento de um software é um processo inevitável, mas podemos tentar


entender suas causas, tomar medidas para limitar seus efeitos, temporariamente reverter
os danos causados por ele e se preparar para o dia em que este software não seja mais
viável [LORGE, 1994].

Ainda segundo [LORGE, 1994], existem dois tipos de envelhecimento de software: o


primeiro ocorre quando os responsáveis por um software falham em adaptá-lo para os
novos requisitos, e o segundo ocorre devido ao resultado provocado pela forma como as
mudanças são realizadas no software, mudanças essas que tinham o objetivo de
satisfazer esses requisitos que mudaram.

Os padrões de projeto representam possibilidade de reestruturação da aplicação e


consequente melhoria na sua arquitetura, de forma que possam ser minimizados os
efeitos do envelhecimento de código. A manutenção preventiva através da
reestruturação tem como objetivo melhorar o uso de padrões em uma dada aplicação.
Entretanto, tem sido relatada dificuldades na avaliação do nível de aderência de padrões
e adicionalmente os mecanismos possíveis para melhorá-lo.

Este trabalho propõe, portanto, uma metodologia que atende tais necessidades
considerando somente os padrões de extensão e operacionais. Para isso será utilizada
uma lista de verificação dos padrões, onde através desta, teremos o resultado do nível de
aderência.

3. Padrões Operacionais e de Extensão:

Neste trabalho foi considerada a classificação de [METSKER, 2004] para padrões de


projeto:
Tabela 1: Classificação dos Padrões segundo [METSKER, 2004].

Padrões de Interface: Endereçam contextos nos quais se define ou redefine-se o acesso


aos métodos de uma classe ou de um grupo de classe. Os padrões de interface estão
divididos entre: Adapter, Facade Composite, Bridge [METSKER, 2004].

Padrões de Responsabilidade: Endereçam o contexto nos quais precisamos nos desviar


das regras normais de que a responsabilidade deveria ser distribuída tanto quanto
possível. Os padrões de responsabilidade estão divididos entre: Singleton, Observer,
Mediator, Proxy, Chain of responsability, Flyweight [METSKER,2004].

Padrões de Construção: Permitem a construção de um novo objeto mediante outros mei-


os que não a chamada de um método construtor de classes. Os padrões de construção
estão divididos entre: Builder, Factory Method, Abstract Factory, Prototype, Memento
[METS-KER,2004].
Neste trabalho, iremos estudar os padrões operacionais e de extensão, devido à
disponibilidade de aplicações usando estes padrões e interesse dos autores.
3.1 Padrões de Operação
Os padrões orientados à operação tratam de contextos em que precisamos de mais
de um método, geralmente com a mesma assinatura, para participar de um Projeto.
[METSKER, 2004]. Os padrões de operações considerados são: Template Method,
State, Strategy, Command, Interpreter.
3.2 Padrões de Extensão
Os padrões orientados à extensão tratam de contextos nos quais precisamos
acrescentar comportamento específico para uma coleção de objetos ou acrescentar novos
comportamentos a um objeto sem alterar sua classe. [METSKER, 2004]. Os padrões de
extensão que serão estudados neste trabalho serão: Iterator, Decorator, Visitor
4. Propondo a Lista de Verificação para Avaliação de Padrões de Projeto

Para elaborar a lista de verificação é necessário identificar os requisitos dos padrões


selecionados. O objetivo da lista de verificação é tornar objetiva a avaliação dos padrões
analisados através da sequência didaticamente elaborada para auxiliar o avaliador na
análise do código fonte da aplicação.

4.1 Listas de verificação dos padrões de operação

4.1.1 Padrão Template Method:

Considerando o modelo do padrão, foram levantadas as seguintes condições:

Condição 1. Existe uma especificação indicando quais operações são abstratas?

Condição 2. O padrão está sendo usado para executar partes invariantes de um


algoritmo?

Condição 3. Não existe duplicação no código?

Condição 4. As alterações feitas no código mantêm a integridade do algoritmo e a sua


estrutura geral?

4.1.2 Padrão State:

Considerando o modelo do padrão, foram levantadas as seguintes condições:

Condição 1: O objeto está mudando de comportamento em tempo de execução


dependendo daquele estado?

Condição 2: Prover uma melhor maneira de estruturar o código, diminuindo a


quantidade de condições.

4.1.3 Padrão Strategy:

Considerando o modelo do padrão, foram levantadas as seguintes condições:

Condição 1: Possui interface?

Condição 2: Várias classes relacionadas estão diferentes somente no seu


comportamento?

Condição 3: Precisa de diferentes variantes de um algoritmo?

Condição 4: Esconde dos clientes dados complexos que o algoritmo usa?

4.1.4 Padrão Command:

Considerando o modelo do padrão, foram levantadas as seguintes condições:


Condição 1: Os objetos estão parametrizados com uma ou mais ações a realizar?

Condição 2: Permite estruturar um sistema em volta de operações de alto nível


construído sobre operações primitivas?

Condição 3: Suporta o registro de estados já ocorridos de forma que possam ser


recuperados, quando necessário?

4.1.5 Padrão Interpreter:

Considerando o modelo do padrão, foram levantadas as seguintes condições:

Condição 1: Existem linguagens que necessitam de interpretação?

Condição 2: É possível a representação da sentença da linguagem como arvores


sintáticas abstratas?

4.2 Listas de verificação dos padrões de extensão

4.2.1 Padrão Iterator:

Considerando o modelo do padrão, foram levantadas as seguintes condições:

Condição 1. Existe a manutenção de qualquer informação de estado?

Condição 2. Existe a implementação da interface iteradora?

Condição 3. Existe uma interface definida para acessar os elementos da coleção a classe
Iteradora?

Condição 4. Existe o suporte a Iteração polimórfica?

4.2.2 Padrão Decorator:

Considerando o modelo do padrão, foram levantadas as seguintes condições:

Condição 1. Os componentes e os decoradores descendem de uma classe de


componentes comuns?

Condição 2. É possível alterar ou estender a funcionalidade do componente


substituindo o objeto da estratégia?

Condição 3. Os decoradores são transparentes ao componente?

Condição 4. O objeto de Interface decorator obedece a interface do componente


decorado?

4.2.3 Padrão Visitor:

Considerando os modelos dos padrões, foram aas seguintes condições:


Condição 1. As novas operações são adicionadas separadas das classes?

Condição 2. O Visitor é aceito pela operação da aceitação na árvore do abstract?

Condição 3. Existe uma classe abstrata Visitor (classe mãe) para todos os visitantes de
uma árvore do abstract sintaxe?

Condição 4. As operações estão definidas em cima da classe em que sequer adicionar


novas operações?

Condição 5. Existe um objeto de ConcreteVisitor que atravessa a estrutura do objeto,


visitando cada elemento com o visitante

Condição 6. Existe uma hierarquia de Classes?

4.3. Determinando o peso de cada condição

Cada condição de uma lista de verificação terá um peso, calculado da seguinte forma:
Divide-se 100 pelo número de condições associadas a cada padrão. De cada premissa,
deve ser analisado, de qual (is) esta é dependente ou quais dependem dela. Para cada
uma que ela depende, ela perde 3% da sua importância, e de cada uma que depende
dela, ela ganha 3%. Por exemplo: Num padrão existem 5 premissas. Dividindo por 100
dá 20 para cada. Caso a premissa 1 dependa de duas premissas, seu peso resultante será
de 14%. E cada premissa que a 1 dependeu ganhou 3%, ficando cada uma com 23%.
Exemplo: Template Method:
Template Method Relação entre condições Peso da condição

Condição 1 --------X--------------X------- 25%

Condição 2 -------X--------------X------ 28%

Condição 3 2 22%

Condição 4 -------X--------------X------- 25%

Tabela 1: Peso do padrão Template Method

Segue para demais padrões. Como passo seguinte, será executado um estudo de caso
avaliando o nível de aderência dos padrões estudados

6. Considerações Finais

Um bom entendimento de padrões de projeto permite ao desenvolvedor diminuir custo


com manutenção e reestruturação do código. Com a elaboração da lista de verificação
foi proposto um método para avaliar o nível de aderência do padrão. A partir dos
resultados obtidos há a possibilidade de aumento desse nível, por exemplo, através da
refatoração.
Como trabalho futuro, tem-se a possibilidade de elaboração de listas de verificação para
os outros padrões de projeto.

7. Referencias
[ALEXANDER, 1977] ALEXANDER, C. et al. A Pattern Language. New York:
Oxford University, 1977.
[DYER, MARTIN, 95]Dyer, S., Martin, J. and Zulauf, J. (1995) “Motion Capture White
Paper”, http://reality.sgi.com/employees/jam_sb/mocap/MoCapWP_v2.0.html,
December.
[ECKEL, Bruce. [EBook] Thinking In Patterns - Problem-Solving Techniques Using Ja-
va.
[FOO,1992] BRIAN Foot. A fractal model of the lifecycles of reusable objects.
OOPSLA’ 92 Workshop on Reuse, Readgin, Ma, 1992.
[FOWLER,1999] FOWLER, M. Refactoring- Improving the design of the existing code.
Adisson Wesley. 1999.
[GALL, 1997] HARALD, Gall, MEHDI, Jazayeri, RENÉ, Klosch, GEORGE,
Trausmuth- Software Evolution Observations based on product release. Proceedings
of the International Conference on Software Maintenance. 1997.
[GAMMA e outros]GAMMA, E; HELM, Richard; JOHNSON, Ralph, VLISSIDES,
John. Design Patterns - elements of reusable object-oriented software. Addison-
Wesley: Mas-sachusetts, 1995.
[GRUBB e TAKANG,2003] GRUBB, P. TAKANG, A. Software Maintenance- Con-
cepts and practice. Second Edition World Scientific Publishing CO. 2003.
[HOLUB, 2004] HOLUB, A. Holub on Patterns. Apress Publishers, 2004.
[LIENTZ, SWANSON 1980] LIENTZ B, SWANSON E. Software Maintenance Man-
agement. Addison-Wesley, 1980.
[LORGE, 1994] LORGE, Parnas- Software Aging. ICSE. 1994.
[METSKER, 2004] METSKER, Steven John. Padrões de projeto em Java / Steven John
Metsker. trad. Werner Loe_er. - Porto Alegre : Bookman, 2004.
[TURSKI 1981] TURSKI W., Software Stability, Proc. 6th A CM European Conf. on
Systems Architecture, London, 1981.
[SOURCEFORGE,2006]http://sourceforge.net/project/showfiles.php?group_id=23316
&package_id=16653, acesso em 01/11/2006.Boulic, R. and Renault, O. (1991)
“3D Hierarchies for Animation”, In: New Trends in Animation and Visualization,
Edited by Nadia Magnenat-Thalmann and Daniel Thalmann, John Wiley & Sons ltd.,
England.
[SMITH, 99] Smith, A. and Jones, B. (1999). On the complexity of computing. In
Advances in Computer Science, pages 555–566. Publishing Press.

You might also like