SlideShare una empresa de Scribd logo
1 de 49
Descargar para leer sin conexión
ESTADO DE MATO GROSSO
      SECRETARIA DE ESTADO DE CIÊNCIAS, TECNOLOGIA E
                    EDUCAÇÃO SUPERIOR
         UNIVERSIDADE DO ESTADO DE MATO GROSSO
              FACULDADE DE CIÊNCIAS EXATAS
          CAMPUS UNIVERSITÁRIO DE BARRA DO BUGRES
         DEPARTAMENTO DE CIÊNCIA DA COMPUTAÇÃO


                JUNIOR CESAR DA ROCHA




APLICAÇÃO DE PADRÕES DE PROJETO PARA A MELHORIA DA
          MANUTENABILIDADE DE SOFTWARE




                BARRA DO BUGRES – MT
                           2012
JUNIOR CESAR DA ROCHA




APLICAÇÃO DE PADRÕES DE PROJETO PARA A MELHORIA DA
         MANUTENABILIDADE DE SOFTWARE




                         Trabalho de conclusão de curso apresentado ao
                         Departamento de Ciência da Computação,
                         Universidade do Estado de Mato Grosso –
                         UNEMAT, como requisito para obtenção do
                         título de Bacharel em Ciência da Computação,
                         sob orientação do professor Esp. Alexandre
                         Berndt.




               BARRA D BUGRES – MT
                       2012
JUNIOR CESAR DA ROCHA




APLICAÇÃO DE PADRÕES DE PROJETO PARA A MELHORIA DA
          MANUTENABILIDADE DE SOFTWARE




                             Trabalho de conclusão de curso apresentado ao
                             Departamento de Ciência da Computação,
                             Universidade do Estado de Mato Grosso –
                             UNEMAT, como requisito para obtenção do
                             título de Bacharel em Ciência da Computação
                             na área de engenharia de software.




                   Banca Examinadora




      ____________________________________________
           Prof. Esp. Alexandre Berndt - UNEMAT
                          Orientador



      ___________________________________________
    Prof. Me. José Fernandes Torres da Cunha - UNEMAT
                         Convidado



      ____________________________________________
           Prof. Me. Allan Karly Luizi - UNEMAT
                  Indicado pelo Departamento




             Aprovado em: 28 de Junho de 2012
AGRADECIMENTOS


         A Deus, por ter proporcionado todas as condições humanas para que eu pudesse
alcançar este objetivo.
         Aos meus pais e irmãos que, com todo apoio, atenção e carinho, contribuíram para a
conclusão desse trabalho monográfico.
         Ao meu orientador, professor Alexandre Berndt, pelo ensinamento e dedicação
disponibilizados no auxilio à conclusão dessa monografia.
         A todos os meus professores, pela dedicação e ensinamentos disponibilizados nas
aulas. Cada um de forma especial contribuiu para a conclusão desse trabalho e
consequentemente para minha formação profissional.
         Aos amigos e colegas que fiz durante o curso, em especial, Paulo Henrique, Michael
e Rodrigo, por todos os momentos que vivenciamos juntos durante esses quatro anos e meio
de curso.
         À UNEMAT, pela formação que recebi em Ciência da Computação.
“Toda igualdade aparente esconde
uma hierarquia”


                  Masson Cooley
RESUMO

A comunidade de desenvolvimento de software vem adotando cada vez mais os conceitos
propostos pelos padrões de projeto no processo de desenvolvimento de software. Estudos
reportam evidências de que esses padrões causam um impacto positivo na qualidade do
software, mas em alguns casos a adoção de padrões de projeto pode ser inapropriada. Esse
trabalho monográfico relata a origem e os fundamentos dos padrões de projeto, e busca
evidenciar a importância da aplicação de padrões para obter a excelência e a qualidade
desejadas para os sistemas de software. Através de uma pesquisa bibliográfica esse trabalho
evidenciou que a aplicação de padrões de projeto na fase de desenvolvimento do software é
um recurso positivo nos processos futuros de manutenção. Fatores como reusabilidade,
modularidade, uso de interfaces, composição de objetos, baixo acoplamento e alta coesão são
diretamente manipulados através dos padrões de projeto e consequentemente promovem
melhorias na manutenabilidade. Apesar dos benefícios proporcionados, os padrões de projeto
também podem ter efeitos negativos sobre os sistemas de software.


Palavras-chave: Engenharia de software. Padrões de projeto. Manutenabilidade.
ABSTRACT

The software development community has been increasingly adopting the concepts of design
patterns in the process of software development. Studies report evidences that these patterns
cause a positive impact on software quality, but in some cases the adoption of design patterns
may be inappropriate. This monographic work describes the origin and fundamentals of
design patterns and seeks to evidence the importance of applying patterns to obtain the
excellence and quality desired for software systems. Through a bibliographic research this
work suggested that the use of design patterns during software development is a positive
factor in future maintenance processes. Factors such as reusability, modularity, use of
interfaces, object composition, loose coupling and high cohesion are directly manipulated
through the design patterns and they consequently promote enhancements in the
maintainability. Despite the benefits provided, design patterns can also have negative effects
on the software systems.


Keywords: Software engineering. Design patterns. Maintainability.
SUMÁRIO

1 PADRÕES DE PROJETO.................................................................................................. 10

   1.1 Origem ........................................................................................................................... 10

   1.2 Fundamentos ................................................................................................................. 11

   1.3 Benefícios e limitações .................................................................................................. 13

2 PADRÕES DE PROJETO GOF ........................................................................................ 16

   2.1 Classificação .................................................................................................................. 16

   2.2 Padrões de criação ........................................................................................................ 18

       2.2.1 Descrição e objetivos ............................................................................................. 19

       2.2.2 Padrão Abstract Factory ........................................................................................ 20

   2.3 Padrões estruturais ....................................................................................................... 23

       2.3.1 Descrição e objetivos ............................................................................................. 23

       2.3.2 Padrão Adapter....................................................................................................... 25

   2.4 Padrões comportamentais ............................................................................................ 26

       2.4.1 Descrição e objetivos ............................................................................................. 27

       2.4.2 Padrão Strategy ...................................................................................................... 30

3 PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE ....... 34

   3.1 Manutenção de software .............................................................................................. 34

   3.2 Manutenabilidade ......................................................................................................... 35

   3.3 Modularidade ................................................................................................................ 38

       3.3.1 Acoplamento .......................................................................................................... 39

       3.3.2 Coesão ..................................................................................................................... 39

   3.4 Reusabilidade ................................................................................................................ 40

   3.5 Uso de interfaces ........................................................................................................... 41

   3.6 Limitações...................................................................................................................... 42

CONCLUSÃO......................................................................................................................... 43

REFERÊNCIAS ..................................................................................................................... 45
8


                                     INTRODUÇÃO


        O princípio da aplicação de padrões de projeto foi relatado em Alexander (1979),
onde teve início a documentação de padrões aplicados a projetos arquitetônicos. Ao adaptar o
conceito de padrões de projeto ao desenvolvimento de software orientado a objetos, Gamma
et al. (1995) publicou o primeiro catálogo de padrões de projeto de software, que é
considerado hoje uma referência para a compreensão do conceito de padrões de projeto
aplicados ao desenvolvimento de software.
        Padrões de projeto de software são soluções para problemas específicos em um
determinado contexto, onde uma solução resolve um problema de modo que se possa
reutilizar essa mesma solução milhares de vezes sem necessariamente seguir os mesmos
passos (GAMMA et al., 2000). As soluções propostas por esses padrões geralmente são
respostas a problemas que tendem a se repetir na construção de todos os softwares para esse
mesmo domínio do problema (MAGELA, 2006).
        A aplicação de padrões de projeto de software busca melhorar a legibilidade e a
facilidade de entendimento do software, sendo considerado como parte integrante da
documentação do projeto (GAMMA et al., 2000). A partir da aplicação de padrões de projeto
é possível promover reusabilidade, modularidade e manutenabilidade do software, pois os
padrões fornecem soluções mais completas e melhor estruturadas do que uma solução simples
para resolver determinado      problema. Entretanto, pode-se adicionar complexidade
desnecessária no software usando uma solução proposta por padrões (VOKAC et al., 2004).
       Os padrões de projeto representam um avanço na área de engenharia de software, pois
oferecem estruturas para a reutilização de soluções de projeto que já foram testadas e
aprovadas por profissionais experientes. Cada padrão fornece uma solução abstrata para um
problema, permitindo assim desenvolver um projeto em uma notação de mais alto nível
(THOMAZINI NETO, 2006).
        A indústria de desenvolvimento de software necessita cada vez mais de recursos de
engenharia de software para tornar os processos de desenvolvimento e manutenção mais
ágeis, no entanto, existem dificuldades em projetar software orientado a objetos de modo que
sejam estabelecidas condições que promovam flexibilidade suficiente para lidar com o
processo de desenvolvimento e manutenção do software (SHALLOWAY; TROTT, 2004).
Neste contexto os padrões de projeto tem grande influência na manutenabilidade de software,
pois eles elevam o nível de facilidade com que o software pode ser modificado (GAMMA et
al., 2000). A manutenção de software é um processo realizado frequentemente, e pode gerar
9


altos custos, tanto pelo custo direto da manutenção quanto pelo custo da indisponibilidade do
sistema (XIONG; XIE; NG, 2011).
        Esta pesquisa tem como objetivo relatar a origem dos padrões de projeto de software,
seus fundamentos e definições, como eles se aplicam ao desenvolvimento de software, e
apontar as vantagens e limitações da sua utilização no processo de manutenção de software. O
capítulo 1 relata o histórico, os fundamentos e os conceitos teóricos sobre padrões de projeto.
O capítulo 2 descreve os padrões de projeto GOF (Gang of four – termo utilizado na
engenharia de software para fazer referência à publicação do primeiro catálogo de padrões de
projeto de software). E o capítulo 3 busca apontar as vantagens e limitações da aplicação de
padrões de projeto para a melhoria da manutenabilidade de software.
10


                                       CAPÍTULO I


1 PADRÕES DE PROJETO

        Os padrões de projeto de software foram adotados pela engenharia de software a
partir da década de 90. No fundamento destes padrões está a descrição de soluções para
problemas recorrentes no desenvolvimento de software orientado a objetos. Este capítulo
contextualiza os padrões de projeto de software, a seção 1.1 relata os princípios que deram
origem aos padrões de projeto, a seção 1.2 descreve os seus fundamentos e a seção 1.3 faz
uma abordagem sobre os benefícios e as limitações dos padrões de projeto.


1.1 Origem

        O termo padrões de projeto é conhecido inicialmente pelo seu uso em projetos
arquitetônicos. Esse novo conceito foi criado na década de 70, a partir dos trabalhos de
Christopher Alexander, um arquiteto urbano e urbanista que associou o termo padrão às
repetições de formas em arquitetura.
       Alexander (1979) publicou um catálogo com 253 padrões aplicados a projetos
arquitetônicos, o qual passou a ser utilizado como uma alternativa aos métodos tradicionais
empregados pela arquitetura. Nessa publicação houve o questionamento sobre a existência de
uma base objetiva para qualificar determinado projeto como sendo bom ou ruim. Essa base
objetiva surgiu a partir da análise de projetos arquitetônicos e da afirmação de que seria
possível qualificar projetos de arquitetura não apenas como uma questão de gosto, mas a
partir de uma base objetiva e mensurável.
        Sob a ótica de padrões, Alexander (1979) passou a analisar os projetos de cidades,
ruas, entre outros aspectos que envolviam conceitos arquitetônicos, e descobriu que as boas
construções tinham algo em comum. Ao analisar dois projetos arquitetônicos que tivessem
sido elaborados de maneira distinta, observou-se que eles poderiam ser similares na tentativa
de resolver o mesmo problema. Esse foi o conceito que se tornou a base inicial para o
processo de identificação de padrões que persistiam em projetos de boa qualidade.
        Passando de padrões de projetos de arquitetura para padrões de projeto de software,
observa-se os trabalhos de Pree (1995) e Gamma et al. (1995), os quais observaram os
conceitos sobre padrões de projeto e notaram que as soluções e os propósitos apresentados
pelos padrões voltados para projetos arquitetônicos poderiam ser aplicados a projetos de
11


software orientado a objetos, pois visavam à flexibilidade e a reutilização de componentes, os
quais poderiam ser aplicados em sistemas de software.
         Gamma et al. (1995) publicaram as suas primeiras experiências sobre padrões de
projeto de software em um livro intitulado Design Patterns: Elements of reusable object
oriented software. Essa publicação, constituída por 23 padrões, também ficou conhecida
como catálogo GOF. Esta obra é considerada hoje a base fundamental para a compreensão do
conceito de padrões de projetos de software. A obra em questão aplicou a ideia de padrões a
projetos de software, descrevendo os fundamentos e uma estrutura para catalogar os padrões
de projeto.
       Shalloway e Trott (2004) cita o trabalho de Pree (1995) e Gamma et al. (1995) como
as publicações que tiveram uma grande influência na formação de uma comunidade de
estudiosos sobre padrões de projeto. Ambas as publicações foram bem aceitas na área de
desenvolvimento de software, e amplamente utilizadas tanto no campo acadêmico quanto
empresarial.


1.2 Fundamentos

         Gamma et al. (2000) define padrões de projeto como soluções para problemas
específicos em um determinado contexto, onde cada solução resolve um problema de modo
que se possa utilizar essa solução milhares de vezes sem necessariamente seguir o mesmo
caminho.


                       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ável. O padrão de projeto identifica as classes e
                       instâncias participantes, seus papéis, colaborações e a distribuição de
                       responsabilidades. Cada padrão de projeto focaliza um problema ou tópico
                       particular de projeto orientado a objetos. Ele descreve em que situação 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. (GAMMA
                       et al., 2000, p. 19).



       Gamma et al. (2000) descrevem alguns elementos que são essenciais para que um
padrão possa ser compreendido e utilizado em projetos de software. Nessa definição, cada
padrão deve ser caracterizado a partir de quatro elementos básicos: nome, problema, solução e
consequências.
12



                       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 em um nível mais alto de
                       abstração [...]
                       O problema mostra em que situação aplicar o padrão. Ele explica o
                       problema e seu contexto. Pode descrever problemas de projeto específicos,
                       tais como representar algoritmos como objetos. Pode descrever estruturas de
                       classe ou objeto sintomáticas de um problema 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.
                       A solução descreve os elementos que compõe o padrão de projeto, seus
                       relacionamentos, suas responsabilidades e colaborações. A solução não
                       descreve um projeto concreto ou uma implementação em particular porque
                       um padrão é um gabarito que pode ser aplicado em muitas situações
                       diferentes. Em vez disso o padrão fornece uma descrição abstrata de um
                       problema de projeto e de como um arranjo geral de elementos (classes e
                       objetos) o resolve.
                       As consequências são os resultados e análises das vantagens e desvantagens
                       (trade 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 projetos e para a compreensão de
                       custos e benefícios da aplicação do padrão. (GAMMA et al., 2000, p. 19,
                       grifo do autor).


        Fowler (2006) e Magela (2006) apresentam conceitos similares aos de Gamma et al.
(2000), ao definir padrões de projeto de software como sendo soluções usuais e específicas
para a resolução de um ou mais problemas que ocorrem com frequência no processo de
desenvolvimento de sistemas de software. De acordo com Magela (2006, p. 98) um padrão de
projeto representa “[...] a solução para um problema em um contexto específico que tende a se
repetir na construção de todos os softwares para esse mesmo domínio do problema [...]”.
Outra definição é apresentada por Arnout (2004), onde é relatado que:


                       Um padrão de projeto de software é um conjunto de ideias arquiteturais de
                       domínio independente. Tipicamente um padrão descreve as classes
                       envolvidas e a colaboração entre as suas instancias, definidas a partir de
                       sistemas do mundo real. Onde as pessoas podem aprender a aplicá-los em
                       projetos de software em resposta a um problema específico. (ARNOUT,
                       2004, p. 40, tradução nossa).


        Na tentativa de definir uma base sólida a partir da qual os padrões de projeto são
identificados e se tornam úteis para as pessoas, Fowler (2006) descreve que os padrões de
projeto podem ser identificados através da observação de problemas que ocorrem na prática, e
que a descoberta e a definição de novos padrões estão relacionadas à experiência acerca de
determinado problema. Partindo desse princípio, pode-se afirmar que a descoberta de novos
13


padrões se da através da observação de projetos que funcionam e da busca pela essência da
sua solução, esse é um processo que exige grande capacidade de análise e experiência na
abordagem do problema.
         Fowler (2006) e Freeman Erich e Freeman Elizabeth (2009) observaram que os
padrões de projeto podem ser úteis na comunicação entre os membros de uma equipe ou
grupo de trabalho, uma vez que os padrões permitem estabelecer um vocabulário
compartilhado na comunicação entre os membros da equipe. “Quando você se comunica
usando padrões, está fazendo mais do que apenas compartilhar um dialeto” (FREEMAN,
Erich; FREEMAN, Elizabeth, 2009, p. 45). Esse dialeto é a expressão de um conjunto de
características, benefícios e restrições que determinado padrão representa. A consequência da
adoção de padrões nessa relação de comunicação entre as pessoas possibilita uma
compreensão imediata e precisa do problema e das possíveis soluções que estão sendo
propostas para o problema.


1.3 Benefícios e limitações

   A indústria de desenvolvimento de software tem evoluído na última década e vem
utilizando cada vez mais recursos de engenharia de software para tornar os processos de
desenvolvimento e manutenção de softwares mais ágeis. Em contrapartida a essa tendência
existe uma grande dificuldade em projetar software orientado a objetos que seja de fato
reutilizável e flexível o suficiente para lidar com as complexidades inerentes ao processo de
desenvolvimento e manutenção de software (SHALLOWAY; TROTT, 2004). Gamma et al.
(2000, p. 17, grifo do autor) relata que:


                        Projetar software orientado a objetos é difícil, mas projetar software
                        reutilizável orientado a objetos é ainda mais complicado. Você deve
                        identificar objetos pertinentes, fatorá-los em classes no nível correto de
                        granularidade, definir as interfaces das classes, as hierarquias de herança e
                        estabelecer as relações-chave entre eles. O seu projeto deve ser específico
                        para o problema a resolver, mas também genérico o suficiente para atender
                        problemas e requisitos futuros. Também deseja evitar o re-projeto, ou pelo
                        menos minimizá-lo. Os mais experientes projetistas de software orientado a
                        objetos lhe dirão que um projeto reutilizável e flexível é difícil, senão
                        impossível, de obter corretamente da primeira vez. Antes que um projeto
                        esteja terminado, eles normalmente tentam reutilizá-lo várias vezes,
                        modificando-o a cada vez.


       Gamma et al. (2000) associa os padrões de projeto à experiência adquirida a partir de
projetos de software bem sucedidos. Em decorrência disso, os projetistas experientes tendem
14


a reutilizar soluções que já se mostraram eficientes em projetos anteriores. É justamente neste
ponto que os padrões de projeto atribuem vantagem àqueles que fazem uso de padrões para a
solução de diferentes problemas de projeto.
       O desenvolvimento de software envolve uma considerável repetição de recursos, onde
determinadas aplicações podem compartilhar as mesmas necessidades. A ideia de reuso
remete à possibilidade de reutilizar elementos de software que possam ser aplicados em
qualquer projeto que necessite explicitamente dessa funcionalidade. Nesse contexto, os
padrões de projeto abstraem a questão do reuso, atribuindo a possibilidade da reutilização de
padrões Arnout (2004).
       Dentre as razões pelos quais os padrões de projeto atribuem maior qualidade a projetos
de software, Arnout (2004) cita uma lista de benefícios que podem ser aplicados ao
desenvolvimento de software:

         Cada padrão reúne uma fonte de conhecimento definida a partir da experiência em
           projetos de software. Uma das consequências disso é que as pessoas sem
           experiência em desenvolvimento de software podem se beneficiar disso,
           adquirindo experiência mais rapidamente.
         Os padrões contribuem para o desenvolvimento de software de maior qualidade a
           partir da definição de uma estrutura que permita atribuir extensibilidade ao
           software.
         Os padrões definem uma linguagem comum para discussões de troca de
           informações,     tanto    entre   os    próprios    desenvolvedores      quanto    entre
           desenvolvedores e gerentes de projeto.

       Gamma et al. (2000) afirma que projetar sistemas de software de modo que sejam
estabelecidas condições reais de reutilização, extensibilidade e facilidade de manutenção é um
processo bastante complexo. Considerando o desenvolvimento de um projeto de software a
partir do início, é necessário encontrar os objetos corretos, definir interfaces, estabelecer a
hierarquia de herança correta entre as classes, entre outras coisas. Considerando ainda que o
projeto deva apresentar soluções não apenas para o problema em questão, mas também ser
abrangente o suficiente para tratar problemas que possam surgir futuramente, dificilmente
será definido a solução ideal para o problema. Gamma et al. (2000, p. 18) relata que:


                         Os padrões de projeto tornam mais fáceis reutilizar projetos e arquiteturas
                         bem-sucedidas. Expressar técnicas testadas e aprovadas as torna mais
                         acessíveis para os desenvolvedores de novos sistemas. Os padrões de projeto
15

                       ajudam a escolher alternativas de projeto que tornam um sistema reutilizável
                       e a evitar alternativas que comprometam a reutilização. Os padrões de
                       projeto podem melhorar a documentação e a manutenção de sistemas ao
                       fornecer uma especificação explícita de interações de classes e objetos e o
                       seu objetivo subjacente. Em suma, ajudam um projetista a obter mais
                       rapidamente um projeto adequado.


       Uma das características relevantes dos padrões de projeto é justamente a capacidade
que eles têm de apresentar alternativas de reuso de arquiteturas que já foram projetadas,
testadas e se mostraram eficientes, assim, evitando alternativas que comprometam a eficiência
do sistema de software que está sendo projetado (GAMMA et al., 2000).
        Para Shalloway e Trott (2004) os motivos pelo qual a utilização de padrões de
projeto se torna relevante consistem na sua capacidade de reutilizar soluções e de estabelecer
uma terminologia comum. A reutilização de soluções se refere ao fato de reutilizar conceitos a
partir da experiência de projetos já estabelecidos, sem ter que reinventar soluções para os
mesmos problemas. Já a definição de uma terminologia comum permite estabelecer uma base
comum para a comunicação entre os membros de um projeto durante a sua fase de análise e
desenvolvimento.


                       A comunicação e o trabalho em equipe requerem uma base de vocabulário e
                       um ponto de vista comum do problema. Os padrões de projeto fornecem um
                       ponto comum de referência durante a fase de análise e elaboração de um
                       projeto. (SHALLOWAY; TROTT, 2004, p. 99).

        Shalloway e Trott (2004) complementa afirmando que os padrões de projeto também
atribuem maior facilidade de modificação em sistemas de software.


                       A maioria dos padrões de projeto torna o software mais passível de
                       modificação. A razão para tal é que eles são soluções comprovadas pelo
                       tempo, portanto, evoluíram em estruturas que podem tratar mudanças mais
                       prontamente do que as que, muitas vezes, vêm primeiro a mente como uma
                       solução. (SHALLOWAY; TROTT, 2004, p. 99).


        Arnout (2004) questiona a posição de Gamma et al. (2000) em relação à reutilização
de soluções proposta por padrões de projeto. Arnout (2004) questiona que a definição de uma
solução utilizando padrões deve ser adaptada para cada novo contexto, o que significa que o
uso de padrões de projeto não proporciona reusabilidade em termos de código, pois ele
precisa ser adaptado a cada novo problema em particular.
16


                                       CAPÍTULO II


2 PADRÕES DE PROJETO GOF


        Este capítulo faz uma abordagem teórica sobre os padrões de projeto GOF. A seção
2.1 descreve os critérios de classificação dos padrões de projeto GOF. As seções seguintes
descrevem os padrões de acordo com as suas finalidades: a seção 2.2 descreve os padrões de
criação, a seção 2.3 descreve os padrões estruturais e a seção 2.4 descreve os padrões
comportamentais.


2.1 Classificação

        Gamma et al. (2000) classifica os padrões de projeto a partir dos critérios de
finalidade e escopo. A finalidade define o que o padrão faz, um padrão pode ter finalidade de
criação, estrutural ou comportamental. O escopo direciona o padrão a relacionamentos entre
classes ou objetos. Os padrões direcionados a classes lidam com os relacionamentos entre
classes e suas subclasses através do mecanismo da herança, abordando o problema no nível
das classes e definindo soluções em tempo de compilação. Já os padrões direcionados a

objetos lidam com os relacionamentos entre objetos, que podem ser definidos em tempo de

execução através dos recursos de polimorfismo e da composição de objetos.

        O método de classificação de padrões apresentado em Gamma et al. (2000) são

fundamentais para a compreensão dos inúmeros padrões de projeto existentes, além de
auxiliar na curva de aprendizagem e na descoberta de novos padrões. O Quadro 1 apresenta os
padrões de projeto de acordo com as suas classificações.
17


                      Quadro 1 – Classificação dos padrões de projeto
                                                     Finalidade
                              De criação          Estrutural          Comportamental
                           Factory Method      Adapter (class)     Interpreter
                  Classe
                                                                   Template Method
                           Abstract Factory    Adapter (object)    Chain of Responsability
                           Builder             Bridge              Command
         Escopo            Prototype           Composite           Iterator
                           Singleton           Decorator           Mediator
                  Objeto                       Facade              Memento
                                               Flyweight           Observer
                                               Proxy               State
                                                                   Strategy
                                                                   Visitor
                           Fonte: Adaptado de Gamma et al. (2000, p. 26)


        Em relação ao escopo o Quadro 1 mostra dois conjuntos de padrões, um direcionado
a classe e outro direcionado a objeto. Em relação à finalidade (propósito), existem três
conjuntos de padrões com diferentes finalidades: de criação, estrutural e comportamental.
        Os padrões de criação no escopo de classe delegam o processo de criação de objetos
para as subclasses, enquanto que os de escopo de objeto postergam esse processo para outros
objetos. Os padrões estruturais no escopo de classe utilizam a herança para compor classes,
enquanto que os de escopo de objeto descrevem estruturas para relacionar objetos. E os
padrões comportamentais no escopo de classe utilizam a herança para descrever algoritmos e
fluxos de controle, enquanto que aqueles voltados para objetos descrevem como um grupo de
objetos se relaciona e compartilha a execução de tarefas (GAMMA et al., 2000).
        A Figura 1 ilustra graficamente as relações entre os padrões de projeto de acordo
com o modo que os padrões mencionam seus inter-relacionamentos.
18


                   Figura 1 – Relacionamento entre os padrões de projeto




                                Fonte: Gamma et al. (2000, p. 26)


2.2 Padrões de criação

        Conforme exposto na seção 2.1, os padrões de projeto podem ser classificados de
acordo com a sua finalidade e escopo. Gamma et al. (2000) descreve que os padrões de
criação têm por finalidade tornar o sistema independente de como os objetos são criados e
compostos, a partir da abstração do processo de instanciação dos objetos. Os padrões de

criação com escopo de classe utilizam a herança para definir as classes que são instanciadas,

enquanto que os padrões de criação com escopo de objeto utilizam fortemente a composição

para delegar o processo de criação de objetos (GAMMA et al., 2000).
19


           Sistemas de software se tornam complexos a medida que evoluem, e necessitam de
mecanismos que forneçam flexibilidade para gerir as modificações no processo de
manutenção. Os padrões de criação contribuem no sentido de promover a composição de
objetos e não apenas o uso da herança (GAMMA et al., 2000).


                        Os padrões de criação se tornam importantes à medida que os sistemas
                        evoluem no sentido de depender mais da composição de objetos do que da
                        herança de classes. Quando isso acontece, a ênfase se desloca da codificação
                        rígida de um conjunto fixo de comportamentos para a definição de um
                        conjunto menor de comportamentos fundamentais, os quais podem ser
                        compostos em qualquer número para definir comportamentos mais
                        complexos. Assim, criar objetos com comportamentos particulares exige
                        mais do que simplesmente instanciar uma classe. (GAMMA et al., 2000, p.
                        91).


           Nesse contexto, o sistema passa a conhecer os seus objetos a partir de classes
abstratas e não apenas por classes concretas. Consequentemente, os padrões de criação
atribuem flexibilidade e permitem que o sistema seja definido através de objetos que variam
amplamente em estrutura e funcionalidade.
           Os padrões de criação com escopo de objeto são Singleton, Prototype, Builder e
Abstract Factory. Em relação ao escopo de classe existe um único padrão, o Factory Method
(GAMMA et al., 2000). Para um melhor entendimento da classificação por criação, o padrão
Abstract Factory será relatado de forma detalhada mais adiante.


2.2.1 Descrição e objetivos

           O padrão Singleton estabelece uma maneira de garantir que uma classe tenha
somente uma instância a partir da definição de um único ponto de acesso a classe. De acordo
com Gamma et al. (2000) o Singleton é útil quando há necessidade de apenas uma instância

de uma classe e essa instância tiver que dar acesso aos clientes através de um único ponto, ou

quando essa instância tiver que ser extensível através de subclasses, possibilitando aos

clientes usar uma instância estendida sem alterar o seu código.
           O padrão Prototype, segundo Gamma et al. (2000), objetiva a redução do número de
classes e a especificação dos tipos de objetos a serem criados usando uma instância protótipo,
onde novos objetos podem ser criados a partir de cópias desse protótipo. O Prototype pode ser
aplicado quando as instâncias de uma classe puderem ter poucas combinações diferentes de

estados.
20


        O padrão Builder é descrito por Gamma et al. (2000) como um recurso para separar a
construção de um objeto complexo da sua representação, de modo que o mesmo processo de
construção possa criar diferentes representações. O padrão pode ser adotado sempre que a

lógica para a criação de um objeto complexo for independente das partes que compõem o

objeto. O processo de construção deve permitir diferentes representações para o objeto que é

construído.


2.2.2 Padrão Abstract Factory

        O padrão Abstract Factory é responsável por fornecer uma interface para criação de
famílias de objetos que se relacionam ou dependem um do outro sem a necessidade de
especificar suas classes concretas (FREEMAN, Erich; FREEMAN, Elizabeth, 2009).
        A família de objetos criada a partir do padrão Abstract Factory é definida por
Gamma et al. (2000) como uma família de objetos-produto, que é um conjunto de objetos que
de algum modo se relacionam para atingir um determinado objetivo. O padrão Abstract
Factory define justamente um tipo abstrato para criar uma família de produtos relacionados.
Na definição de Gamma et al. (2000), produtos são objetos concretos que atingem um
objetivo específico do sistema, definidos por subclasses de um tipo abstrato.


                       O padrão Abstract Factory ajuda a controlar as classes de objetos criadas por
                       uma aplicação. Uma vez que a fábrica encapsula a responsabilidade e o
                       processo de criar objetos-produto, isola os clientes das classes de
                       implementação. Os clientes manipulam as instâncias através das suas
                       interfaces abstratas. Nomes de classes-produto ficam isolados na
                       implementação da fábrica concreta. (GAMMA et al., 2000, p. 98).


        A vantagem do padrão Abstract Factory é que ele permite definir uma regra de
negócio ao mesmo tempo em que promove baixo acoplamento, tornando o sistema pouco
dependente das implementações concretas. Gamma et al. (2000) recomenda o uso do padrão
Abstract Factory sempre que for identificado alguma das características a seguir:

        Houver independência de como os produtos de um sistema são criados.

        O sistema tiver de ser configurado como um produto de uma família de múltiplos

         produtos.
21


        Uma família de objetos for projetada para ser usada em conjunto, e houver a

         necessidade de garantir esta restrição;

        Um ponto-chave do padrão Abstract Factory consiste em estabelecer condições para
definir um conjunto de classes de produtos de modo que somente suas interfaces sejam
responsáveis pelo controle dos recursos, e não suas implementações concretas (GAMMA et
al., 2000). A Figura 2 exemplifica a aplicação do padrão Abstract Factory.
                             Figura 2 – padrão Abstract Factory




                                  Fonte: Gamma et al. (2000, p. 96)


        O diagrama da Figura 2 mostra o conceito geral do padrão Abstract Factory. A partir
da análise desse diagrama é possível compreender a aplicabilidade do padrão. Como pode ser
observado no diagrama, são definidos grupos de famílias de classes que implementam a
mesma interface. Gamma et al. (2000) define uma família de classes quando há um conjunto
de classes concretas que herdam características de uma mesma classe abstrata.
       Gamma et al. (2000) relata que a classe AbstractFactory atua como uma fábrica
abstrata que contém apenas as assinaturas dos métodos que instanciam fábricas concretas.
Cada fábrica concreta é responsável por definir um conjunto específico de recursos do
sistema, ela reúne um conjunto de produtos que devem fazer parte do sistema em um
determinado contexto. Uma fábrica abstrata permite implementar uma ou várias fábricas
concretas, onde cada qual define o uso de um conjunto de produtos para contextos diferentes.
Com isso, a possibilidade de definir uma nova regra ou criar uma nova funcionalidade se
torna um processo bem definido.


                       Uma fábrica abstrata nos da uma interface para criar uma família de
                       produtos. Ao escrever o código que usa essa interface, desvinculamos nosso
22

                         código da fábrica real que cria os produtos. Isso nos permite implementar
                         uma variedade de fábricas que fazem produtos para contextos diferentes –
                         como regiões diferentes, sistemas operacionais diferentes ou aparências
                         diferentes. Como nosso código é desvinculado dos produtos reais, podemos
                         substituir fabricas diferentes para obter comportamentos diferentes.
                         (FREEMAN, Erich; FREEMAN, Elizabeth, 2009, p. 135).


       O papel das fábricas concretas é justamente definir regras de negócio. O diagrama da
Figura 2 mostra duas fábricas concretas, ConcreteFactory1 e ConcreteFactory2, que definem
regras a partir da seleção de um conjunto de produtos, que juntos atendem a um propósito
específico do sistema. No entanto, no nível das fábricas concretas o sistema trata das
colaborações entre classes ainda de modo abstrato, pois as fábricas concretas apenas definem
a criação de um conjunto de produtos que visam atender a um objetivo ou regra de negócio.
Uma vez que o código fica desvinculado dos produtos concretos, pode-se criar ou modificar
fábricas para obter comportamentos diferentes (GAMMA et al., 2000).
           Fábricas concretas apenas cuidam da instanciação de objetos-produto, o processo de
criação de produtos concretos fica a cargo das classes de produtos, as quais podem partir
desde níveis concretos a níveis abstratos, onde através da herança criam-se classes de
produtos concretos. No diagrama da Figura 2, as classes AbstractProductA e
AbstractProductB cuidam da implementação de produtos concretos. Segundo Gamma et al.
(2000) definir classes que atuam como produtos permite codificar regras de negócio
específicas, e isso facilita a reutilização das funcionalidades do produto, sendo que os
produtos são compostos em fábricas concretas a medida que a aplicação exige os recursos do
produto.
           Do diagrama da Figura 2 a classe Client são os objetos que interagem com alguma
fábrica abstrata. Os clientes apenas necessitam saber qual tipo de abstração estão usando, pois
as subclasses do tipo abstrato tratam das implementações concretas, mantendo os clientes
vinculados apenas aos tipos abstratos. As fábricas concretas têm conhecimento apenas dos
produtos instanciados por elas e as instancias da classe Client não podem fazer referências
diretas para os produtos ou fábricas concretas, há apenas a possibilidade de manter referências
para a fábrica abstrata. A vantagem desse recurso é que novas fábricas ou produtos podem ser
definidos sem qualquer impacto no objeto cliente. Isso torna a codificação flexível e garante
coesão e acoplamento (GAMMA et al., 2000).
           Apesar das vantagens do padrão Abstract Factory, existem algumas desvantagens na
sua utilização. Segundo Gamma et al. (2000) o padrão dificulta o suporte a novos tipos de
23


produtos em consequência da complexidade de extensão de fábricas abstratas e criação de
novos tipos de produtos.


                        Estender fábricas abstratas para produzir novos tipos de Produtos não é fácil.
                        Isso se deve ao fato de que a interface de AbstractFactory fixa o conjunto de
                        produtos que podem ser criados. Suportar novos tipos de produto exige
                        estender a interface da fábrica, o que envolve mudar a classe
                        AbstractFactory e todas as suas subclasses. (GAMMA et al., 2000, p. 98).


         No relato de Gamma et al. (2000) a interface da fábrica abstrata fixa um conjunto de
produtos que podem ser criados, em consequência disso o suporte a novos tipos de produto
exige que a interface da fábrica abstrata seja estendida.

2.3 Padrões estruturais

         De acordo com Gamma et al. (2000) os padrões de projeto estruturais tem a função
de definir o modo como classes e objetos são compostos para formar estruturas maiores. No
escopo de classe os padrões estruturais utilizam a herança para compor interfaces. Enquanto
que no escopo de objeto os padrões descrevem estratégias para compor objetos em tempo de
execução. Os padrões estruturais atribuem flexibilidade ao sistema, obtida principalmente
pela sua capacidade de compor objetos em tempo de execução.
         Os padrões de projeto classificados como estruturais são: Adapter, Bridge,
Composite, Decorator, Facade, Flyweight e Proxy (GAMMA et al., 2000). O padrão Adapter
será explicado de forma detalhada para demonstrar a aplicabilidade dos padrões classificados
como estruturais.


2.3.1 Descrição e objetivos

         Os padrões de projeto estruturais têm por objetivo descrever métodos de organização
de classes e objetos, atribuindo ao sistema maior flexibilidade de adaptação a mudanças e
operações de manutenção (GAMMA et al., 2000).
         O padrão Bridge permite realizar abstrações em objetos, de modo que o objeto se
torne independente da sua implementação concreta, e permite que o objeto possa variar
independente da sua implementação. Uma abstração pode ser realizada através do uso da

herança, onde uma classe abstrata define uma interface para abstrair classes em uma
24


hierarquia, e as subclasses concretas as implementam de maneiras diferentes (GAMMA et al.,
2000).
         O padrão Composite é outro exemplo de um padrão estrutural. Segundo Gamma et
al. (2000), o padrão descreve como construir hierarquias de classes em estruturas de árvores,
esse mecanismo permite definir objetos simples e compostos para criar hierarquias
arbitrariamente complexas. Desse modo, o padrão é aplicado para representar hierarquias de
objetos clientes que necessitam tratar um conjunto de objetos em estruturas compostas e de
modo uniforme. Isso permite que os objetos clientes sejam capazes de ignorar a diferença
entre objetos individuais e a composição de um conjunto de objetos.
         Segundo Gamma et al. (2000) O padrão Decorator visa atribuir responsabilidades
adicionais a um objeto em tempo de execução ao fornecer alternativas para extensões de
funcionalidades.


                       [...] Os Decorators fornecem uma alternativa flexível ao uso de subclasses
                       para extensão de funcionalidades [...] Algumas vezes queremos acrescentar
                       responsabilidades a objetos individuais, e não a toda uma classe. Por
                       exemplo, um toolkit para construção de interfaces gráficas de usuário deveria
                       permitir a adição de propriedades, como bordas, ou comportamentos, como
                       rolamento, para qualquer componente da interface do usuário. (GAMMA et
                       al., 2000, p. 170).


         O padrão Facade (fachada) tem por objetivo fornecer uma interface única para os
recursos de um subsistema, abstraindo o acesso aos recursos internos do subsistema. Ao
aplicar o padrão define-se uma interface de alto nível que torna o subsistema mais fácil de ser
utilizado (GAMMA et al., 2000).


                       Estruturar um sistema em subsistemas ajuda a reduzir a complexidade. Um
                       objetivo comum de todos os projetos é minimizar a comunicação e as
                       dependências entre subsistemas. Uma maneira de atingir esse objetivo é
                       introduzir um objeto facade (fachada), o qual fornece uma interface única e
                       simplificada para os recursos e facilidades mais gerais de um subsistema.
                       (GAMMA et al., 2000, p. 170, grifo do autor).


         O padrão Flyweight, como o próprio nome sugere, tem por objetivo fornecer uma
estrutura para o compartilhamento de objetos leves e que geralmente se encontram em grande
número em uma aplicação (GAMMA et al., 2000).
         O padrão Proxy, segundo Gamma et al. (2000), fornece um objeto substituto
responsável por registrar a localização de outro objeto de modo que o acesso a este outro
25


objeto possa ser controlado. Proxy pode ser aplicado sempre que há necessidade de uma

referência mais variável do que um simples apontador para um objeto. O padrão Proxy
também pode ser adaptado para incluir o padrão Flyweight em situações onde várias cópias de
um objeto complexo devem existir.


2.3.2 Padrão Adapter

        De acordo com Gamma et al. (2000) o padrão Adapter permite que classes com
interfaces incompatíveis possam atuar em conjunto através de uma interface única, que
permite a um objeto utilizar os serviços de outros objetos com interfaces diferentes. O padrão
fornece um adaptador que realiza a comunicação, proporcionando ao sistema um mecanismo
de adaptação a mudanças.


                       [...] Em geral, um Adapter faz com que uma interface adaptada (em inglês,
                       adaptee) seja compatível com outra, dessa forma fornecendo uma abstração
                       uniforme de diferentes interfaces. A classe adaptadora (adapter) atinge esse
                       objetivo herdando, privadamente, de uma classe adaptada. O adapter, então,
                       exprime sua interface em termos da interface da classe adaptada. (GAMMA
                       et al., 2000, p. 139).


        Gamma et al. (2000) subdivide o padrão Adapter em adaptadores de objeto e
adaptadores de classe. Basicamente, um adaptador de objeto utiliza a composição de objetos
para situações em que o adaptador contenha dois ou mais objetos que necessitam ser
adaptados para implementar uma interface alvo, enquanto que um adaptador de classe usa o
recurso de herança múltipla para adaptar duas interfaces incompatíveis. As Figuras 3 e 4
mostram os diagramas que representam adaptadores de classe e de objeto.
                           Figura 3 – Padrão Adapter para classes




                                Fonte: Gamma et al. (2000, p. 143)
26


                           Figura 4 – Padrão Adapter para objetos




                                Fonte: Gamma et al. (2000, p. 143)


         Ao observar as Figuras 3 e 4 é possível notar que ambos os adaptadores, de classe e
de objeto, tem um princípio em comum, realizar o acoplamento da classe Target (alvo),
chamada pelo cliente, à classe Adaptee (adaptada). Isso implica que o cliente não sofrerá
alterações a medida que necessita se relacionar com a classe Target. Supondo que a interface
Adaptee realize algo que o cliente deseja, porém Target e Adaptee sejam interfaces
incompatíveis, a classe Adapter realiza essa comunicação (GAMMA et al., 2000).
         A medida que o sistema se torna complexo e o nível de interação entre as classes
cresce, os adaptadores de classe e de objeto assumem características diferentes. Os
adaptadores de classe fazem uso de classes concretas para adaptar duas classes incompatíveis,
onde Adapter é geralmente uma subclasse da classe adaptada, denominada Adaptee. Um
adaptador de classe tem capacidade de substituir apenas os comportamentos da classe
adaptada e não funciona quando há necessidade de adaptar simultaneamente as suas
subclasses. Em contrapartida, os adaptadores de objeto permitem que uma única classe,
denominada Adapter, manipule várias classes simultaneamente, a classe adaptada,
denominada Adaptee, e todas as suas subclasses. A medida que o número de classes que
implementam a classe adaptada cresce, a capacidade do adaptador de objeto diminui, pois o
adaptador deve ter referências a todas as subclasses concretas da classe adaptada (GAMMA et
al., 2000).


2.4 Padrões comportamentais

         De acordo com Gamma et al. (2000) os padrões de projeto comportamentais tem a
função de encapsular o comportamento de classes e objetos de modo que os seus níveis de
complexidade sejam minimizado. Os padrões comportamentais fornecem flexibilidade ao
27


sistema em função da sua capacidade de definir comportamentos a objetos em tempo de
execução. No escopo de classe, os padrões comportamentais descrevem estratégias de
relacionamentos entre classes e utilizam a herança para distribuir o comportamento entre os
objetos. No escopo de objeto os padrões descrevem estratégias para definir objetos que
necessitam de cooperação para a execução de tarefas que exigem a interação mútua de um
conjunto de objetos.


                       Os padrões comportamentais se preocupam com algoritmos e a atribuição de
                       responsabilidades entre objetos. Os padrões comportamentais não descrevem
                       apenas padrões de objetos ou classes, mas também os padrões de
                       comunicação entre eles. Esses padrões caracterizam fluxos de controle
                       difíceis de seguir em tempo de execução. Eles afastam o foco do fluxo de
                       controle para permitir que você se concentre somente na maneira como os
                       objetos são interconectados. (GAMMA et al., 2000, p. 139).


        Os padrões de projeto classificados como comportamentais são: Interpreter,
Template Method, Chain of Responsibility, Command, Iterator, Mediator, Memento,
Observer, State, Strategy e Visitor (GAMMA et al., 2000).


2.4.1 Descrição e objetivos

        O padrão Chain of Responsibility tem como objetivo definir regras de acoplamento
fraco entre objetos remetentes e receptores, fornecendo a vários objetos a oportunidade de
atender uma mesma solicitação. Seguindo esse princípio, determinada solicitação é passada ao
longo de uma cadeia de objetos até que um deles esteja apto a atender a solicitação. De acordo
com Gamma et al. (2000, p. 211-212) o padrão Chain of Responsibility permite:


                       [...] enviar solicitações implicitamente para um objeto através de uma cadeia
                       de objetos candidatos. Qualquer candidato pode satisfazer a solicitação
                       dependendo de condições em tempo de execução. O número de candidatos é
                       aberto e você pode selecionar quais candidatos participam da cadeia em
                       tempo de execução.


        Chain of Responsibility pode ser aplicado quando há um conjunto de objetos aptos a
tratar uma solicitação, porém apenas um dentre estes objetos é o suficiente para tratar a
solicitação e este pode ser definido em tempo de execução. A medida que determinado objeto
emite uma solicitação sem especificar explicitamente o receptor, a solicitação se propaga ao
28


longo de uma cadeia até que determinado objeto assuma dinamicamente a responsabilidade

de atender a solicitação (GAMMA et al., 2000).
         O padrão Command tem por objetivo encapsular solicitações como objetos,
permitindo que os objetos clientes sejam parametrizados com diferentes solicitações. Usos
conhecidos do padrão são as operações de copiar e desfazer presentes em um grande número
de aplicativos. Em resumo o padrão define uma estrutura de comandos para a implementação

de operações que podem ser desfeitas em tempo de execução (GAMMA et al., 2000).
         O padrão Interpreter está associado à representação de gramáticas. De acordo com
Gamma et al. (2000) o padrão descreve metodologias para definir gramáticas para linguagens
simples, representar sentenças na linguagem e interpretar essas sentenças. Nesse contexto, o
padrão envolve a definição de uma gramática e a representação e interpretação de expressões
regulares da gramática. O padrão pode ser aplicado quando houver uma linguagem para

interpretar e sentenças dessa linguagem puderem ser representadas como árvores sintáticas

abstratas.
         O padrão Iterator também conhecido como Cursor, fornece um método de acesso
aos elementos de um objeto de modo sequencial e sem expor a sua representação interna.
Gamma et al. (2000) relata o exemplo de um objeto que constitui uma lista, onde os
elementos da lista podem ser acessados a partir de diferentes critérios sem que a sua estrutura
interna seja exposta. A ideia principal do padrão é transferir a responsabilidade de acesso e

percurso de um conjunto de objeto para um objeto iterator, fornecendo uma interface que

percorra diferentes estruturas agregadas.
         O padrão Mediator abstrair a interação entre um conjunto de objetos. De acordo com
Gamma et al. (2000, p. 257) o padrão Mediator tem como objetivo: “[...] definir um objeto
que encapsula a forma como um conjunto de objetos se interagem. O Mediator promove o
acoplamento fraco ao evitar que os objetos se refiram uns aos outros explicitamente e permite
variar suas interações independentemente.” O padrão pode ser aplicado quando a

comunicação entre um conjunto de objetos ocorre de modo complexo, onde as

interdependências resultantes são difíceis de compreender. A aplicabilidade do padrão

promove a reutilização de objetos que mantém uma comunicação com um número

arbitrariamente elevado de objetos, pois ele abstrai e estrutura essas relações de comunicação

entre os objetos.
29


        Segundo Gamma et al. (2000) o padrão Memento registra o estado interno de um
objeto sem violar o encapsulamento, de modo que o objeto possa ser restaurado para esse
mesmo estado mais tarde. A aplicabilidade do padrão ocorre quando o estado interno de um
objeto necessita ser salvo em determinado momento na execução da aplicação, de modo que o
objeto possa recuperar o estado salvo posteriormente.
        O padrão Observer define uma dependência de um para muitos entre objetos, onde
existe um objeto que possui informações de interesse para um conjunto de objetos
dependentes deste. Quando o objeto de interesse muda de estado, todos os seus dependentes
são notificados e atualizados automaticamente. O padrão pode ser aplicado quando um objeto
deseja notificar um conjunto indefinido de outros objetos, sem a necessidade de conhecer
quais são esses objetos. O tipo de interação disponibilizada pelo padrão Observer também é
conhecido como publish-subscribe, onde um objeto de interesse (subject) atua como um
publicador de notificações, enviando-as sem ter que saber quem são os objetos observadores
(GAMMA et al., 2000). O padrão Observer pode ser aplicado a medida que:


                       [...] uma abstração tem dois aspectos, um dependente do outro.
                       Encapsulando esses aspectos em objetos separados, permite-se variá-los e
                       reutilizá-los independentemente [...] Quando uma mudança em um objeto
                       exige mudanças em outros, e você não sabe quantos objetos necessitam ser
                       mudados [...] Quando um objeto deve ser capaz de notificar outros objetos
                       sem fazer hipóteses, ou usar informações, sobre quem são esses objetos. Em
                       outras palavras, você não quer que esses objetos sejam fortemente
                       acoplados. (GAMMA et al., 2000, p. 275).


        O padrão State permite que um objeto altere seu comportamento quando o seu estado
interno muda. O padrão permite a introdução de uma classe abstrata que, por composição de
objetos, pode assumir diferentes comportamentos. Gamma et al. (2000, p. 285) recomenda o
padrão State nos seguintes casos:


                       O comportamento de um objeto depende do seu estado e ele pode mudar seu
                       comportamento em tempo de execução, dependendo desse estado [...] Esse
                       estado é normalmente representado por uma ou mais constantes enumeradas.
                       Frequentemente, várias operações conterão essa mesma estrutura
                       condicional. O padrão State coloca cada ramo do comando adicional em uma
                       classe separada. Isto lhe permite tratar o estado do objeto como um objeto
                       propriamente dito, que pode variar independentemente de outros objetos.
30


        Segundo Gamma et al. (2000) o padrão Template Method define a estrutura de um
algoritmo em uma operação, permitindo que subclasses redefinam certos passos do algoritmo
sem mudar a sua estrutura. O conceito apresentado por este padrão torna-o aplicável na

implementação de partes de algoritmos que não variam durante a execução da aplicação. Ao

identificar as partes que não variam, o padrão delega para as subclasses a implementação do

comportamento que pode variar em tempo de execução.
        O padrão Visitor tem por objetivo representar operações a serem executadas nos
elementos de uma estrutura de objetos, permitindo definir uma nova operação sem mudar as
classes dos elementos sobre os quais o objeto atua. O padrão permite que sejam adicionadas
novas funcionalidades a classe de um objeto sem a necessidade de modificação dessa classe
(GAMMA et al., 2000).


2.4.2 Padrão Strategy

        O padrão Strategy permite definir uma família de algoritmos e encapsular cada
algoritmo como uma classe, permitindo que o algoritmo seja definido em tempo de execução
e que possa variar independentemente dos clientes que o utilizam (GAMMA et al., 2000).

         A partir da definição de Gamma et al. (2000) nota-se que podem ser definidas

estratégias que permitem configurar uma classe capaz de adquirir um dentre muitos

comportamentos que a aplicação pode requerer em tempo de execução.
                                Figura 5 – Padrão Strategy




                               Fonte: Gamma et al. (2000, p. 294)


        O diagrama exposto na Figura 5 define uma interface comum a todos os algoritmos
suportados. A interface denominada Strategy está apta a assumir o comportamento de uma
dentre varias classes ConcreteStrategy. Context representa genericamente um objeto em um
determinado contexto e usa a interface Strategy para chamar um dado algoritmo, definido por
31


uma das classes ConcreteStrategy. Na origem das colaborações estão os objetos clientes, que
passam um objeto ConcreteStrategy para o contexto. O contexto repassa as solicitações dos
objetos clientes para sua estratégia em resposta a requisição de cada cliente. Nota-se que os
objetos clientes interagem exclusivamente com o contexto, e para cada interface existe uma
família de classes ConcreteStrategy onde os objetos clientes decidem em tempo de execução o
algoritmo a ser executado (GAMMA et al., 2000).
        Rocha (2011) aplicou o padrão Strategy para o desenvolvimento de rotinas de
geração de eventos aleatórios a partir de distribuições teóricas de probabilidade. A Figura 6
mostra o diagrama de classes envolvido na rotina.
         Figura 6 – Diagrama de classes envolvido na geração de eventos aleatórios.




                                   Fonte: Rocha (2011, p. 16)


        No diagrama da Figura 6 tem-se que Entity é o contexto, ProbabilityDistribution é a
estratégia, e as classes concretas Exponential, Uniform e Constant constituem a família de
algoritmos    possíveis    de    serem      adotados       pela   estratégia.   A     interface
ProbabilityDistributionBehavior apenas define regras de comportamento às classes que a
implementam (ROCHA, 2011).
        De acordo com Rocha (2011) essa é uma situação típica onde o padrão Strategy pode
ser aplicado, pois as classes concretas de geração de variáveis aleatórias formam uma família
32


de classes que compartilham um comportamento obrigatório, e são capazes de fornecer
variáveis aleatórias referentes a uma dada distribuição de probabilidade requisitada em tempo
de execução pelo objeto cliente.
       A vantagem do padrão Strategy nesta situação é que uma nova distribuição teórica de
probabilidade pode ser facilmente adicionada ao projeto a partir da criação de uma nova
classe que estenda a classe abstrata ProbabilityDistribution e implemente a interface
ProbabilityDistributionBehavior (ROCHA, 2011).
       Cassimiro (2010) utilizou o padrão Strategy para modelar um sistema chamado
TMTurismo, como mostra a Figura 7.
                    Figura 7 – Padrão Strategy para os pacotes turísticos.




                                   Fonte: Cassimiro (2010, p. 38)


        De acordo com Cassimiro (2010) o sistema TMTurismo deve ser flexível o suficiente
para o atendente modelar um pacote turístico de acordo com a preferência do cliente. Esse
33


fato implica que o cliente vai informar qual o destino quer ir, o tipo de passagem, a
hospedagem e as opções de veículo e passeios juntamente com atividades desejadas.
        O padrão Strategy foi implementado com o intuito de proporcionar alterações nos
pacotes turísticos de forma organizada e planejada no código fonte, uma vez que se novos
pacotes forem criados ou novos comportamentos adicionados, é necessário apenas herdar da
classe abstrata PacoteTuristicoStrategy, no caso da criação de novos pacote, ou criar uma
interface com sua família de comportamento e adicionar a sua referência na classe
PacoteTuristicoStrategy.
34


                                      CAPÍTULO III


3 PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE

        Os capítulos anteriores apresentaram os princípios e os fundamentos dos padrões de
projeto de software, com o objetivo de discutir neste capítulo as vantagens e as limitações da
aplicação desses padrões no processo de manutenção de software, visando a melhoria da
manutenabilidade.


3.1 Manutenção de software

        Pressman (1995) e Sommerville (2003) definem manutenção de software como o
processo de modificação de um sistema após a sua conclusão. Esse processo de modificação
pode ser simples, destinado a corrigir erros de código, ou significativo, com a finalidade de
adicionar novos componentes ou realizar a reestruturação do software. IEEE - Institute of
Electrical and Electronics Engineers (1997) relata que as atividades de manutenção iniciam o
processo de modificação no ciclo de vida do software.
        Pressman (1995) e Peters e Pedrycs (2001) categorizam a manutenção de software
em quatro grupos:
       Manutenção adaptativa: modificação do software para mantê-lo utilizável após
         mudanças no ambiente;
       Manutenção corretiva: modificação do software para corrigir falhas descobertas após
         a entrega;
       Manutenção preventiva: modificação do software antes que ocorram falhas
         operacionais;
       Manutenção de aperfeiçoamento: modificação do software para aperfeiçoamento, em
         função das mudanças da organização ou de regras de negócio.
        O processo de manutenção de software é uma consequência dos procedimentos de
gestão da qualidade realizados na fase de desenvolvimento do projeto. Em função disso,
quanto menos definidos esses procedimentos, maiores os defeitos ou falhas que devem ser
removidos durante a operação do software (PAULA FILHO, 2003).
35


3.2 Manutenabilidade

        IEEE (1990, p. 46, tradução nossa) define manutenabilidade de software como “[...] a
facilidade com que um sistema ou componente de software pode ser modificado para corrigir
falhas, melhorar o desempenho ou outros atributos, ou se adaptar a uma modificação do
ambiente”. Seguindo essa mesma orientação, Pressman (1995) descreve a manutenabilidade
como a facilidade com que um software pode ser corrigido, adaptado ou ampliado, caso haja a
necessidade de inclusão ou alteração nos requisitos funcionais.
        Gamma et al. (2000) sustenta que os padrões de projeto tem grande influência na
manutenabilidade de software. Na medida em que influenciam diretamente em alguns fatores,
tais como limitação de dependências de plataforma, viabilização de estruturas em camadas,
facilidade de extensão, entre outros, os padrões de projetos elevam o nível de facilidade com
que um sistema de software pode ser modificado.


                       Os padrões de projeto também tornam uma aplicação mais fácil de ser
                       mantida quando são usados para limitar dependências de plataforma e
                       fornecer uma estrutura de camadas a um sistema. Eles melhoram a facilidade
                       de extensão ao mostrar como estender hierarquias de classes e explorar a
                       composição de objetos. (GAMMA et al., 2000, p. 41).


        Prechelt et al. (2001) realizou um experimento com intuito de investigar a efetividade
do uso dos padrões Observer, Visitor, Decorator, Composite e AbstractFactory em processos
de manutenção de software. Participaram voluntariamente da experiência 29 profissionais da
área, os quais foram submetidos a testes de programação utilizando papel e caneta. Os
resultados da experiência mostraram efeitos positivos e negativos sobre os padrões analisados.
O padrão Observer teve efeito negativo sobre a manutenabilidade, o padrão Visitor se
manteve neutro, o padrão Decorator teve efeito positivo, e os padrões Composite e
AbstractFactory mostraram-se pouco significativos.
        Jeanmart et al. (2009) realizou um estudo para avaliar o impacto do padrão Visitor
sobre a manutenabilidade de software. Os resultados do estudo mostraram que o padrão
Visitor tem um impacto positivo sobre a manutenabilidade de software, diferenciando dos
resultados obtidos por Prechelt et al. (2001), no qual o padrão se manteve neutro. No estudo
de Jeanmart et al. (2009), apesar do padrão Visitor ter influenciado pouco no esforço de
compreensão do software, a sua representação gráfica junto ao diagrama de classes reduziu
consideravelmente os esforços nas tarefas de modificação do software.
36


        Prechelt et al. (2002) realizou um estudo para analisar a relevância da documentação
gerada a partir da aplicação de padrões de projeto, no sentido de facilitar mudanças no
processo de manutenção. Os parâmetros considerados no estudo foram o tempo gasto e a
eficiência esperada em cada tarefa de modificação do software. No software objeto do estudo
foram analisados os padrões Composite, Observer, Template Method, e Visitor, e os
resultados mostraram que, com o suporte de uma documentação explícita, as tarefas de
manutenção podem ser realizadas mais rapidamente e com menos falhas.
        Nanthaamornphong e Carver (2011) replicaram o experimento realizado por Prechelt
et al. (2001), no qual foi realizado um estudo com foco no impacto que os padrões de projeto
têm sobre a manutenabilidade e a compreensão de software. Um novo parâmetro incluído
nesse experimento e que não foi considerado por Prechelt et al. (2001), foi a avaliação do
nível de compreensão do software. As tarefas de manutenção foram realizadas em duas
versões do mesmo software, uma com a presença de padrões, e outra elaborada somente a
partir de soluções alternativas aos padrões. Dados estatísticos do estudo indicaram que para as
tarefas de manutenção os padrões de projeto não contribuíram para a melhoria da
manutenabilidade e compreensão do software.
        Ng et al. (2006) refizeram o software JHotDrow – um editor de desenho de código
fonte aberto – adicionando padrões de projeto em algumas funcionalidades do software. O
objetivo do trabalho foi realizar três tarefas de manutenção em funcionalidades similares ao
software original e ao software refeito. Dois grupos de pessoas participaram do experimento,
um formado por profissionais experientes na área e outro grupo ainda sem experiência prática.
Os resultados do experimento mostraram que o tempo gasto nas tarefas de manutenção
referente à versão do software refeito foi menor que o tempo gasto na versão original. Outro
fator interessante foi que, até mesmo o grupo de pessoas inexperientes, realizaram as tarefas
em um espaço de tempo relativamente inferior. Além disso, a solução proposta pelo grupo
inexperiente alcançou o mesmo nível de qualidade da solução proposta pelo grupo experiente.


                        [...] Uma vez que os padrões de projeto descritos apoiaram as modificações
                       necessárias no software, as pessoas que utilizaram a abordagem refeita
                       gastaram menos tempo ao analisar os códigos a serem modificados na tarefa
                       de manutenção [...] A parte interessante dos nossos resultados é que,
                       independentemente da experiência das pessoas, o fator tempo usando a
                       abordagem refeita foi acentuadamente menor do que a abordagem direta,
                       mesmo após incluir o tempo gasto no processo de redefinição do software.
                       (NG et al., 2006, p. 9, tradução nossa).
37


        Ng et al. (2007) realizaram um estudo empírico para avaliar a relevância dos padrões
de projeto aplicados na fase de desenvolvimento do software e os reflexos sobre os processos
posteriores de manutenção. O objetivo do trabalho foi analisar a interação entre dois cenários:
a aplicação de padrões na fase de desenvolvimento do software e a utilização destes padrões
em tarefas futuras de modificação. Os resultados da pesquisa mostraram que os padrões de
projeto aplicados na fase de desenvolvimento do software foram efetivamente úteis no sentido
de prever mudanças futuras. Estatisticamente o estudo mostrou que há menos falhas de código
ao realizar tarefas de modificação a partir de padrões que tenham sido implementados na fase
de desenvolvimento do software.
        Ng, Yu e Cheung (2010) relataram um estudo empírico onde foram investigados os
efeitos de cinco fatores humanos que podem influenciar na manutenabilidade do software:
exposição prévia dos profissionais aos padrões de projeto; exposição prévia ao software
utilizado no estudo; exposição prévia a linguagem de programação; experiência dos
profissionais; e soluções alternativas ao uso dos padrões. Foi selecionado para o estudo um
software em que já havia a presença de padrões de projeto em sua estrutura, e os resultados
mostraram que a exposição prévia ao programa foi o fator mais significativo em termos do
tempo gasto na manutenção, a exposição prévia aos padrões de projeto e à linguagem de
programação não foram significativos, e o uso de soluções alternativas aos padrões de projeto
foi inconclusivo no estudo.
        Os resultados obtidos em Ng, Yu e Cheung (2010) foram reafirmados em Ng et al.
(2012). Além disso, este último estudo identificou um novo fator relevante para a
manutenabilidade do software, que consiste no fato de que os profissionais tendem a aplicar
soluções mais simples quando essa solução é mais fácil de ser aplicada que a solução proposta
por um padrão conhecido. Esse novo fator é descrito no estudo da seguinte maneira:


                       Uso inconsciente de padrões sugere que, se uma solução mais simples do
                       que a solução proposta por um padrão conhecido é identificada, o
                       profissional provavelmente escolherá a solução mais simples. A título de
                       orientação, os desenvolvedores não devem aplicar padrões de projeto para
                       apoiar modificações simplesmente porque determinado padrão é aplicável,
                       também é necessário considerar se há alternativas mais simples. (NG et al.,
                       2012, p. 26, tradução nossa).


        Em resumo, o estudo concluiu que há três fatores estritamente correlacionados ao
tempo despendido na execução de tarefas de manutenção: os padrões de projeto existentes no
software; o conhecimento prévio do software; e o uso de soluções alternativas.
38


         Vokac et al. (2004) replicaram o experimento realizado por Prechelt et al. (2001). Os
resultados do estudo mais recente se diferenciaram do estudo anterior em relação aos padrões
Observer e Visitor. Enquanto que a experiência original mostrou efeitos negativos em relação
ao padrão Observer, os resultados do estudo mais recentes mostraram dados estatísticos
favoráveis ao uso do padrão, uma vez que o padrão Observer se mostrou bastante
compreensivo e intuitivo até mesmo pelos profissionais com pouca experiência sobre o
padrão. Em contrapartida, enquanto que a experiência original apresentou efeitos positivos em
relação ao padrão Visitor, no estudo mais recente o padrão se mostrou significativamente
confuso e pouco compreensivo pelos profissionais. Os resultados do estudo indicaram ainda
que alguns padrões, tais como Observer e Decorator são relativamente mais fáceis de serem
compreendidos e utilizados do que outros.
         Chatzigeorgiou, Tsantalis e Deligiannis (2008) realizou um estudo empírico para
avaliar a habilidade de um grupo de estudantes na compreensão de padrões de projeto. Os
estudantes tiveram que desenvolver duas versões de um mesmo software; uma versão
aplicando padrões de projeto e outra aplicando soluções alternativas. Os resultados indicaram
que a versão do software com a presença de padrões oferecia uma arquitetura bem elaborada,
uma vez que padrões foram aplicados corretamente. Em contrapartida, a versão do software
sem a presença de padrões apresentou uma arquitetura pobre e com falhas.


3.3 Modularidade

         De acordo com IEEE (1990) modularidade é o grau com que um sistema ou
programa de computador é composto em componentes, de modo que uma mudança em um
componente tenha o mínimo de impacto em outros componentes. Shalloway e Trott (2004)
relata que a modularidade ajuda a tornar o código mais compreensível, e que essa capacidade
de compreensão, por sua vez, o torna mais fácil de manter.
         A modularidade de software está fortemente relacionada ao conceito de acoplamento
e coesão. Esses dois conceitos de software são constantemente utilizados pelos padrões de
projeto e influenciam positivamente na modularidade do software (SHALLOWAY; TROTT,
2004).
39


3.3.1 Acoplamento

        De acordo com IEEE (1990) acoplamento é a medida que define o grau de
interdependência entre dois módulos de software. Lino (2011) descreve este mesmo conceito
e relata que em sistemas que são estruturados em módulos, devem ser criadas interfaces bem
definidas para a comunicação entre os diversos módulos, reduzindo assim o impacto que a
modificação de um módulo possa causar no sistema.
        Gamma et al. (2000), Shalloway e Trott (2004) e Lino (2011) consideram que esse
grau de dependência entre módulos deve ser fraco para promover a reusabilidade, e
descrevem que os padrões de projeto têm justamente esse objetivo, reduzir as dependências
para aumentar a reusabilidade interna do software.


                       Os padrões de projeto que reduzem dependências podem aumentar a
                       reusabilidade interna. O acoplamento mais fraco aumenta a probabilidade de
                       que uma classe de objetos possa cooperar com várias outras. Por exemplo,
                       quando você elimina dependências de operações específicas, pelo isolamento
                       e encapsulamento de cada operação, torna mais fácil a reutilização de uma
                       operação em contextos diferentes [...] (GAMMA et al., 2000, p. 41).


        Gamma et al. (2000) observa ainda que o acoplamento reduzido também promove
portabilidade, facilidade de modificação e extensibilidade em sistemas de softwares. Os
padrões de projeto usam técnicas para reduzir o acoplamento e definir camadas para obter
sistemas com alto grau de modularidade.
        São vários os padrões de projeto que promovem efetivamente o acoplamento entre
módulos ou componentes de software. Gamma et al. (2000) e Shalloway e Trott (2004)
descrevem quatro padrões que atuam no sentido de reduzir o acoplamento de sistemas de
software: Chain of Responsability, Facade, Mediator e Observer.


3.3.2 Coesão

        De acordo com IEEE (1990) a coesão é a intensidade ou grau com que as tarefas
executadas por um módulo de software estão relacionadas. Shalloway e Trott (2004) e
Ferreira (2011) seguem esse mesmo conceito ao relacionar a coesão ao nível de comunicação
entre os elementos internos de um módulo. Lino (2011) afirma que a coesão permite que um
módulo ou classe dependa menos dos outros componentes, uma vez que a comunicação
interna de cada módulo é otimizada.
40


           A quantidade de conexões entre os módulos de um sistema tende a ser menor a
medida que o nível de coesão interna de cada módulo aumenta. Isso resulta em um impacto
positivo no processo de modificação interna de determinado módulo, uma vez que as
consequências desse processo sobre os outros módulos do software são minimizadas
(FERREIRA; BIGONHA, M.; BIGONHA, R., 2008).
           O nível de coesão de um módulo retrata o impacto que o processo de modificação de
um módulo causa sobre os outros módulos do software. Gamma et al. (2000) afirma que os
padrões de projeto buscam justamente elevar esse nível de coesão, pois a medida que o
módulo se torna coeso ele promove a modularidade e consequentemente contribui para a
manutenabilidade do software.


3.4 Reusabilidade

       Freeman Erich e Freeman Elizabeth (2009) relata que os princípios de orientação a
objeto como herança, composição, polimorfismo, entre outros, devem estar associados aos
padrões de projeto para atribuir facilidade de reutilização em projetos de software. Os padrões
de projeto permitem aplicar esses princípios de orientação a objeto considerando um alto nível
de abstração para que se possa definir a melhor solução.
           O desenvolvimento de software envolve uma considerável repetição de recursos,
onde determinadas aplicações podem compartilhar as mesmas funcionalidades. Arnout (2004)
relata que a concepção de reuso se refere à possibilidade de reaproveitar elementos de
software que possam ser utilizados em qualquer projeto que necessite explicitamente dessa
funcionalidade. Nesse contexto, os padrões de projeto abstraem o reuso de funcionalidades,
atribuindo a possibilidade de reutilização de soluções padronizadas.
       Gamma et al. (2000) relata que a herança de classe e a composição de objetos são as
duas técnicas mais comuns para a reutilização de funcionalidades. Enquanto que a herança de
classe é definida em tempo de compilação e é dependente da implementação, a composição de
objetos é definida dinamicamente em tempo de execução e exige a obtenção de referências a
outros objetos. Assim, a herança e a composição atuam em conjunto e, em função disso,
promovem a reusabilidade interna do software e são aplicadas frequentemente aos padrões de
projeto.
41


3.5 Uso de interfaces

         As interfaces são fundamentais em sistemas orientados a objeto. A definição de uma
interface consiste em reunir um conjunto de regras para as classes que a implementam. Isso
permite que os objetos sejam conhecidos somente através das suas interfaces, e o único modo
de obter informações sobre o objeto ou de pedir que ele execute alguma operação é sob o
intermédio da sua interface. O benefício do uso de interfaces é que elas permitem especificar
um objeto sem definir a sua implementação concreta, consequentemente dois ou mais objetos
da mesma interface podem realizar operações de modos diferentes (GAMMA et al., 2000).
         Gamma et al. (2000) menciona a ligação dinâmica como um recurso bastante
explorado ao utilizar interfaces. O entendimento da ligação dinâmica consiste em associar
uma solicitação a um objeto e a uma de suas operações em tempo de execução.


                        Quando uma mensagem é enviada a um objeto, a operação específica que
                        será executada depende de ambos, mensagem e objeto receptor. Diferentes
                        objetos que suportam solicitações idênticas, podem ter diferentes
                        implementações das operações que atendem a estas solicitações. A
                        associação em tempo de execução de uma solicitação a um objeto e a uma
                        das suas operações é conhecida como ligação dinâmica. (GAMMA et al.,
                        2000, p. 29, grifo do autor).

         O uso da ligação dinâmica significa que o envio de uma solicitação não define um
fluxo de operação em particular até o momento da execução. Em razão disso o programa é
capaz de esperar um objeto com uma interface em particular, sabendo que qualquer objeto que
tenha a interface correta está apto a aceitar a solicitação. Além do mais, a ligação dinâmica
permite substituir objetos que tenham interfaces idênticas em tempo de execução (GAMMA
et al., 2000).
         De acordo com Gamma et al. (2000) os padrões de projeto permitem definir
interfaces pela identificação de seus elementos-chave e pelos tipos de dados que são enviados
através de uma interface. Os padrões de projeto também especificam relacionamentos entre
interfaces ao exigir que determinadas classes tenham interfaces similares, ou colocam
restrições sobre interfaces de determinadas classes. Um exemplo disso pode ser observado nos
padrões Decorator e Proxy, ao exigir que as interfaces de objetos Decorator e Proxy sejam
idênticas. O padrão Strategy depende fortemente do uso de interfaces ao definir para cada
família de algoritmos uma interface comum para todos os algoritmos suportados. No padrão
Visitor uma interface deve refletir todas as classes de objetos denominados visitantes.
42


         Ao abstrair o processo de criação de objetos, os padrões de criação concedem
diferentes maneiras de associar uma interface à sua implementação de forma transparente no
momento da instanciação. Os padrões de criação asseguram que o projeto esteja definido em
termos de interfaces e não apenas de implementações concretas. Gamma et al. (2000, p. 33)
relata o seguinte: “Não declare variáveis como instâncias de classes concretas específicas. Em
vez disso, prenda-se somente a uma interface definida por uma classe abstrata [...]”


3.6 Limitações

         Wendorff (2001) realizou uma análise para averiguar o uso excessivo de padrões de
projeto em um amplo sistema comercial. O estudo reportou consequências negativas que a
prática do uso excessivo de padrões pode causar nos processos futuros de manutenção. O
estudo revelou ainda que muitas vezes os padrões são aplicados sem que haja uma análise
prévia das suas consequências. Em função disso a aplicação de padrões pode ter efeitos
negativos sobre o software e consequentemente conduzir a processos de reengenharia e altos
custos de manutenção no futuro.
         Gamma et al. (2000) afirmam que cada padrão de projeto se refere a um problema
que ocorre com determinada frequência em um contexto específico, descrevendo uma solução
para o problema de modo que se possa utilizar essa solução milhares de vezes sem
necessariamente seguir o mesmo caminho. Esta asserção é questionada por Arnout (2004), o
qual indaga que a definição de uma solução utilizando padrões deve ser adaptada para cada
novo contexto, o que significa que o uso de padrões de projeto não proporciona reusabilidade
em termos de código, mas sim em termos de uma adaptação a cada problema ou contexto em
particular.
43


                                       CONCLUSÃO


           Padrões de projeto de software são soluções para os problemas que ocorrem com
frequência no processo de desenvolvimento de sistemas de software. Pesquisas bibliográficas
revelam que os padrões de projeto fornecem alternativas de reuso de soluções que já foram
projetadas, testadas e se mostraram eficientes, assim, evitando alternativas que comprometam
a eficiência do sistema de software.
           Os padrões de projeto GOF são classificados em três grupos principais: padrões de
criação, que descrevem técnicas para instanciar objetos; padrões estruturais, que descrevem
métodos de organização de classes e objetos em estruturas maiores; e padrões
comportamentais, que descrevem métodos de atribuição de responsabilidades a classes e
objetos.
           Os avanços na indústria de software vêm requisitando cada vez mais os recursos de
engenharia de software para tornar os processos de desenvolvimento e manutenção mais
ágeis, menos suscetíveis a erros e a um menor custo. É neste contexto que a proposta dos
padrões de projeto ganhou relevância na comunidade de engenharia de software. As soluções
propostas por padrões de projeto retratam a experiência de profissionais e de projetos bem
sucedidos, definem uma terminologia comum que permite estabelecer um vocabulário
compartilhado na comunicação entre os membros da equipe, ajudam na identificação de
equívocos ou armadilhas comuns que ocorrem no desenvolvimento de software, e contribuem
para o desenvolvimento de software de maior qualidade.
           Os estudos de caso apresentados neste trabalho monográfico mostraram que a
aplicação de padrões de projeto pode levar à construção de software com maior qualidade
estrutural e, portanto, de mais fácil manutenção. Os experimentos revelaram indícios de que a
aplicação de padrões de projeto na fase desenvolvimento do software é um fator positivo nos
processos futuros de manutenção: a documentação gerada a partir da aplicação de padrões de
projeto contribuiu para a manutenabilidade, uma vez que o suporte de uma documentação
explícita possibilita que as tarefas de manutenção sejam realizadas mais rapidamente e com
menos falhas; os padrões Decorator e Observer revelaram-se como os mais fáceis de serem
compreendidos e se mostraram bastante intuitivos, sendo utilizados facilmente pelos
profissionais com pouca experiência na aplicação destes padrões; o padrão Visitor reduziu os
esforços em tarefas de modificação do software, em função da sua representação gráfica junto
ao diagrama de classes.
44


        Sistemas    de    software   modulares   mantém     o   código   compreensível   e
consequentemente mais fácil de manter. O grau de modularidade depende dos níveis de
acoplamento entre módulos e da coesão interna de cada módulo, à medida que o nível de
acoplamento é reduzido e o de coesão é elevado, obtém-se um software com maior grau de
modularidade. A influência dos padrões de projeto sobre a modularidade do software ocorre
através da manipulação direta dos níveis de acoplamento e coesão.
        Apesar dos benefícios proporcionados, os padrões de projeto também podem ter
efeitos negativos no software. A aplicação de padrões sem que haja uma análise prévia das
suas consequências pode levar a processos de reengenharia e gerar autos custos de
manutenção.
        Este trabalho monográfico aponta para os seguintes estudos futuros: realização de
experimentos em softwares de diferentes tamanhos e propósitos para avaliar a influência dos
padrões de projeto sobre o processo de manutenção; realização de trabalhos similares,
considerando métricas de software para avaliar a relevância dos padrões de projeto em
diferentes aspectos do software.
45


                                    REFERÊNCIAS

ALEXANDER, C. The timeless way of building. New York: Oxford University Press, 1979.

ARNOUT, K. From patterns to components. 2004. 430f. Dissertação (Tese de doutorado).
Swiss federal institute of technology, Zurich, 2004.

CASSIMIRO, M. H. O. Padrões arquiteturais e seus benefícios no processo de
manutenção do software. 2010, 43f. Trabalho de conclusão de curso (graduação em Ciência
da Computação). Faculdade de Ciências Empresariais, Belo Horizonte, 2010. Disponível em:
<http://www.ricardoterra.com.br/publications/students/2010_cassimiro.pdf >. Acesso em: 22
maio 2012.

CHATZIGEORGIOU, A.; TSANTALIS, N.; DELIGIANNIS, I. An empirical study on
students’ ability to comprehend design patterns. Computers & Education, Oxford, UK, v.
51, n. 3, p. 1007-1016, 2008. Disponível em:
<http://eprints.csse.uom.gr/5/1/CompEdu_2008.pdf>. Acesso em: 22 maio 2012.

FREEMAN, Erich; FREEMAN, Elizabeth. Use a cabeça: padrões de projetos. 2. ed. Rio de
Janeiro: Alta books, 2009.


FERREIRA, K. A. M.; BIGONHA, M. A. S.; BIGONHA, R. S. Reestruturação de software
dirigida por conectividade para redução de custo de manutenção. Revista de informática
teórica e aplicada, Porto Alegre, v. 15, n. 2, p. 155-180, 2008. Disponível em:
<http://seer.ufrgs.br/rita/article/view/rita_v15_n2_p155-180>. Acesso em: 02 jun. 2012.

FERREIRA, K. A. M. Um modelo de predição de amplitude da propagação de
modificações contratuais em software orientado por objetos. 2011. 224f. Dissertação
(Tese de doutorado). Universidade federal de Minas Gerais, Belo Horizonte, 2011. Disponível
em: <http://www.bibliotecadigital.ufmg.br/dspace/bitstream/1843/SLSS-
8GYFSX/1/keciaalinemarquesferreira.pdf>. Acesso em: 02 jun. 2012.

FOWLER, M. Padrões de arquitetura de aplicações corporativas. Porto Alegre: Bookman,
2006.

GAMMA, E.; HELM, R.; JOHNSON, R.; VLISSIDES, J. Design Patterns: elements of
reusable object-oriented software. [S.l.]: Addison-Wesley, 1995.

GAMMA, E.; HELM, R.; JOHNSON, R.; VLISSIDES, J. Padrões de projeto: soluções
reutilizáveis de software orientado a objetos. São Paulo: Bookman, 2000.

IEEE. Standard glossary of software engineering terminology. Std 610.12, 1990, New
York: IEEE, ISBN 1-55937-067-X. Disponível em:
<http://www.idi.ntnu.no/grupper/su/publ/ese/ieee-se-glossary-610.12-1990.pdf>. Acesso em:
01 jun. 2012.
Aplicação de Padrões de Projeto para a melhoria da manutenabilidade de software
Aplicação de Padrões de Projeto para a melhoria da manutenabilidade de software
Aplicação de Padrões de Projeto para a melhoria da manutenabilidade de software

Más contenido relacionado

La actualidad más candente

Padrão de Projeto - Adapter
Padrão de Projeto - AdapterPadrão de Projeto - Adapter
Padrão de Projeto - AdapterJuliana Cindra
 
Padrões de Projeto: Adapter
Padrões de Projeto: AdapterPadrões de Projeto: Adapter
Padrões de Projeto: AdapterMessias Batista
 
Fundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de SoftwareFundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de SoftwareÁlvaro Farias Pinheiro
 
Design Pattern MVC – Arquitetura de Software Coesa e Flexível
Design Pattern MVC – Arquitetura de Software Coesa e FlexívelDesign Pattern MVC – Arquitetura de Software Coesa e Flexível
Design Pattern MVC – Arquitetura de Software Coesa e FlexívelRyan Padilha
 
Exemplos de Design Patterns em Java
Exemplos de Design Patterns em JavaExemplos de Design Patterns em Java
Exemplos de Design Patterns em Javaalexmacedo
 
design patterns - introdução
design patterns - introduçãodesign patterns - introdução
design patterns - introduçãoelliando dias
 
MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!Flávio Lisboa
 
Orientação a Objetos no Delphi - Controle de Estoque (II)
Orientação a Objetos no Delphi - Controle de Estoque (II)Orientação a Objetos no Delphi - Controle de Estoque (II)
Orientação a Objetos no Delphi - Controle de Estoque (II)Ryan Padilha
 
Programação orientada à objetos & mvc
Programação orientada à objetos & mvcProgramação orientada à objetos & mvc
Programação orientada à objetos & mvcJhordam Siqueira
 
Orientação a Objetos no Delphi - Controle de Estoque (III)
Orientação a Objetos no Delphi - Controle de Estoque (III)Orientação a Objetos no Delphi - Controle de Estoque (III)
Orientação a Objetos no Delphi - Controle de Estoque (III)Ryan Padilha
 
Padroes de projetos gof
Padroes de projetos gofPadroes de projetos gof
Padroes de projetos gofYan Justino
 
Orientação a Objetos no Delphi - Por onde começar (I)
Orientação a Objetos no Delphi - Por onde começar (I)Orientação a Objetos no Delphi - Por onde começar (I)
Orientação a Objetos no Delphi - Por onde começar (I)Ryan Padilha
 
Padrões Arquiteturais de Sistemas
Padrões Arquiteturais de SistemasPadrões Arquiteturais de Sistemas
Padrões Arquiteturais de SistemasVagner Santana
 
IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...
IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...
IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...Eduardo Bertolucci
 
Aula de Introdução - JAVA
Aula de Introdução  - JAVAAula de Introdução  - JAVA
Aula de Introdução - JAVAMoises Omena
 
Poo apostila visual c
Poo apostila visual cPoo apostila visual c
Poo apostila visual cFabiano Lima
 

La actualidad más candente (20)

Padrão de Projeto - Adapter
Padrão de Projeto - AdapterPadrão de Projeto - Adapter
Padrão de Projeto - Adapter
 
Padrões de Projeto: Adapter
Padrões de Projeto: AdapterPadrões de Projeto: Adapter
Padrões de Projeto: Adapter
 
Fundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de SoftwareFundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de Software
 
Design Patterns - Adapter e Decorator
Design Patterns - Adapter e DecoratorDesign Patterns - Adapter e Decorator
Design Patterns - Adapter e Decorator
 
Design Pattern MVC – Arquitetura de Software Coesa e Flexível
Design Pattern MVC – Arquitetura de Software Coesa e FlexívelDesign Pattern MVC – Arquitetura de Software Coesa e Flexível
Design Pattern MVC – Arquitetura de Software Coesa e Flexível
 
Exemplos de Design Patterns em Java
Exemplos de Design Patterns em JavaExemplos de Design Patterns em Java
Exemplos de Design Patterns em Java
 
design patterns - introdução
design patterns - introduçãodesign patterns - introdução
design patterns - introdução
 
MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!
 
DCI com PHP
DCI com PHPDCI com PHP
DCI com PHP
 
Orientação a Objetos no Delphi - Controle de Estoque (II)
Orientação a Objetos no Delphi - Controle de Estoque (II)Orientação a Objetos no Delphi - Controle de Estoque (II)
Orientação a Objetos no Delphi - Controle de Estoque (II)
 
Programação orientada à objetos & mvc
Programação orientada à objetos & mvcProgramação orientada à objetos & mvc
Programação orientada à objetos & mvc
 
UML
UMLUML
UML
 
Orientação a Objetos no Delphi - Controle de Estoque (III)
Orientação a Objetos no Delphi - Controle de Estoque (III)Orientação a Objetos no Delphi - Controle de Estoque (III)
Orientação a Objetos no Delphi - Controle de Estoque (III)
 
Padroes de projetos gof
Padroes de projetos gofPadroes de projetos gof
Padroes de projetos gof
 
Orientação a Objetos no Delphi - Por onde começar (I)
Orientação a Objetos no Delphi - Por onde começar (I)Orientação a Objetos no Delphi - Por onde começar (I)
Orientação a Objetos no Delphi - Por onde começar (I)
 
Padrões Arquiteturais de Sistemas
Padrões Arquiteturais de SistemasPadrões Arquiteturais de Sistemas
Padrões Arquiteturais de Sistemas
 
IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...
IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...
IHC - Trabalho de Prototipação - Eduardo Bertolucci e Colegas e Classe - UNOP...
 
Aula de Introdução - JAVA
Aula de Introdução  - JAVAAula de Introdução  - JAVA
Aula de Introdução - JAVA
 
Oo delphi
Oo delphiOo delphi
Oo delphi
 
Poo apostila visual c
Poo apostila visual cPoo apostila visual c
Poo apostila visual c
 

Destacado

Publish-Subscribe Middlewares
Publish-Subscribe MiddlewaresPublish-Subscribe Middlewares
Publish-Subscribe Middlewareshome
 
Padrões de Projeto - Observer
Padrões de Projeto - ObserverPadrões de Projeto - Observer
Padrões de Projeto - ObserverJuliana Cindra
 
Padrão de Projeto Observer
Padrão de Projeto ObserverPadrão de Projeto Observer
Padrão de Projeto ObserverLuiza Uira
 
Arquitetura da plataforma com o Biztalk Server
Arquitetura da plataforma com o Biztalk ServerArquitetura da plataforma com o Biztalk Server
Arquitetura da plataforma com o Biztalk ServerMarkus Christen
 
Publisher subscriber pattern
Publisher subscriber patternPublisher subscriber pattern
Publisher subscriber patternDaeMyung Kang
 
Publish & Subscribe to events using an Event Aggregator
Publish & Subscribe to events using an Event AggregatorPublish & Subscribe to events using an Event Aggregator
Publish & Subscribe to events using an Event AggregatorLars-Erik Kindblad
 
Publish subscribe model overview
Publish subscribe model overviewPublish subscribe model overview
Publish subscribe model overviewIshraq Al Fataftah
 
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...Caelum
 
Observer - Padrões de projeto
Observer - Padrões de projetoObserver - Padrões de projeto
Observer - Padrões de projetoEduardo Mendes
 

Destacado (11)

Publish-Subscribe Middlewares
Publish-Subscribe MiddlewaresPublish-Subscribe Middlewares
Publish-Subscribe Middlewares
 
Padrões de Projeto - Observer
Padrões de Projeto - ObserverPadrões de Projeto - Observer
Padrões de Projeto - Observer
 
Padrão de Projeto Observer
Padrão de Projeto ObserverPadrão de Projeto Observer
Padrão de Projeto Observer
 
Padrões de Projeto para Jogos
Padrões de Projeto para JogosPadrões de Projeto para Jogos
Padrões de Projeto para Jogos
 
Arquitetura da plataforma com o Biztalk Server
Arquitetura da plataforma com o Biztalk ServerArquitetura da plataforma com o Biztalk Server
Arquitetura da plataforma com o Biztalk Server
 
Publisher subscriber pattern
Publisher subscriber patternPublisher subscriber pattern
Publisher subscriber pattern
 
Publish & Subscribe to events using an Event Aggregator
Publish & Subscribe to events using an Event AggregatorPublish & Subscribe to events using an Event Aggregator
Publish & Subscribe to events using an Event Aggregator
 
Publish subscribe model overview
Publish subscribe model overviewPublish subscribe model overview
Publish subscribe model overview
 
Algoritmos - Procedimentos
Algoritmos - ProcedimentosAlgoritmos - Procedimentos
Algoritmos - Procedimentos
 
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
 
Observer - Padrões de projeto
Observer - Padrões de projetoObserver - Padrões de projeto
Observer - Padrões de projeto
 

Similar a Aplicação de Padrões de Projeto para a melhoria da manutenabilidade de software

Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...
Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...
Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...Gabriel Cabral
 
Monografia douglashiura
Monografia douglashiuraMonografia douglashiura
Monografia douglashiuraDouglas Longo
 
Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...
Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...
Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...Ari Amaral
 
Engenharia de requisitos para metodos ageis dissertacao
Engenharia de requisitos para metodos ageis   dissertacaoEngenharia de requisitos para metodos ageis   dissertacao
Engenharia de requisitos para metodos ageis dissertacaotsblackboy
 
O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...
O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...
O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...Rogério Batista
 
TCC - Pós Engenharia de Software
TCC - Pós Engenharia de SoftwareTCC - Pós Engenharia de Software
TCC - Pós Engenharia de Softwarethiago.lenz
 
Graduação puc - aplicações de padrões de projeto no desenvolvimento de inte...
Graduação   puc - aplicações de padrões de projeto no desenvolvimento de inte...Graduação   puc - aplicações de padrões de projeto no desenvolvimento de inte...
Graduação puc - aplicações de padrões de projeto no desenvolvimento de inte...Wagner Tironi Pinto
 
Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...
Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...
Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...Anderson Kanegae Soares Rocha
 
MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...
MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...
MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...Daniele Aimi
 
Proposta de Projeto de Pesquisa - CEFET - 2014
Proposta de Projeto de Pesquisa - CEFET - 2014Proposta de Projeto de Pesquisa - CEFET - 2014
Proposta de Projeto de Pesquisa - CEFET - 2014Waldir R. Pires Jr
 
Trabalho de Conclusão de Curso de Graduação
Trabalho de Conclusão de Curso de GraduaçãoTrabalho de Conclusão de Curso de Graduação
Trabalho de Conclusão de Curso de GraduaçãoDaniel Fernando Pigatto
 
Gestao contexto qos_qoe
Gestao contexto qos_qoeGestao contexto qos_qoe
Gestao contexto qos_qoeIP10
 
Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...
Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...
Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...Gilmar Pupo
 
UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...
UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...
UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...antonio sérgio nogueira
 
Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...
Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...
Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...Erivan de Sena Ramos
 
Framework Entities - Dissertação
Framework Entities - DissertaçãoFramework Entities - Dissertação
Framework Entities - DissertaçãoMarcius Brandão
 
Fases do desenvolvimento de software baseado no código de ética.
Fases do desenvolvimento de software baseado no código de ética.Fases do desenvolvimento de software baseado no código de ética.
Fases do desenvolvimento de software baseado no código de ética.Ronildo Oliveira
 

Similar a Aplicação de Padrões de Projeto para a melhoria da manutenabilidade de software (20)

Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...
Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...
Monografia - Engenharia de software baseada em modelos um estudo sobre WebML ...
 
Monografia douglashiura
Monografia douglashiuraMonografia douglashiura
Monografia douglashiura
 
Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...
Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...
Análise da Utilização de Métodos Ágeis no Desenvolvimento de Ambientes Virtua...
 
Engenharia de requisitos para metodos ageis dissertacao
Engenharia de requisitos para metodos ageis   dissertacaoEngenharia de requisitos para metodos ageis   dissertacao
Engenharia de requisitos para metodos ageis dissertacao
 
O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...
O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...
O uso de frameworks em aplicações desktop baseadas na metodologia de desenvol...
 
TCC - Pós Engenharia de Software
TCC - Pós Engenharia de SoftwareTCC - Pós Engenharia de Software
TCC - Pós Engenharia de Software
 
Graduação puc - aplicações de padrões de projeto no desenvolvimento de inte...
Graduação   puc - aplicações de padrões de projeto no desenvolvimento de inte...Graduação   puc - aplicações de padrões de projeto no desenvolvimento de inte...
Graduação puc - aplicações de padrões de projeto no desenvolvimento de inte...
 
Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...
Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...
Software para Gerência de Projetos baseado em Metodologias Ágeis [Relatório T...
 
MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...
MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...
MÉTODO DE DESENVOLVIMENTO DE ÓRTESE PERSONALIZADA DE BAIXO CUSTO PARA A MANUF...
 
Proposta de Projeto de Pesquisa - CEFET - 2014
Proposta de Projeto de Pesquisa - CEFET - 2014Proposta de Projeto de Pesquisa - CEFET - 2014
Proposta de Projeto de Pesquisa - CEFET - 2014
 
Livro mef aa
Livro mef aaLivro mef aa
Livro mef aa
 
livro_mef_aa.pdf
livro_mef_aa.pdflivro_mef_aa.pdf
livro_mef_aa.pdf
 
Trabalho de Conclusão de Curso de Graduação
Trabalho de Conclusão de Curso de GraduaçãoTrabalho de Conclusão de Curso de Graduação
Trabalho de Conclusão de Curso de Graduação
 
Gestao contexto qos_qoe
Gestao contexto qos_qoeGestao contexto qos_qoe
Gestao contexto qos_qoe
 
Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...
Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...
Gerência de Configuração de Software: Benefícios Do Controle de Versões Distr...
 
Aula1 Apresentacao TEES
Aula1 Apresentacao TEESAula1 Apresentacao TEES
Aula1 Apresentacao TEES
 
UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...
UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...
UMA SUGESTÃO DE METODOLOGIA DE DESENVOLVIMENTO E GESTÃO DE PROJETO DE SOFTWAR...
 
Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...
Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...
Pesquisa Um Mapeamento Sistemático sobre Padrões de Software para Reengenhari...
 
Framework Entities - Dissertação
Framework Entities - DissertaçãoFramework Entities - Dissertação
Framework Entities - Dissertação
 
Fases do desenvolvimento de software baseado no código de ética.
Fases do desenvolvimento de software baseado no código de ética.Fases do desenvolvimento de software baseado no código de ética.
Fases do desenvolvimento de software baseado no código de ética.
 

Aplicação de Padrões de Projeto para a melhoria da manutenabilidade de software

  • 1. ESTADO DE MATO GROSSO SECRETARIA DE ESTADO DE CIÊNCIAS, TECNOLOGIA E EDUCAÇÃO SUPERIOR UNIVERSIDADE DO ESTADO DE MATO GROSSO FACULDADE DE CIÊNCIAS EXATAS CAMPUS UNIVERSITÁRIO DE BARRA DO BUGRES DEPARTAMENTO DE CIÊNCIA DA COMPUTAÇÃO JUNIOR CESAR DA ROCHA APLICAÇÃO DE PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE DE SOFTWARE BARRA DO BUGRES – MT 2012
  • 2. JUNIOR CESAR DA ROCHA APLICAÇÃO DE PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE DE SOFTWARE Trabalho de conclusão de curso apresentado ao Departamento de Ciência da Computação, Universidade do Estado de Mato Grosso – UNEMAT, como requisito para obtenção do título de Bacharel em Ciência da Computação, sob orientação do professor Esp. Alexandre Berndt. BARRA D BUGRES – MT 2012
  • 3. JUNIOR CESAR DA ROCHA APLICAÇÃO DE PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE DE SOFTWARE Trabalho de conclusão de curso apresentado ao Departamento de Ciência da Computação, Universidade do Estado de Mato Grosso – UNEMAT, como requisito para obtenção do título de Bacharel em Ciência da Computação na área de engenharia de software. Banca Examinadora ____________________________________________ Prof. Esp. Alexandre Berndt - UNEMAT Orientador ___________________________________________ Prof. Me. José Fernandes Torres da Cunha - UNEMAT Convidado ____________________________________________ Prof. Me. Allan Karly Luizi - UNEMAT Indicado pelo Departamento Aprovado em: 28 de Junho de 2012
  • 4. AGRADECIMENTOS A Deus, por ter proporcionado todas as condições humanas para que eu pudesse alcançar este objetivo. Aos meus pais e irmãos que, com todo apoio, atenção e carinho, contribuíram para a conclusão desse trabalho monográfico. Ao meu orientador, professor Alexandre Berndt, pelo ensinamento e dedicação disponibilizados no auxilio à conclusão dessa monografia. A todos os meus professores, pela dedicação e ensinamentos disponibilizados nas aulas. Cada um de forma especial contribuiu para a conclusão desse trabalho e consequentemente para minha formação profissional. Aos amigos e colegas que fiz durante o curso, em especial, Paulo Henrique, Michael e Rodrigo, por todos os momentos que vivenciamos juntos durante esses quatro anos e meio de curso. À UNEMAT, pela formação que recebi em Ciência da Computação.
  • 5. “Toda igualdade aparente esconde uma hierarquia” Masson Cooley
  • 6. RESUMO A comunidade de desenvolvimento de software vem adotando cada vez mais os conceitos propostos pelos padrões de projeto no processo de desenvolvimento de software. Estudos reportam evidências de que esses padrões causam um impacto positivo na qualidade do software, mas em alguns casos a adoção de padrões de projeto pode ser inapropriada. Esse trabalho monográfico relata a origem e os fundamentos dos padrões de projeto, e busca evidenciar a importância da aplicação de padrões para obter a excelência e a qualidade desejadas para os sistemas de software. Através de uma pesquisa bibliográfica esse trabalho evidenciou que a aplicação de padrões de projeto na fase de desenvolvimento do software é um recurso positivo nos processos futuros de manutenção. Fatores como reusabilidade, modularidade, uso de interfaces, composição de objetos, baixo acoplamento e alta coesão são diretamente manipulados através dos padrões de projeto e consequentemente promovem melhorias na manutenabilidade. Apesar dos benefícios proporcionados, os padrões de projeto também podem ter efeitos negativos sobre os sistemas de software. Palavras-chave: Engenharia de software. Padrões de projeto. Manutenabilidade.
  • 7. ABSTRACT The software development community has been increasingly adopting the concepts of design patterns in the process of software development. Studies report evidences that these patterns cause a positive impact on software quality, but in some cases the adoption of design patterns may be inappropriate. This monographic work describes the origin and fundamentals of design patterns and seeks to evidence the importance of applying patterns to obtain the excellence and quality desired for software systems. Through a bibliographic research this work suggested that the use of design patterns during software development is a positive factor in future maintenance processes. Factors such as reusability, modularity, use of interfaces, object composition, loose coupling and high cohesion are directly manipulated through the design patterns and they consequently promote enhancements in the maintainability. Despite the benefits provided, design patterns can also have negative effects on the software systems. Keywords: Software engineering. Design patterns. Maintainability.
  • 8. SUMÁRIO 1 PADRÕES DE PROJETO.................................................................................................. 10 1.1 Origem ........................................................................................................................... 10 1.2 Fundamentos ................................................................................................................. 11 1.3 Benefícios e limitações .................................................................................................. 13 2 PADRÕES DE PROJETO GOF ........................................................................................ 16 2.1 Classificação .................................................................................................................. 16 2.2 Padrões de criação ........................................................................................................ 18 2.2.1 Descrição e objetivos ............................................................................................. 19 2.2.2 Padrão Abstract Factory ........................................................................................ 20 2.3 Padrões estruturais ....................................................................................................... 23 2.3.1 Descrição e objetivos ............................................................................................. 23 2.3.2 Padrão Adapter....................................................................................................... 25 2.4 Padrões comportamentais ............................................................................................ 26 2.4.1 Descrição e objetivos ............................................................................................. 27 2.4.2 Padrão Strategy ...................................................................................................... 30 3 PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE ....... 34 3.1 Manutenção de software .............................................................................................. 34 3.2 Manutenabilidade ......................................................................................................... 35 3.3 Modularidade ................................................................................................................ 38 3.3.1 Acoplamento .......................................................................................................... 39 3.3.2 Coesão ..................................................................................................................... 39 3.4 Reusabilidade ................................................................................................................ 40 3.5 Uso de interfaces ........................................................................................................... 41 3.6 Limitações...................................................................................................................... 42 CONCLUSÃO......................................................................................................................... 43 REFERÊNCIAS ..................................................................................................................... 45
  • 9. 8 INTRODUÇÃO O princípio da aplicação de padrões de projeto foi relatado em Alexander (1979), onde teve início a documentação de padrões aplicados a projetos arquitetônicos. Ao adaptar o conceito de padrões de projeto ao desenvolvimento de software orientado a objetos, Gamma et al. (1995) publicou o primeiro catálogo de padrões de projeto de software, que é considerado hoje uma referência para a compreensão do conceito de padrões de projeto aplicados ao desenvolvimento de software. Padrões de projeto de software são soluções para problemas específicos em um determinado contexto, onde uma solução resolve um problema de modo que se possa reutilizar essa mesma solução milhares de vezes sem necessariamente seguir os mesmos passos (GAMMA et al., 2000). As soluções propostas por esses padrões geralmente são respostas a problemas que tendem a se repetir na construção de todos os softwares para esse mesmo domínio do problema (MAGELA, 2006). A aplicação de padrões de projeto de software busca melhorar a legibilidade e a facilidade de entendimento do software, sendo considerado como parte integrante da documentação do projeto (GAMMA et al., 2000). A partir da aplicação de padrões de projeto é possível promover reusabilidade, modularidade e manutenabilidade do software, pois os padrões fornecem soluções mais completas e melhor estruturadas do que uma solução simples para resolver determinado problema. Entretanto, pode-se adicionar complexidade desnecessária no software usando uma solução proposta por padrões (VOKAC et al., 2004). Os padrões de projeto representam um avanço na área de engenharia de software, pois oferecem estruturas para a reutilização de soluções de projeto que já foram testadas e aprovadas por profissionais experientes. Cada padrão fornece uma solução abstrata para um problema, permitindo assim desenvolver um projeto em uma notação de mais alto nível (THOMAZINI NETO, 2006). A indústria de desenvolvimento de software necessita cada vez mais de recursos de engenharia de software para tornar os processos de desenvolvimento e manutenção mais ágeis, no entanto, existem dificuldades em projetar software orientado a objetos de modo que sejam estabelecidas condições que promovam flexibilidade suficiente para lidar com o processo de desenvolvimento e manutenção do software (SHALLOWAY; TROTT, 2004). Neste contexto os padrões de projeto tem grande influência na manutenabilidade de software, pois eles elevam o nível de facilidade com que o software pode ser modificado (GAMMA et al., 2000). A manutenção de software é um processo realizado frequentemente, e pode gerar
  • 10. 9 altos custos, tanto pelo custo direto da manutenção quanto pelo custo da indisponibilidade do sistema (XIONG; XIE; NG, 2011). Esta pesquisa tem como objetivo relatar a origem dos padrões de projeto de software, seus fundamentos e definições, como eles se aplicam ao desenvolvimento de software, e apontar as vantagens e limitações da sua utilização no processo de manutenção de software. O capítulo 1 relata o histórico, os fundamentos e os conceitos teóricos sobre padrões de projeto. O capítulo 2 descreve os padrões de projeto GOF (Gang of four – termo utilizado na engenharia de software para fazer referência à publicação do primeiro catálogo de padrões de projeto de software). E o capítulo 3 busca apontar as vantagens e limitações da aplicação de padrões de projeto para a melhoria da manutenabilidade de software.
  • 11. 10 CAPÍTULO I 1 PADRÕES DE PROJETO Os padrões de projeto de software foram adotados pela engenharia de software a partir da década de 90. No fundamento destes padrões está a descrição de soluções para problemas recorrentes no desenvolvimento de software orientado a objetos. Este capítulo contextualiza os padrões de projeto de software, a seção 1.1 relata os princípios que deram origem aos padrões de projeto, a seção 1.2 descreve os seus fundamentos e a seção 1.3 faz uma abordagem sobre os benefícios e as limitações dos padrões de projeto. 1.1 Origem O termo padrões de projeto é conhecido inicialmente pelo seu uso em projetos arquitetônicos. Esse novo conceito foi criado na década de 70, a partir dos trabalhos de Christopher Alexander, um arquiteto urbano e urbanista que associou o termo padrão às repetições de formas em arquitetura. Alexander (1979) publicou um catálogo com 253 padrões aplicados a projetos arquitetônicos, o qual passou a ser utilizado como uma alternativa aos métodos tradicionais empregados pela arquitetura. Nessa publicação houve o questionamento sobre a existência de uma base objetiva para qualificar determinado projeto como sendo bom ou ruim. Essa base objetiva surgiu a partir da análise de projetos arquitetônicos e da afirmação de que seria possível qualificar projetos de arquitetura não apenas como uma questão de gosto, mas a partir de uma base objetiva e mensurável. Sob a ótica de padrões, Alexander (1979) passou a analisar os projetos de cidades, ruas, entre outros aspectos que envolviam conceitos arquitetônicos, e descobriu que as boas construções tinham algo em comum. Ao analisar dois projetos arquitetônicos que tivessem sido elaborados de maneira distinta, observou-se que eles poderiam ser similares na tentativa de resolver o mesmo problema. Esse foi o conceito que se tornou a base inicial para o processo de identificação de padrões que persistiam em projetos de boa qualidade. Passando de padrões de projetos de arquitetura para padrões de projeto de software, observa-se os trabalhos de Pree (1995) e Gamma et al. (1995), os quais observaram os conceitos sobre padrões de projeto e notaram que as soluções e os propósitos apresentados pelos padrões voltados para projetos arquitetônicos poderiam ser aplicados a projetos de
  • 12. 11 software orientado a objetos, pois visavam à flexibilidade e a reutilização de componentes, os quais poderiam ser aplicados em sistemas de software. Gamma et al. (1995) publicaram as suas primeiras experiências sobre padrões de projeto de software em um livro intitulado Design Patterns: Elements of reusable object oriented software. Essa publicação, constituída por 23 padrões, também ficou conhecida como catálogo GOF. Esta obra é considerada hoje a base fundamental para a compreensão do conceito de padrões de projetos de software. A obra em questão aplicou a ideia de padrões a projetos de software, descrevendo os fundamentos e uma estrutura para catalogar os padrões de projeto. Shalloway e Trott (2004) cita o trabalho de Pree (1995) e Gamma et al. (1995) como as publicações que tiveram uma grande influência na formação de uma comunidade de estudiosos sobre padrões de projeto. Ambas as publicações foram bem aceitas na área de desenvolvimento de software, e amplamente utilizadas tanto no campo acadêmico quanto empresarial. 1.2 Fundamentos Gamma et al. (2000) define padrões de projeto como soluções para problemas específicos em um determinado contexto, onde cada solução resolve um problema de modo que se possa utilizar essa solução milhares de vezes sem necessariamente seguir o mesmo caminho. 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ável. O padrão de projeto identifica as classes e instâncias participantes, seus papéis, colaborações e a distribuição de responsabilidades. Cada padrão de projeto focaliza um problema ou tópico particular de projeto orientado a objetos. Ele descreve em que situação 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. (GAMMA et al., 2000, p. 19). Gamma et al. (2000) descrevem alguns elementos que são essenciais para que um padrão possa ser compreendido e utilizado em projetos de software. Nessa definição, cada padrão deve ser caracterizado a partir de quatro elementos básicos: nome, problema, solução e consequências.
  • 13. 12 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 em um nível mais alto de abstração [...] O problema mostra em que situação aplicar o padrão. Ele explica o problema e seu contexto. Pode descrever problemas de projeto específicos, tais como representar algoritmos como objetos. Pode descrever estruturas de classe ou objeto sintomáticas de um problema 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. A solução descreve os elementos que compõe o padrão de projeto, seus relacionamentos, suas responsabilidades e colaborações. A solução não descreve um projeto concreto ou uma implementação em particular porque um padrão é um gabarito que pode ser aplicado em muitas situações diferentes. Em vez disso o padrão fornece uma descrição abstrata de um problema de projeto e de como um arranjo geral de elementos (classes e objetos) o resolve. As consequências são os resultados e análises das vantagens e desvantagens (trade 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 projetos e para a compreensão de custos e benefícios da aplicação do padrão. (GAMMA et al., 2000, p. 19, grifo do autor). Fowler (2006) e Magela (2006) apresentam conceitos similares aos de Gamma et al. (2000), ao definir padrões de projeto de software como sendo soluções usuais e específicas para a resolução de um ou mais problemas que ocorrem com frequência no processo de desenvolvimento de sistemas de software. De acordo com Magela (2006, p. 98) um padrão de projeto representa “[...] a solução para um problema em um contexto específico que tende a se repetir na construção de todos os softwares para esse mesmo domínio do problema [...]”. Outra definição é apresentada por Arnout (2004), onde é relatado que: Um padrão de projeto de software é um conjunto de ideias arquiteturais de domínio independente. Tipicamente um padrão descreve as classes envolvidas e a colaboração entre as suas instancias, definidas a partir de sistemas do mundo real. Onde as pessoas podem aprender a aplicá-los em projetos de software em resposta a um problema específico. (ARNOUT, 2004, p. 40, tradução nossa). Na tentativa de definir uma base sólida a partir da qual os padrões de projeto são identificados e se tornam úteis para as pessoas, Fowler (2006) descreve que os padrões de projeto podem ser identificados através da observação de problemas que ocorrem na prática, e que a descoberta e a definição de novos padrões estão relacionadas à experiência acerca de determinado problema. Partindo desse princípio, pode-se afirmar que a descoberta de novos
  • 14. 13 padrões se da através da observação de projetos que funcionam e da busca pela essência da sua solução, esse é um processo que exige grande capacidade de análise e experiência na abordagem do problema. Fowler (2006) e Freeman Erich e Freeman Elizabeth (2009) observaram que os padrões de projeto podem ser úteis na comunicação entre os membros de uma equipe ou grupo de trabalho, uma vez que os padrões permitem estabelecer um vocabulário compartilhado na comunicação entre os membros da equipe. “Quando você se comunica usando padrões, está fazendo mais do que apenas compartilhar um dialeto” (FREEMAN, Erich; FREEMAN, Elizabeth, 2009, p. 45). Esse dialeto é a expressão de um conjunto de características, benefícios e restrições que determinado padrão representa. A consequência da adoção de padrões nessa relação de comunicação entre as pessoas possibilita uma compreensão imediata e precisa do problema e das possíveis soluções que estão sendo propostas para o problema. 1.3 Benefícios e limitações A indústria de desenvolvimento de software tem evoluído na última década e vem utilizando cada vez mais recursos de engenharia de software para tornar os processos de desenvolvimento e manutenção de softwares mais ágeis. Em contrapartida a essa tendência existe uma grande dificuldade em projetar software orientado a objetos que seja de fato reutilizável e flexível o suficiente para lidar com as complexidades inerentes ao processo de desenvolvimento e manutenção de software (SHALLOWAY; TROTT, 2004). Gamma et al. (2000, p. 17, grifo do autor) relata que: Projetar software orientado a objetos é difícil, mas projetar software reutilizável orientado a objetos é ainda mais complicado. Você deve identificar objetos pertinentes, fatorá-los em classes no nível correto de granularidade, definir as interfaces das classes, as hierarquias de herança e estabelecer as relações-chave entre eles. O seu projeto deve ser específico para o problema a resolver, mas também genérico o suficiente para atender problemas e requisitos futuros. Também deseja evitar o re-projeto, ou pelo menos minimizá-lo. Os mais experientes projetistas de software orientado a objetos lhe dirão que um projeto reutilizável e flexível é difícil, senão impossível, de obter corretamente da primeira vez. Antes que um projeto esteja terminado, eles normalmente tentam reutilizá-lo várias vezes, modificando-o a cada vez. Gamma et al. (2000) associa os padrões de projeto à experiência adquirida a partir de projetos de software bem sucedidos. Em decorrência disso, os projetistas experientes tendem
  • 15. 14 a reutilizar soluções que já se mostraram eficientes em projetos anteriores. É justamente neste ponto que os padrões de projeto atribuem vantagem àqueles que fazem uso de padrões para a solução de diferentes problemas de projeto. O desenvolvimento de software envolve uma considerável repetição de recursos, onde determinadas aplicações podem compartilhar as mesmas necessidades. A ideia de reuso remete à possibilidade de reutilizar elementos de software que possam ser aplicados em qualquer projeto que necessite explicitamente dessa funcionalidade. Nesse contexto, os padrões de projeto abstraem a questão do reuso, atribuindo a possibilidade da reutilização de padrões Arnout (2004). Dentre as razões pelos quais os padrões de projeto atribuem maior qualidade a projetos de software, Arnout (2004) cita uma lista de benefícios que podem ser aplicados ao desenvolvimento de software:  Cada padrão reúne uma fonte de conhecimento definida a partir da experiência em projetos de software. Uma das consequências disso é que as pessoas sem experiência em desenvolvimento de software podem se beneficiar disso, adquirindo experiência mais rapidamente.  Os padrões contribuem para o desenvolvimento de software de maior qualidade a partir da definição de uma estrutura que permita atribuir extensibilidade ao software.  Os padrões definem uma linguagem comum para discussões de troca de informações, tanto entre os próprios desenvolvedores quanto entre desenvolvedores e gerentes de projeto. Gamma et al. (2000) afirma que projetar sistemas de software de modo que sejam estabelecidas condições reais de reutilização, extensibilidade e facilidade de manutenção é um processo bastante complexo. Considerando o desenvolvimento de um projeto de software a partir do início, é necessário encontrar os objetos corretos, definir interfaces, estabelecer a hierarquia de herança correta entre as classes, entre outras coisas. Considerando ainda que o projeto deva apresentar soluções não apenas para o problema em questão, mas também ser abrangente o suficiente para tratar problemas que possam surgir futuramente, dificilmente será definido a solução ideal para o problema. Gamma et al. (2000, p. 18) relata que: Os padrões de projeto tornam mais fáceis reutilizar projetos e arquiteturas bem-sucedidas. Expressar técnicas testadas e aprovadas as torna mais acessíveis para os desenvolvedores de novos sistemas. Os padrões de projeto
  • 16. 15 ajudam a escolher alternativas de projeto que tornam um sistema reutilizável e a evitar alternativas que comprometam a reutilização. Os padrões de projeto podem melhorar a documentação e a manutenção de sistemas ao fornecer uma especificação explícita de interações de classes e objetos e o seu objetivo subjacente. Em suma, ajudam um projetista a obter mais rapidamente um projeto adequado. Uma das características relevantes dos padrões de projeto é justamente a capacidade que eles têm de apresentar alternativas de reuso de arquiteturas que já foram projetadas, testadas e se mostraram eficientes, assim, evitando alternativas que comprometam a eficiência do sistema de software que está sendo projetado (GAMMA et al., 2000). Para Shalloway e Trott (2004) os motivos pelo qual a utilização de padrões de projeto se torna relevante consistem na sua capacidade de reutilizar soluções e de estabelecer uma terminologia comum. A reutilização de soluções se refere ao fato de reutilizar conceitos a partir da experiência de projetos já estabelecidos, sem ter que reinventar soluções para os mesmos problemas. Já a definição de uma terminologia comum permite estabelecer uma base comum para a comunicação entre os membros de um projeto durante a sua fase de análise e desenvolvimento. A comunicação e o trabalho em equipe requerem uma base de vocabulário e um ponto de vista comum do problema. Os padrões de projeto fornecem um ponto comum de referência durante a fase de análise e elaboração de um projeto. (SHALLOWAY; TROTT, 2004, p. 99). Shalloway e Trott (2004) complementa afirmando que os padrões de projeto também atribuem maior facilidade de modificação em sistemas de software. A maioria dos padrões de projeto torna o software mais passível de modificação. A razão para tal é que eles são soluções comprovadas pelo tempo, portanto, evoluíram em estruturas que podem tratar mudanças mais prontamente do que as que, muitas vezes, vêm primeiro a mente como uma solução. (SHALLOWAY; TROTT, 2004, p. 99). Arnout (2004) questiona a posição de Gamma et al. (2000) em relação à reutilização de soluções proposta por padrões de projeto. Arnout (2004) questiona que a definição de uma solução utilizando padrões deve ser adaptada para cada novo contexto, o que significa que o uso de padrões de projeto não proporciona reusabilidade em termos de código, pois ele precisa ser adaptado a cada novo problema em particular.
  • 17. 16 CAPÍTULO II 2 PADRÕES DE PROJETO GOF Este capítulo faz uma abordagem teórica sobre os padrões de projeto GOF. A seção 2.1 descreve os critérios de classificação dos padrões de projeto GOF. As seções seguintes descrevem os padrões de acordo com as suas finalidades: a seção 2.2 descreve os padrões de criação, a seção 2.3 descreve os padrões estruturais e a seção 2.4 descreve os padrões comportamentais. 2.1 Classificação Gamma et al. (2000) classifica os padrões de projeto a partir dos critérios de finalidade e escopo. A finalidade define o que o padrão faz, um padrão pode ter finalidade de criação, estrutural ou comportamental. O escopo direciona o padrão a relacionamentos entre classes ou objetos. Os padrões direcionados a classes lidam com os relacionamentos entre classes e suas subclasses através do mecanismo da herança, abordando o problema no nível das classes e definindo soluções em tempo de compilação. Já os padrões direcionados a objetos lidam com os relacionamentos entre objetos, que podem ser definidos em tempo de execução através dos recursos de polimorfismo e da composição de objetos. O método de classificação de padrões apresentado em Gamma et al. (2000) são fundamentais para a compreensão dos inúmeros padrões de projeto existentes, além de auxiliar na curva de aprendizagem e na descoberta de novos padrões. O Quadro 1 apresenta os padrões de projeto de acordo com as suas classificações.
  • 18. 17 Quadro 1 – Classificação dos padrões de projeto Finalidade De criação Estrutural Comportamental Factory Method Adapter (class) Interpreter Classe Template Method Abstract Factory Adapter (object) Chain of Responsability Builder Bridge Command Escopo Prototype Composite Iterator Singleton Decorator Mediator Objeto Facade Memento Flyweight Observer Proxy State Strategy Visitor Fonte: Adaptado de Gamma et al. (2000, p. 26) Em relação ao escopo o Quadro 1 mostra dois conjuntos de padrões, um direcionado a classe e outro direcionado a objeto. Em relação à finalidade (propósito), existem três conjuntos de padrões com diferentes finalidades: de criação, estrutural e comportamental. Os padrões de criação no escopo de classe delegam o processo de criação de objetos para as subclasses, enquanto que os de escopo de objeto postergam esse processo para outros objetos. Os padrões estruturais no escopo de classe utilizam a herança para compor classes, enquanto que os de escopo de objeto descrevem estruturas para relacionar objetos. E os padrões comportamentais no escopo de classe utilizam a herança para descrever algoritmos e fluxos de controle, enquanto que aqueles voltados para objetos descrevem como um grupo de objetos se relaciona e compartilha a execução de tarefas (GAMMA et al., 2000). A Figura 1 ilustra graficamente as relações entre os padrões de projeto de acordo com o modo que os padrões mencionam seus inter-relacionamentos.
  • 19. 18 Figura 1 – Relacionamento entre os padrões de projeto Fonte: Gamma et al. (2000, p. 26) 2.2 Padrões de criação Conforme exposto na seção 2.1, os padrões de projeto podem ser classificados de acordo com a sua finalidade e escopo. Gamma et al. (2000) descreve que os padrões de criação têm por finalidade tornar o sistema independente de como os objetos são criados e compostos, a partir da abstração do processo de instanciação dos objetos. Os padrões de criação com escopo de classe utilizam a herança para definir as classes que são instanciadas, enquanto que os padrões de criação com escopo de objeto utilizam fortemente a composição para delegar o processo de criação de objetos (GAMMA et al., 2000).
  • 20. 19 Sistemas de software se tornam complexos a medida que evoluem, e necessitam de mecanismos que forneçam flexibilidade para gerir as modificações no processo de manutenção. Os padrões de criação contribuem no sentido de promover a composição de objetos e não apenas o uso da herança (GAMMA et al., 2000). Os padrões de criação se tornam importantes à medida que os sistemas evoluem no sentido de depender mais da composição de objetos do que da herança de classes. Quando isso acontece, a ênfase se desloca da codificação rígida de um conjunto fixo de comportamentos para a definição de um conjunto menor de comportamentos fundamentais, os quais podem ser compostos em qualquer número para definir comportamentos mais complexos. Assim, criar objetos com comportamentos particulares exige mais do que simplesmente instanciar uma classe. (GAMMA et al., 2000, p. 91). Nesse contexto, o sistema passa a conhecer os seus objetos a partir de classes abstratas e não apenas por classes concretas. Consequentemente, os padrões de criação atribuem flexibilidade e permitem que o sistema seja definido através de objetos que variam amplamente em estrutura e funcionalidade. Os padrões de criação com escopo de objeto são Singleton, Prototype, Builder e Abstract Factory. Em relação ao escopo de classe existe um único padrão, o Factory Method (GAMMA et al., 2000). Para um melhor entendimento da classificação por criação, o padrão Abstract Factory será relatado de forma detalhada mais adiante. 2.2.1 Descrição e objetivos O padrão Singleton estabelece uma maneira de garantir que uma classe tenha somente uma instância a partir da definição de um único ponto de acesso a classe. De acordo com Gamma et al. (2000) o Singleton é útil quando há necessidade de apenas uma instância de uma classe e essa instância tiver que dar acesso aos clientes através de um único ponto, ou quando essa instância tiver que ser extensível através de subclasses, possibilitando aos clientes usar uma instância estendida sem alterar o seu código. O padrão Prototype, segundo Gamma et al. (2000), objetiva a redução do número de classes e a especificação dos tipos de objetos a serem criados usando uma instância protótipo, onde novos objetos podem ser criados a partir de cópias desse protótipo. O Prototype pode ser aplicado quando as instâncias de uma classe puderem ter poucas combinações diferentes de estados.
  • 21. 20 O padrão Builder é descrito por Gamma et al. (2000) como um recurso para separar a construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção possa criar diferentes representações. O padrão pode ser adotado sempre que a lógica para a criação de um objeto complexo for independente das partes que compõem o objeto. O processo de construção deve permitir diferentes representações para o objeto que é construído. 2.2.2 Padrão Abstract Factory O padrão Abstract Factory é responsável por fornecer uma interface para criação de famílias de objetos que se relacionam ou dependem um do outro sem a necessidade de especificar suas classes concretas (FREEMAN, Erich; FREEMAN, Elizabeth, 2009). A família de objetos criada a partir do padrão Abstract Factory é definida por Gamma et al. (2000) como uma família de objetos-produto, que é um conjunto de objetos que de algum modo se relacionam para atingir um determinado objetivo. O padrão Abstract Factory define justamente um tipo abstrato para criar uma família de produtos relacionados. Na definição de Gamma et al. (2000), produtos são objetos concretos que atingem um objetivo específico do sistema, definidos por subclasses de um tipo abstrato. O padrão Abstract Factory ajuda a controlar as classes de objetos criadas por uma aplicação. Uma vez que a fábrica encapsula a responsabilidade e o processo de criar objetos-produto, isola os clientes das classes de implementação. Os clientes manipulam as instâncias através das suas interfaces abstratas. Nomes de classes-produto ficam isolados na implementação da fábrica concreta. (GAMMA et al., 2000, p. 98). A vantagem do padrão Abstract Factory é que ele permite definir uma regra de negócio ao mesmo tempo em que promove baixo acoplamento, tornando o sistema pouco dependente das implementações concretas. Gamma et al. (2000) recomenda o uso do padrão Abstract Factory sempre que for identificado alguma das características a seguir:  Houver independência de como os produtos de um sistema são criados.  O sistema tiver de ser configurado como um produto de uma família de múltiplos produtos.
  • 22. 21  Uma família de objetos for projetada para ser usada em conjunto, e houver a necessidade de garantir esta restrição; Um ponto-chave do padrão Abstract Factory consiste em estabelecer condições para definir um conjunto de classes de produtos de modo que somente suas interfaces sejam responsáveis pelo controle dos recursos, e não suas implementações concretas (GAMMA et al., 2000). A Figura 2 exemplifica a aplicação do padrão Abstract Factory. Figura 2 – padrão Abstract Factory Fonte: Gamma et al. (2000, p. 96) O diagrama da Figura 2 mostra o conceito geral do padrão Abstract Factory. A partir da análise desse diagrama é possível compreender a aplicabilidade do padrão. Como pode ser observado no diagrama, são definidos grupos de famílias de classes que implementam a mesma interface. Gamma et al. (2000) define uma família de classes quando há um conjunto de classes concretas que herdam características de uma mesma classe abstrata. Gamma et al. (2000) relata que a classe AbstractFactory atua como uma fábrica abstrata que contém apenas as assinaturas dos métodos que instanciam fábricas concretas. Cada fábrica concreta é responsável por definir um conjunto específico de recursos do sistema, ela reúne um conjunto de produtos que devem fazer parte do sistema em um determinado contexto. Uma fábrica abstrata permite implementar uma ou várias fábricas concretas, onde cada qual define o uso de um conjunto de produtos para contextos diferentes. Com isso, a possibilidade de definir uma nova regra ou criar uma nova funcionalidade se torna um processo bem definido. Uma fábrica abstrata nos da uma interface para criar uma família de produtos. Ao escrever o código que usa essa interface, desvinculamos nosso
  • 23. 22 código da fábrica real que cria os produtos. Isso nos permite implementar uma variedade de fábricas que fazem produtos para contextos diferentes – como regiões diferentes, sistemas operacionais diferentes ou aparências diferentes. Como nosso código é desvinculado dos produtos reais, podemos substituir fabricas diferentes para obter comportamentos diferentes. (FREEMAN, Erich; FREEMAN, Elizabeth, 2009, p. 135). O papel das fábricas concretas é justamente definir regras de negócio. O diagrama da Figura 2 mostra duas fábricas concretas, ConcreteFactory1 e ConcreteFactory2, que definem regras a partir da seleção de um conjunto de produtos, que juntos atendem a um propósito específico do sistema. No entanto, no nível das fábricas concretas o sistema trata das colaborações entre classes ainda de modo abstrato, pois as fábricas concretas apenas definem a criação de um conjunto de produtos que visam atender a um objetivo ou regra de negócio. Uma vez que o código fica desvinculado dos produtos concretos, pode-se criar ou modificar fábricas para obter comportamentos diferentes (GAMMA et al., 2000). Fábricas concretas apenas cuidam da instanciação de objetos-produto, o processo de criação de produtos concretos fica a cargo das classes de produtos, as quais podem partir desde níveis concretos a níveis abstratos, onde através da herança criam-se classes de produtos concretos. No diagrama da Figura 2, as classes AbstractProductA e AbstractProductB cuidam da implementação de produtos concretos. Segundo Gamma et al. (2000) definir classes que atuam como produtos permite codificar regras de negócio específicas, e isso facilita a reutilização das funcionalidades do produto, sendo que os produtos são compostos em fábricas concretas a medida que a aplicação exige os recursos do produto. Do diagrama da Figura 2 a classe Client são os objetos que interagem com alguma fábrica abstrata. Os clientes apenas necessitam saber qual tipo de abstração estão usando, pois as subclasses do tipo abstrato tratam das implementações concretas, mantendo os clientes vinculados apenas aos tipos abstratos. As fábricas concretas têm conhecimento apenas dos produtos instanciados por elas e as instancias da classe Client não podem fazer referências diretas para os produtos ou fábricas concretas, há apenas a possibilidade de manter referências para a fábrica abstrata. A vantagem desse recurso é que novas fábricas ou produtos podem ser definidos sem qualquer impacto no objeto cliente. Isso torna a codificação flexível e garante coesão e acoplamento (GAMMA et al., 2000). Apesar das vantagens do padrão Abstract Factory, existem algumas desvantagens na sua utilização. Segundo Gamma et al. (2000) o padrão dificulta o suporte a novos tipos de
  • 24. 23 produtos em consequência da complexidade de extensão de fábricas abstratas e criação de novos tipos de produtos. Estender fábricas abstratas para produzir novos tipos de Produtos não é fácil. Isso se deve ao fato de que a interface de AbstractFactory fixa o conjunto de produtos que podem ser criados. Suportar novos tipos de produto exige estender a interface da fábrica, o que envolve mudar a classe AbstractFactory e todas as suas subclasses. (GAMMA et al., 2000, p. 98). No relato de Gamma et al. (2000) a interface da fábrica abstrata fixa um conjunto de produtos que podem ser criados, em consequência disso o suporte a novos tipos de produto exige que a interface da fábrica abstrata seja estendida. 2.3 Padrões estruturais De acordo com Gamma et al. (2000) os padrões de projeto estruturais tem a função de definir o modo como classes e objetos são compostos para formar estruturas maiores. No escopo de classe os padrões estruturais utilizam a herança para compor interfaces. Enquanto que no escopo de objeto os padrões descrevem estratégias para compor objetos em tempo de execução. Os padrões estruturais atribuem flexibilidade ao sistema, obtida principalmente pela sua capacidade de compor objetos em tempo de execução. Os padrões de projeto classificados como estruturais são: Adapter, Bridge, Composite, Decorator, Facade, Flyweight e Proxy (GAMMA et al., 2000). O padrão Adapter será explicado de forma detalhada para demonstrar a aplicabilidade dos padrões classificados como estruturais. 2.3.1 Descrição e objetivos Os padrões de projeto estruturais têm por objetivo descrever métodos de organização de classes e objetos, atribuindo ao sistema maior flexibilidade de adaptação a mudanças e operações de manutenção (GAMMA et al., 2000). O padrão Bridge permite realizar abstrações em objetos, de modo que o objeto se torne independente da sua implementação concreta, e permite que o objeto possa variar independente da sua implementação. Uma abstração pode ser realizada através do uso da herança, onde uma classe abstrata define uma interface para abstrair classes em uma
  • 25. 24 hierarquia, e as subclasses concretas as implementam de maneiras diferentes (GAMMA et al., 2000). O padrão Composite é outro exemplo de um padrão estrutural. Segundo Gamma et al. (2000), o padrão descreve como construir hierarquias de classes em estruturas de árvores, esse mecanismo permite definir objetos simples e compostos para criar hierarquias arbitrariamente complexas. Desse modo, o padrão é aplicado para representar hierarquias de objetos clientes que necessitam tratar um conjunto de objetos em estruturas compostas e de modo uniforme. Isso permite que os objetos clientes sejam capazes de ignorar a diferença entre objetos individuais e a composição de um conjunto de objetos. Segundo Gamma et al. (2000) O padrão Decorator visa atribuir responsabilidades adicionais a um objeto em tempo de execução ao fornecer alternativas para extensões de funcionalidades. [...] Os Decorators fornecem uma alternativa flexível ao uso de subclasses para extensão de funcionalidades [...] Algumas vezes queremos acrescentar responsabilidades a objetos individuais, e não a toda uma classe. Por exemplo, um toolkit para construção de interfaces gráficas de usuário deveria permitir a adição de propriedades, como bordas, ou comportamentos, como rolamento, para qualquer componente da interface do usuário. (GAMMA et al., 2000, p. 170). O padrão Facade (fachada) tem por objetivo fornecer uma interface única para os recursos de um subsistema, abstraindo o acesso aos recursos internos do subsistema. Ao aplicar o padrão define-se uma interface de alto nível que torna o subsistema mais fácil de ser utilizado (GAMMA et al., 2000). Estruturar um sistema em subsistemas ajuda a reduzir a complexidade. Um objetivo comum de todos os projetos é minimizar a comunicação e as dependências entre subsistemas. Uma maneira de atingir esse objetivo é introduzir um objeto facade (fachada), o qual fornece uma interface única e simplificada para os recursos e facilidades mais gerais de um subsistema. (GAMMA et al., 2000, p. 170, grifo do autor). O padrão Flyweight, como o próprio nome sugere, tem por objetivo fornecer uma estrutura para o compartilhamento de objetos leves e que geralmente se encontram em grande número em uma aplicação (GAMMA et al., 2000). O padrão Proxy, segundo Gamma et al. (2000), fornece um objeto substituto responsável por registrar a localização de outro objeto de modo que o acesso a este outro
  • 26. 25 objeto possa ser controlado. Proxy pode ser aplicado sempre que há necessidade de uma referência mais variável do que um simples apontador para um objeto. O padrão Proxy também pode ser adaptado para incluir o padrão Flyweight em situações onde várias cópias de um objeto complexo devem existir. 2.3.2 Padrão Adapter De acordo com Gamma et al. (2000) o padrão Adapter permite que classes com interfaces incompatíveis possam atuar em conjunto através de uma interface única, que permite a um objeto utilizar os serviços de outros objetos com interfaces diferentes. O padrão fornece um adaptador que realiza a comunicação, proporcionando ao sistema um mecanismo de adaptação a mudanças. [...] Em geral, um Adapter faz com que uma interface adaptada (em inglês, adaptee) seja compatível com outra, dessa forma fornecendo uma abstração uniforme de diferentes interfaces. A classe adaptadora (adapter) atinge esse objetivo herdando, privadamente, de uma classe adaptada. O adapter, então, exprime sua interface em termos da interface da classe adaptada. (GAMMA et al., 2000, p. 139). Gamma et al. (2000) subdivide o padrão Adapter em adaptadores de objeto e adaptadores de classe. Basicamente, um adaptador de objeto utiliza a composição de objetos para situações em que o adaptador contenha dois ou mais objetos que necessitam ser adaptados para implementar uma interface alvo, enquanto que um adaptador de classe usa o recurso de herança múltipla para adaptar duas interfaces incompatíveis. As Figuras 3 e 4 mostram os diagramas que representam adaptadores de classe e de objeto. Figura 3 – Padrão Adapter para classes Fonte: Gamma et al. (2000, p. 143)
  • 27. 26 Figura 4 – Padrão Adapter para objetos Fonte: Gamma et al. (2000, p. 143) Ao observar as Figuras 3 e 4 é possível notar que ambos os adaptadores, de classe e de objeto, tem um princípio em comum, realizar o acoplamento da classe Target (alvo), chamada pelo cliente, à classe Adaptee (adaptada). Isso implica que o cliente não sofrerá alterações a medida que necessita se relacionar com a classe Target. Supondo que a interface Adaptee realize algo que o cliente deseja, porém Target e Adaptee sejam interfaces incompatíveis, a classe Adapter realiza essa comunicação (GAMMA et al., 2000). A medida que o sistema se torna complexo e o nível de interação entre as classes cresce, os adaptadores de classe e de objeto assumem características diferentes. Os adaptadores de classe fazem uso de classes concretas para adaptar duas classes incompatíveis, onde Adapter é geralmente uma subclasse da classe adaptada, denominada Adaptee. Um adaptador de classe tem capacidade de substituir apenas os comportamentos da classe adaptada e não funciona quando há necessidade de adaptar simultaneamente as suas subclasses. Em contrapartida, os adaptadores de objeto permitem que uma única classe, denominada Adapter, manipule várias classes simultaneamente, a classe adaptada, denominada Adaptee, e todas as suas subclasses. A medida que o número de classes que implementam a classe adaptada cresce, a capacidade do adaptador de objeto diminui, pois o adaptador deve ter referências a todas as subclasses concretas da classe adaptada (GAMMA et al., 2000). 2.4 Padrões comportamentais De acordo com Gamma et al. (2000) os padrões de projeto comportamentais tem a função de encapsular o comportamento de classes e objetos de modo que os seus níveis de complexidade sejam minimizado. Os padrões comportamentais fornecem flexibilidade ao
  • 28. 27 sistema em função da sua capacidade de definir comportamentos a objetos em tempo de execução. No escopo de classe, os padrões comportamentais descrevem estratégias de relacionamentos entre classes e utilizam a herança para distribuir o comportamento entre os objetos. No escopo de objeto os padrões descrevem estratégias para definir objetos que necessitam de cooperação para a execução de tarefas que exigem a interação mútua de um conjunto de objetos. Os padrões comportamentais se preocupam com algoritmos e a atribuição de responsabilidades entre objetos. Os padrões comportamentais não descrevem apenas padrões de objetos ou classes, mas também os padrões de comunicação entre eles. Esses padrões caracterizam fluxos de controle difíceis de seguir em tempo de execução. Eles afastam o foco do fluxo de controle para permitir que você se concentre somente na maneira como os objetos são interconectados. (GAMMA et al., 2000, p. 139). Os padrões de projeto classificados como comportamentais são: Interpreter, Template Method, Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy e Visitor (GAMMA et al., 2000). 2.4.1 Descrição e objetivos O padrão Chain of Responsibility tem como objetivo definir regras de acoplamento fraco entre objetos remetentes e receptores, fornecendo a vários objetos a oportunidade de atender uma mesma solicitação. Seguindo esse princípio, determinada solicitação é passada ao longo de uma cadeia de objetos até que um deles esteja apto a atender a solicitação. De acordo com Gamma et al. (2000, p. 211-212) o padrão Chain of Responsibility permite: [...] enviar solicitações implicitamente para um objeto através de uma cadeia de objetos candidatos. Qualquer candidato pode satisfazer a solicitação dependendo de condições em tempo de execução. O número de candidatos é aberto e você pode selecionar quais candidatos participam da cadeia em tempo de execução. Chain of Responsibility pode ser aplicado quando há um conjunto de objetos aptos a tratar uma solicitação, porém apenas um dentre estes objetos é o suficiente para tratar a solicitação e este pode ser definido em tempo de execução. A medida que determinado objeto emite uma solicitação sem especificar explicitamente o receptor, a solicitação se propaga ao
  • 29. 28 longo de uma cadeia até que determinado objeto assuma dinamicamente a responsabilidade de atender a solicitação (GAMMA et al., 2000). O padrão Command tem por objetivo encapsular solicitações como objetos, permitindo que os objetos clientes sejam parametrizados com diferentes solicitações. Usos conhecidos do padrão são as operações de copiar e desfazer presentes em um grande número de aplicativos. Em resumo o padrão define uma estrutura de comandos para a implementação de operações que podem ser desfeitas em tempo de execução (GAMMA et al., 2000). O padrão Interpreter está associado à representação de gramáticas. De acordo com Gamma et al. (2000) o padrão descreve metodologias para definir gramáticas para linguagens simples, representar sentenças na linguagem e interpretar essas sentenças. Nesse contexto, o padrão envolve a definição de uma gramática e a representação e interpretação de expressões regulares da gramática. O padrão pode ser aplicado quando houver uma linguagem para interpretar e sentenças dessa linguagem puderem ser representadas como árvores sintáticas abstratas. O padrão Iterator também conhecido como Cursor, fornece um método de acesso aos elementos de um objeto de modo sequencial e sem expor a sua representação interna. Gamma et al. (2000) relata o exemplo de um objeto que constitui uma lista, onde os elementos da lista podem ser acessados a partir de diferentes critérios sem que a sua estrutura interna seja exposta. A ideia principal do padrão é transferir a responsabilidade de acesso e percurso de um conjunto de objeto para um objeto iterator, fornecendo uma interface que percorra diferentes estruturas agregadas. O padrão Mediator abstrair a interação entre um conjunto de objetos. De acordo com Gamma et al. (2000, p. 257) o padrão Mediator tem como objetivo: “[...] definir um objeto que encapsula a forma como um conjunto de objetos se interagem. O Mediator promove o acoplamento fraco ao evitar que os objetos se refiram uns aos outros explicitamente e permite variar suas interações independentemente.” O padrão pode ser aplicado quando a comunicação entre um conjunto de objetos ocorre de modo complexo, onde as interdependências resultantes são difíceis de compreender. A aplicabilidade do padrão promove a reutilização de objetos que mantém uma comunicação com um número arbitrariamente elevado de objetos, pois ele abstrai e estrutura essas relações de comunicação entre os objetos.
  • 30. 29 Segundo Gamma et al. (2000) o padrão Memento registra o estado interno de um objeto sem violar o encapsulamento, de modo que o objeto possa ser restaurado para esse mesmo estado mais tarde. A aplicabilidade do padrão ocorre quando o estado interno de um objeto necessita ser salvo em determinado momento na execução da aplicação, de modo que o objeto possa recuperar o estado salvo posteriormente. O padrão Observer define uma dependência de um para muitos entre objetos, onde existe um objeto que possui informações de interesse para um conjunto de objetos dependentes deste. Quando o objeto de interesse muda de estado, todos os seus dependentes são notificados e atualizados automaticamente. O padrão pode ser aplicado quando um objeto deseja notificar um conjunto indefinido de outros objetos, sem a necessidade de conhecer quais são esses objetos. O tipo de interação disponibilizada pelo padrão Observer também é conhecido como publish-subscribe, onde um objeto de interesse (subject) atua como um publicador de notificações, enviando-as sem ter que saber quem são os objetos observadores (GAMMA et al., 2000). O padrão Observer pode ser aplicado a medida que: [...] uma abstração tem dois aspectos, um dependente do outro. Encapsulando esses aspectos em objetos separados, permite-se variá-los e reutilizá-los independentemente [...] Quando uma mudança em um objeto exige mudanças em outros, e você não sabe quantos objetos necessitam ser mudados [...] Quando um objeto deve ser capaz de notificar outros objetos sem fazer hipóteses, ou usar informações, sobre quem são esses objetos. Em outras palavras, você não quer que esses objetos sejam fortemente acoplados. (GAMMA et al., 2000, p. 275). O padrão State permite que um objeto altere seu comportamento quando o seu estado interno muda. O padrão permite a introdução de uma classe abstrata que, por composição de objetos, pode assumir diferentes comportamentos. Gamma et al. (2000, p. 285) recomenda o padrão State nos seguintes casos: O comportamento de um objeto depende do seu estado e ele pode mudar seu comportamento em tempo de execução, dependendo desse estado [...] Esse estado é normalmente representado por uma ou mais constantes enumeradas. Frequentemente, várias operações conterão essa mesma estrutura condicional. O padrão State coloca cada ramo do comando adicional em uma classe separada. Isto lhe permite tratar o estado do objeto como um objeto propriamente dito, que pode variar independentemente de outros objetos.
  • 31. 30 Segundo Gamma et al. (2000) o padrão Template Method define a estrutura de um algoritmo em uma operação, permitindo que subclasses redefinam certos passos do algoritmo sem mudar a sua estrutura. O conceito apresentado por este padrão torna-o aplicável na implementação de partes de algoritmos que não variam durante a execução da aplicação. Ao identificar as partes que não variam, o padrão delega para as subclasses a implementação do comportamento que pode variar em tempo de execução. O padrão Visitor tem por objetivo representar operações a serem executadas nos elementos de uma estrutura de objetos, permitindo definir uma nova operação sem mudar as classes dos elementos sobre os quais o objeto atua. O padrão permite que sejam adicionadas novas funcionalidades a classe de um objeto sem a necessidade de modificação dessa classe (GAMMA et al., 2000). 2.4.2 Padrão Strategy O padrão Strategy permite definir uma família de algoritmos e encapsular cada algoritmo como uma classe, permitindo que o algoritmo seja definido em tempo de execução e que possa variar independentemente dos clientes que o utilizam (GAMMA et al., 2000). A partir da definição de Gamma et al. (2000) nota-se que podem ser definidas estratégias que permitem configurar uma classe capaz de adquirir um dentre muitos comportamentos que a aplicação pode requerer em tempo de execução. Figura 5 – Padrão Strategy Fonte: Gamma et al. (2000, p. 294) O diagrama exposto na Figura 5 define uma interface comum a todos os algoritmos suportados. A interface denominada Strategy está apta a assumir o comportamento de uma dentre varias classes ConcreteStrategy. Context representa genericamente um objeto em um determinado contexto e usa a interface Strategy para chamar um dado algoritmo, definido por
  • 32. 31 uma das classes ConcreteStrategy. Na origem das colaborações estão os objetos clientes, que passam um objeto ConcreteStrategy para o contexto. O contexto repassa as solicitações dos objetos clientes para sua estratégia em resposta a requisição de cada cliente. Nota-se que os objetos clientes interagem exclusivamente com o contexto, e para cada interface existe uma família de classes ConcreteStrategy onde os objetos clientes decidem em tempo de execução o algoritmo a ser executado (GAMMA et al., 2000). Rocha (2011) aplicou o padrão Strategy para o desenvolvimento de rotinas de geração de eventos aleatórios a partir de distribuições teóricas de probabilidade. A Figura 6 mostra o diagrama de classes envolvido na rotina. Figura 6 – Diagrama de classes envolvido na geração de eventos aleatórios. Fonte: Rocha (2011, p. 16) No diagrama da Figura 6 tem-se que Entity é o contexto, ProbabilityDistribution é a estratégia, e as classes concretas Exponential, Uniform e Constant constituem a família de algoritmos possíveis de serem adotados pela estratégia. A interface ProbabilityDistributionBehavior apenas define regras de comportamento às classes que a implementam (ROCHA, 2011). De acordo com Rocha (2011) essa é uma situação típica onde o padrão Strategy pode ser aplicado, pois as classes concretas de geração de variáveis aleatórias formam uma família
  • 33. 32 de classes que compartilham um comportamento obrigatório, e são capazes de fornecer variáveis aleatórias referentes a uma dada distribuição de probabilidade requisitada em tempo de execução pelo objeto cliente. A vantagem do padrão Strategy nesta situação é que uma nova distribuição teórica de probabilidade pode ser facilmente adicionada ao projeto a partir da criação de uma nova classe que estenda a classe abstrata ProbabilityDistribution e implemente a interface ProbabilityDistributionBehavior (ROCHA, 2011). Cassimiro (2010) utilizou o padrão Strategy para modelar um sistema chamado TMTurismo, como mostra a Figura 7. Figura 7 – Padrão Strategy para os pacotes turísticos. Fonte: Cassimiro (2010, p. 38) De acordo com Cassimiro (2010) o sistema TMTurismo deve ser flexível o suficiente para o atendente modelar um pacote turístico de acordo com a preferência do cliente. Esse
  • 34. 33 fato implica que o cliente vai informar qual o destino quer ir, o tipo de passagem, a hospedagem e as opções de veículo e passeios juntamente com atividades desejadas. O padrão Strategy foi implementado com o intuito de proporcionar alterações nos pacotes turísticos de forma organizada e planejada no código fonte, uma vez que se novos pacotes forem criados ou novos comportamentos adicionados, é necessário apenas herdar da classe abstrata PacoteTuristicoStrategy, no caso da criação de novos pacote, ou criar uma interface com sua família de comportamento e adicionar a sua referência na classe PacoteTuristicoStrategy.
  • 35. 34 CAPÍTULO III 3 PADRÕES DE PROJETO PARA A MELHORIA DA MANUTENABILIDADE Os capítulos anteriores apresentaram os princípios e os fundamentos dos padrões de projeto de software, com o objetivo de discutir neste capítulo as vantagens e as limitações da aplicação desses padrões no processo de manutenção de software, visando a melhoria da manutenabilidade. 3.1 Manutenção de software Pressman (1995) e Sommerville (2003) definem manutenção de software como o processo de modificação de um sistema após a sua conclusão. Esse processo de modificação pode ser simples, destinado a corrigir erros de código, ou significativo, com a finalidade de adicionar novos componentes ou realizar a reestruturação do software. IEEE - Institute of Electrical and Electronics Engineers (1997) relata que as atividades de manutenção iniciam o processo de modificação no ciclo de vida do software. Pressman (1995) e Peters e Pedrycs (2001) categorizam a manutenção de software em quatro grupos: Manutenção adaptativa: modificação do software para mantê-lo utilizável após mudanças no ambiente; Manutenção corretiva: modificação do software para corrigir falhas descobertas após a entrega; Manutenção preventiva: modificação do software antes que ocorram falhas operacionais; Manutenção de aperfeiçoamento: modificação do software para aperfeiçoamento, em função das mudanças da organização ou de regras de negócio. O processo de manutenção de software é uma consequência dos procedimentos de gestão da qualidade realizados na fase de desenvolvimento do projeto. Em função disso, quanto menos definidos esses procedimentos, maiores os defeitos ou falhas que devem ser removidos durante a operação do software (PAULA FILHO, 2003).
  • 36. 35 3.2 Manutenabilidade IEEE (1990, p. 46, tradução nossa) define manutenabilidade de software como “[...] a facilidade com que um sistema ou componente de software pode ser modificado para corrigir falhas, melhorar o desempenho ou outros atributos, ou se adaptar a uma modificação do ambiente”. Seguindo essa mesma orientação, Pressman (1995) descreve a manutenabilidade como a facilidade com que um software pode ser corrigido, adaptado ou ampliado, caso haja a necessidade de inclusão ou alteração nos requisitos funcionais. Gamma et al. (2000) sustenta que os padrões de projeto tem grande influência na manutenabilidade de software. Na medida em que influenciam diretamente em alguns fatores, tais como limitação de dependências de plataforma, viabilização de estruturas em camadas, facilidade de extensão, entre outros, os padrões de projetos elevam o nível de facilidade com que um sistema de software pode ser modificado. Os padrões de projeto também tornam uma aplicação mais fácil de ser mantida quando são usados para limitar dependências de plataforma e fornecer uma estrutura de camadas a um sistema. Eles melhoram a facilidade de extensão ao mostrar como estender hierarquias de classes e explorar a composição de objetos. (GAMMA et al., 2000, p. 41). Prechelt et al. (2001) realizou um experimento com intuito de investigar a efetividade do uso dos padrões Observer, Visitor, Decorator, Composite e AbstractFactory em processos de manutenção de software. Participaram voluntariamente da experiência 29 profissionais da área, os quais foram submetidos a testes de programação utilizando papel e caneta. Os resultados da experiência mostraram efeitos positivos e negativos sobre os padrões analisados. O padrão Observer teve efeito negativo sobre a manutenabilidade, o padrão Visitor se manteve neutro, o padrão Decorator teve efeito positivo, e os padrões Composite e AbstractFactory mostraram-se pouco significativos. Jeanmart et al. (2009) realizou um estudo para avaliar o impacto do padrão Visitor sobre a manutenabilidade de software. Os resultados do estudo mostraram que o padrão Visitor tem um impacto positivo sobre a manutenabilidade de software, diferenciando dos resultados obtidos por Prechelt et al. (2001), no qual o padrão se manteve neutro. No estudo de Jeanmart et al. (2009), apesar do padrão Visitor ter influenciado pouco no esforço de compreensão do software, a sua representação gráfica junto ao diagrama de classes reduziu consideravelmente os esforços nas tarefas de modificação do software.
  • 37. 36 Prechelt et al. (2002) realizou um estudo para analisar a relevância da documentação gerada a partir da aplicação de padrões de projeto, no sentido de facilitar mudanças no processo de manutenção. Os parâmetros considerados no estudo foram o tempo gasto e a eficiência esperada em cada tarefa de modificação do software. No software objeto do estudo foram analisados os padrões Composite, Observer, Template Method, e Visitor, e os resultados mostraram que, com o suporte de uma documentação explícita, as tarefas de manutenção podem ser realizadas mais rapidamente e com menos falhas. Nanthaamornphong e Carver (2011) replicaram o experimento realizado por Prechelt et al. (2001), no qual foi realizado um estudo com foco no impacto que os padrões de projeto têm sobre a manutenabilidade e a compreensão de software. Um novo parâmetro incluído nesse experimento e que não foi considerado por Prechelt et al. (2001), foi a avaliação do nível de compreensão do software. As tarefas de manutenção foram realizadas em duas versões do mesmo software, uma com a presença de padrões, e outra elaborada somente a partir de soluções alternativas aos padrões. Dados estatísticos do estudo indicaram que para as tarefas de manutenção os padrões de projeto não contribuíram para a melhoria da manutenabilidade e compreensão do software. Ng et al. (2006) refizeram o software JHotDrow – um editor de desenho de código fonte aberto – adicionando padrões de projeto em algumas funcionalidades do software. O objetivo do trabalho foi realizar três tarefas de manutenção em funcionalidades similares ao software original e ao software refeito. Dois grupos de pessoas participaram do experimento, um formado por profissionais experientes na área e outro grupo ainda sem experiência prática. Os resultados do experimento mostraram que o tempo gasto nas tarefas de manutenção referente à versão do software refeito foi menor que o tempo gasto na versão original. Outro fator interessante foi que, até mesmo o grupo de pessoas inexperientes, realizaram as tarefas em um espaço de tempo relativamente inferior. Além disso, a solução proposta pelo grupo inexperiente alcançou o mesmo nível de qualidade da solução proposta pelo grupo experiente. [...] Uma vez que os padrões de projeto descritos apoiaram as modificações necessárias no software, as pessoas que utilizaram a abordagem refeita gastaram menos tempo ao analisar os códigos a serem modificados na tarefa de manutenção [...] A parte interessante dos nossos resultados é que, independentemente da experiência das pessoas, o fator tempo usando a abordagem refeita foi acentuadamente menor do que a abordagem direta, mesmo após incluir o tempo gasto no processo de redefinição do software. (NG et al., 2006, p. 9, tradução nossa).
  • 38. 37 Ng et al. (2007) realizaram um estudo empírico para avaliar a relevância dos padrões de projeto aplicados na fase de desenvolvimento do software e os reflexos sobre os processos posteriores de manutenção. O objetivo do trabalho foi analisar a interação entre dois cenários: a aplicação de padrões na fase de desenvolvimento do software e a utilização destes padrões em tarefas futuras de modificação. Os resultados da pesquisa mostraram que os padrões de projeto aplicados na fase de desenvolvimento do software foram efetivamente úteis no sentido de prever mudanças futuras. Estatisticamente o estudo mostrou que há menos falhas de código ao realizar tarefas de modificação a partir de padrões que tenham sido implementados na fase de desenvolvimento do software. Ng, Yu e Cheung (2010) relataram um estudo empírico onde foram investigados os efeitos de cinco fatores humanos que podem influenciar na manutenabilidade do software: exposição prévia dos profissionais aos padrões de projeto; exposição prévia ao software utilizado no estudo; exposição prévia a linguagem de programação; experiência dos profissionais; e soluções alternativas ao uso dos padrões. Foi selecionado para o estudo um software em que já havia a presença de padrões de projeto em sua estrutura, e os resultados mostraram que a exposição prévia ao programa foi o fator mais significativo em termos do tempo gasto na manutenção, a exposição prévia aos padrões de projeto e à linguagem de programação não foram significativos, e o uso de soluções alternativas aos padrões de projeto foi inconclusivo no estudo. Os resultados obtidos em Ng, Yu e Cheung (2010) foram reafirmados em Ng et al. (2012). Além disso, este último estudo identificou um novo fator relevante para a manutenabilidade do software, que consiste no fato de que os profissionais tendem a aplicar soluções mais simples quando essa solução é mais fácil de ser aplicada que a solução proposta por um padrão conhecido. Esse novo fator é descrito no estudo da seguinte maneira: Uso inconsciente de padrões sugere que, se uma solução mais simples do que a solução proposta por um padrão conhecido é identificada, o profissional provavelmente escolherá a solução mais simples. A título de orientação, os desenvolvedores não devem aplicar padrões de projeto para apoiar modificações simplesmente porque determinado padrão é aplicável, também é necessário considerar se há alternativas mais simples. (NG et al., 2012, p. 26, tradução nossa). Em resumo, o estudo concluiu que há três fatores estritamente correlacionados ao tempo despendido na execução de tarefas de manutenção: os padrões de projeto existentes no software; o conhecimento prévio do software; e o uso de soluções alternativas.
  • 39. 38 Vokac et al. (2004) replicaram o experimento realizado por Prechelt et al. (2001). Os resultados do estudo mais recente se diferenciaram do estudo anterior em relação aos padrões Observer e Visitor. Enquanto que a experiência original mostrou efeitos negativos em relação ao padrão Observer, os resultados do estudo mais recentes mostraram dados estatísticos favoráveis ao uso do padrão, uma vez que o padrão Observer se mostrou bastante compreensivo e intuitivo até mesmo pelos profissionais com pouca experiência sobre o padrão. Em contrapartida, enquanto que a experiência original apresentou efeitos positivos em relação ao padrão Visitor, no estudo mais recente o padrão se mostrou significativamente confuso e pouco compreensivo pelos profissionais. Os resultados do estudo indicaram ainda que alguns padrões, tais como Observer e Decorator são relativamente mais fáceis de serem compreendidos e utilizados do que outros. Chatzigeorgiou, Tsantalis e Deligiannis (2008) realizou um estudo empírico para avaliar a habilidade de um grupo de estudantes na compreensão de padrões de projeto. Os estudantes tiveram que desenvolver duas versões de um mesmo software; uma versão aplicando padrões de projeto e outra aplicando soluções alternativas. Os resultados indicaram que a versão do software com a presença de padrões oferecia uma arquitetura bem elaborada, uma vez que padrões foram aplicados corretamente. Em contrapartida, a versão do software sem a presença de padrões apresentou uma arquitetura pobre e com falhas. 3.3 Modularidade De acordo com IEEE (1990) modularidade é o grau com que um sistema ou programa de computador é composto em componentes, de modo que uma mudança em um componente tenha o mínimo de impacto em outros componentes. Shalloway e Trott (2004) relata que a modularidade ajuda a tornar o código mais compreensível, e que essa capacidade de compreensão, por sua vez, o torna mais fácil de manter. A modularidade de software está fortemente relacionada ao conceito de acoplamento e coesão. Esses dois conceitos de software são constantemente utilizados pelos padrões de projeto e influenciam positivamente na modularidade do software (SHALLOWAY; TROTT, 2004).
  • 40. 39 3.3.1 Acoplamento De acordo com IEEE (1990) acoplamento é a medida que define o grau de interdependência entre dois módulos de software. Lino (2011) descreve este mesmo conceito e relata que em sistemas que são estruturados em módulos, devem ser criadas interfaces bem definidas para a comunicação entre os diversos módulos, reduzindo assim o impacto que a modificação de um módulo possa causar no sistema. Gamma et al. (2000), Shalloway e Trott (2004) e Lino (2011) consideram que esse grau de dependência entre módulos deve ser fraco para promover a reusabilidade, e descrevem que os padrões de projeto têm justamente esse objetivo, reduzir as dependências para aumentar a reusabilidade interna do software. Os padrões de projeto que reduzem dependências podem aumentar a reusabilidade interna. O acoplamento mais fraco aumenta a probabilidade de que uma classe de objetos possa cooperar com várias outras. Por exemplo, quando você elimina dependências de operações específicas, pelo isolamento e encapsulamento de cada operação, torna mais fácil a reutilização de uma operação em contextos diferentes [...] (GAMMA et al., 2000, p. 41). Gamma et al. (2000) observa ainda que o acoplamento reduzido também promove portabilidade, facilidade de modificação e extensibilidade em sistemas de softwares. Os padrões de projeto usam técnicas para reduzir o acoplamento e definir camadas para obter sistemas com alto grau de modularidade. São vários os padrões de projeto que promovem efetivamente o acoplamento entre módulos ou componentes de software. Gamma et al. (2000) e Shalloway e Trott (2004) descrevem quatro padrões que atuam no sentido de reduzir o acoplamento de sistemas de software: Chain of Responsability, Facade, Mediator e Observer. 3.3.2 Coesão De acordo com IEEE (1990) a coesão é a intensidade ou grau com que as tarefas executadas por um módulo de software estão relacionadas. Shalloway e Trott (2004) e Ferreira (2011) seguem esse mesmo conceito ao relacionar a coesão ao nível de comunicação entre os elementos internos de um módulo. Lino (2011) afirma que a coesão permite que um módulo ou classe dependa menos dos outros componentes, uma vez que a comunicação interna de cada módulo é otimizada.
  • 41. 40 A quantidade de conexões entre os módulos de um sistema tende a ser menor a medida que o nível de coesão interna de cada módulo aumenta. Isso resulta em um impacto positivo no processo de modificação interna de determinado módulo, uma vez que as consequências desse processo sobre os outros módulos do software são minimizadas (FERREIRA; BIGONHA, M.; BIGONHA, R., 2008). O nível de coesão de um módulo retrata o impacto que o processo de modificação de um módulo causa sobre os outros módulos do software. Gamma et al. (2000) afirma que os padrões de projeto buscam justamente elevar esse nível de coesão, pois a medida que o módulo se torna coeso ele promove a modularidade e consequentemente contribui para a manutenabilidade do software. 3.4 Reusabilidade Freeman Erich e Freeman Elizabeth (2009) relata que os princípios de orientação a objeto como herança, composição, polimorfismo, entre outros, devem estar associados aos padrões de projeto para atribuir facilidade de reutilização em projetos de software. Os padrões de projeto permitem aplicar esses princípios de orientação a objeto considerando um alto nível de abstração para que se possa definir a melhor solução. O desenvolvimento de software envolve uma considerável repetição de recursos, onde determinadas aplicações podem compartilhar as mesmas funcionalidades. Arnout (2004) relata que a concepção de reuso se refere à possibilidade de reaproveitar elementos de software que possam ser utilizados em qualquer projeto que necessite explicitamente dessa funcionalidade. Nesse contexto, os padrões de projeto abstraem o reuso de funcionalidades, atribuindo a possibilidade de reutilização de soluções padronizadas. Gamma et al. (2000) relata que a herança de classe e a composição de objetos são as duas técnicas mais comuns para a reutilização de funcionalidades. Enquanto que a herança de classe é definida em tempo de compilação e é dependente da implementação, a composição de objetos é definida dinamicamente em tempo de execução e exige a obtenção de referências a outros objetos. Assim, a herança e a composição atuam em conjunto e, em função disso, promovem a reusabilidade interna do software e são aplicadas frequentemente aos padrões de projeto.
  • 42. 41 3.5 Uso de interfaces As interfaces são fundamentais em sistemas orientados a objeto. A definição de uma interface consiste em reunir um conjunto de regras para as classes que a implementam. Isso permite que os objetos sejam conhecidos somente através das suas interfaces, e o único modo de obter informações sobre o objeto ou de pedir que ele execute alguma operação é sob o intermédio da sua interface. O benefício do uso de interfaces é que elas permitem especificar um objeto sem definir a sua implementação concreta, consequentemente dois ou mais objetos da mesma interface podem realizar operações de modos diferentes (GAMMA et al., 2000). Gamma et al. (2000) menciona a ligação dinâmica como um recurso bastante explorado ao utilizar interfaces. O entendimento da ligação dinâmica consiste em associar uma solicitação a um objeto e a uma de suas operações em tempo de execução. Quando uma mensagem é enviada a um objeto, a operação específica que será executada depende de ambos, mensagem e objeto receptor. Diferentes objetos que suportam solicitações idênticas, podem ter diferentes implementações das operações que atendem a estas solicitações. A associação em tempo de execução de uma solicitação a um objeto e a uma das suas operações é conhecida como ligação dinâmica. (GAMMA et al., 2000, p. 29, grifo do autor). O uso da ligação dinâmica significa que o envio de uma solicitação não define um fluxo de operação em particular até o momento da execução. Em razão disso o programa é capaz de esperar um objeto com uma interface em particular, sabendo que qualquer objeto que tenha a interface correta está apto a aceitar a solicitação. Além do mais, a ligação dinâmica permite substituir objetos que tenham interfaces idênticas em tempo de execução (GAMMA et al., 2000). De acordo com Gamma et al. (2000) os padrões de projeto permitem definir interfaces pela identificação de seus elementos-chave e pelos tipos de dados que são enviados através de uma interface. Os padrões de projeto também especificam relacionamentos entre interfaces ao exigir que determinadas classes tenham interfaces similares, ou colocam restrições sobre interfaces de determinadas classes. Um exemplo disso pode ser observado nos padrões Decorator e Proxy, ao exigir que as interfaces de objetos Decorator e Proxy sejam idênticas. O padrão Strategy depende fortemente do uso de interfaces ao definir para cada família de algoritmos uma interface comum para todos os algoritmos suportados. No padrão Visitor uma interface deve refletir todas as classes de objetos denominados visitantes.
  • 43. 42 Ao abstrair o processo de criação de objetos, os padrões de criação concedem diferentes maneiras de associar uma interface à sua implementação de forma transparente no momento da instanciação. Os padrões de criação asseguram que o projeto esteja definido em termos de interfaces e não apenas de implementações concretas. Gamma et al. (2000, p. 33) relata o seguinte: “Não declare variáveis como instâncias de classes concretas específicas. Em vez disso, prenda-se somente a uma interface definida por uma classe abstrata [...]” 3.6 Limitações Wendorff (2001) realizou uma análise para averiguar o uso excessivo de padrões de projeto em um amplo sistema comercial. O estudo reportou consequências negativas que a prática do uso excessivo de padrões pode causar nos processos futuros de manutenção. O estudo revelou ainda que muitas vezes os padrões são aplicados sem que haja uma análise prévia das suas consequências. Em função disso a aplicação de padrões pode ter efeitos negativos sobre o software e consequentemente conduzir a processos de reengenharia e altos custos de manutenção no futuro. Gamma et al. (2000) afirmam que cada padrão de projeto se refere a um problema que ocorre com determinada frequência em um contexto específico, descrevendo uma solução para o problema de modo que se possa utilizar essa solução milhares de vezes sem necessariamente seguir o mesmo caminho. Esta asserção é questionada por Arnout (2004), o qual indaga que a definição de uma solução utilizando padrões deve ser adaptada para cada novo contexto, o que significa que o uso de padrões de projeto não proporciona reusabilidade em termos de código, mas sim em termos de uma adaptação a cada problema ou contexto em particular.
  • 44. 43 CONCLUSÃO Padrões de projeto de software são soluções para os problemas que ocorrem com frequência no processo de desenvolvimento de sistemas de software. Pesquisas bibliográficas revelam que os padrões de projeto fornecem alternativas de reuso de soluções que já foram projetadas, testadas e se mostraram eficientes, assim, evitando alternativas que comprometam a eficiência do sistema de software. Os padrões de projeto GOF são classificados em três grupos principais: padrões de criação, que descrevem técnicas para instanciar objetos; padrões estruturais, que descrevem métodos de organização de classes e objetos em estruturas maiores; e padrões comportamentais, que descrevem métodos de atribuição de responsabilidades a classes e objetos. Os avanços na indústria de software vêm requisitando cada vez mais os recursos de engenharia de software para tornar os processos de desenvolvimento e manutenção mais ágeis, menos suscetíveis a erros e a um menor custo. É neste contexto que a proposta dos padrões de projeto ganhou relevância na comunidade de engenharia de software. As soluções propostas por padrões de projeto retratam a experiência de profissionais e de projetos bem sucedidos, definem uma terminologia comum que permite estabelecer um vocabulário compartilhado na comunicação entre os membros da equipe, ajudam na identificação de equívocos ou armadilhas comuns que ocorrem no desenvolvimento de software, e contribuem para o desenvolvimento de software de maior qualidade. Os estudos de caso apresentados neste trabalho monográfico mostraram que a aplicação de padrões de projeto pode levar à construção de software com maior qualidade estrutural e, portanto, de mais fácil manutenção. Os experimentos revelaram indícios de que a aplicação de padrões de projeto na fase desenvolvimento do software é um fator positivo nos processos futuros de manutenção: a documentação gerada a partir da aplicação de padrões de projeto contribuiu para a manutenabilidade, uma vez que o suporte de uma documentação explícita possibilita que as tarefas de manutenção sejam realizadas mais rapidamente e com menos falhas; os padrões Decorator e Observer revelaram-se como os mais fáceis de serem compreendidos e se mostraram bastante intuitivos, sendo utilizados facilmente pelos profissionais com pouca experiência na aplicação destes padrões; o padrão Visitor reduziu os esforços em tarefas de modificação do software, em função da sua representação gráfica junto ao diagrama de classes.
  • 45. 44 Sistemas de software modulares mantém o código compreensível e consequentemente mais fácil de manter. O grau de modularidade depende dos níveis de acoplamento entre módulos e da coesão interna de cada módulo, à medida que o nível de acoplamento é reduzido e o de coesão é elevado, obtém-se um software com maior grau de modularidade. A influência dos padrões de projeto sobre a modularidade do software ocorre através da manipulação direta dos níveis de acoplamento e coesão. Apesar dos benefícios proporcionados, os padrões de projeto também podem ter efeitos negativos no software. A aplicação de padrões sem que haja uma análise prévia das suas consequências pode levar a processos de reengenharia e gerar autos custos de manutenção. Este trabalho monográfico aponta para os seguintes estudos futuros: realização de experimentos em softwares de diferentes tamanhos e propósitos para avaliar a influência dos padrões de projeto sobre o processo de manutenção; realização de trabalhos similares, considerando métricas de software para avaliar a relevância dos padrões de projeto em diferentes aspectos do software.
  • 46. 45 REFERÊNCIAS ALEXANDER, C. The timeless way of building. New York: Oxford University Press, 1979. ARNOUT, K. From patterns to components. 2004. 430f. Dissertação (Tese de doutorado). Swiss federal institute of technology, Zurich, 2004. CASSIMIRO, M. H. O. Padrões arquiteturais e seus benefícios no processo de manutenção do software. 2010, 43f. Trabalho de conclusão de curso (graduação em Ciência da Computação). Faculdade de Ciências Empresariais, Belo Horizonte, 2010. Disponível em: <http://www.ricardoterra.com.br/publications/students/2010_cassimiro.pdf >. Acesso em: 22 maio 2012. CHATZIGEORGIOU, A.; TSANTALIS, N.; DELIGIANNIS, I. An empirical study on students’ ability to comprehend design patterns. Computers & Education, Oxford, UK, v. 51, n. 3, p. 1007-1016, 2008. Disponível em: <http://eprints.csse.uom.gr/5/1/CompEdu_2008.pdf>. Acesso em: 22 maio 2012. FREEMAN, Erich; FREEMAN, Elizabeth. Use a cabeça: padrões de projetos. 2. ed. Rio de Janeiro: Alta books, 2009. FERREIRA, K. A. M.; BIGONHA, M. A. S.; BIGONHA, R. S. Reestruturação de software dirigida por conectividade para redução de custo de manutenção. Revista de informática teórica e aplicada, Porto Alegre, v. 15, n. 2, p. 155-180, 2008. Disponível em: <http://seer.ufrgs.br/rita/article/view/rita_v15_n2_p155-180>. Acesso em: 02 jun. 2012. FERREIRA, K. A. M. Um modelo de predição de amplitude da propagação de modificações contratuais em software orientado por objetos. 2011. 224f. Dissertação (Tese de doutorado). Universidade federal de Minas Gerais, Belo Horizonte, 2011. Disponível em: <http://www.bibliotecadigital.ufmg.br/dspace/bitstream/1843/SLSS- 8GYFSX/1/keciaalinemarquesferreira.pdf>. Acesso em: 02 jun. 2012. FOWLER, M. Padrões de arquitetura de aplicações corporativas. Porto Alegre: Bookman, 2006. GAMMA, E.; HELM, R.; JOHNSON, R.; VLISSIDES, J. Design Patterns: elements of reusable object-oriented software. [S.l.]: Addison-Wesley, 1995. GAMMA, E.; HELM, R.; JOHNSON, R.; VLISSIDES, J. Padrões de projeto: soluções reutilizáveis de software orientado a objetos. São Paulo: Bookman, 2000. IEEE. Standard glossary of software engineering terminology. Std 610.12, 1990, New York: IEEE, ISBN 1-55937-067-X. Disponível em: <http://www.idi.ntnu.no/grupper/su/publ/ese/ieee-se-glossary-610.12-1990.pdf>. Acesso em: 01 jun. 2012.