Você está na página 1de 13

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA PERNAMBUCO

HENRIQUE NUNES MENDES

ENGENHARIA DE SOFTWARE

Padrões de Projeto Grasp e GoF

Jaboatão dos Guararapes


2018
HENRIQUE NUNES MENDES

PESQUISA: ​Padrões de Projeto Grasp e GoF

Pesquisa sobre os padrões de projeto: Grasp e GoF para


o Curso de Informática para Internet, na disciplina de
Engenharia de Software.

Prof. Me Nilson Cândido

Jaboatão dos Guararapes

​2018
Padrão de projeto

Na Engenharia de Software, padrão de projeto​, ​oriundo do inglês: design pattern, é uma


resolução geral para problemas que acontecem constantemente em projetos de software. Um
padrão de projeto não é um projeto concluído que pode ser diretamente transformado em
código fonte ou de máquina, ele é um modelo, fazendo uma analogia, seria como se fosse a
planta de construção de um imóvel, o padrão de projeto tem como objetivo resolver um
problema que pode ser usado em muitas situações diferentes. Padrões são melhores práticas
formalizadas que o programador pode usar para resolver problemas comuns quando projetar
uma aplicação ou sistema. Padrões de projeto orientados a objeto normalmente mostram
relacionamentos e interações entre classes ou objetos, sem especificar as classes ou objetos
da aplicação final que estão envolvidas. Padrões que implicam orientação a objetos ou estado
mutável mais geral, não são tão aplicáveis em linguagens de programação funcional. Padrões
de projeto residem no domínio de módulos e interconexões. Em um nível mais alto há padrões
arquiteturais que são maiores em escopo, usualmente descrevendo um padrão global seguido
por um sistema inteiro.

As características obrigatórias que devem ser atendidas por um padrão de projeto é composto
basicamente por 4 elementos que são:

● Nome​ do padrão;
● Problema​ a ser resolvido;
● Solução​ dada pelo padrão; e
● Consequências​.

Os padrões de projeto:
● visam facilitar a reutilização de soluções de desenho - isto é, soluções na fase de
projeto do software - e
● estabelecem um vocabulário comum de desenho, facilitando comunicação,
documentação e aprendizado dos sistemas de ​software​.
O nome do padrão é um identificador que podemos usar para descrever um problema de
projeto, soluções e conseqüências em uma palavra ou duas. Nomeando um padrão
imediatamente aumenta nosso vocabulário de design. Ele nos permite projetar em um nível
mais alto de abstração. Ter um vocabulário para padrões nos permite falar sobre eles com
nossos colegas, em nossa documentação e até para nós mesmos. Isso faz mais fácil pensar
em projetos e comunicá-los e seus trade-offs para outros. Encontrar bons nomes tem sido uma
das partes mais difíceis de desenvolver nosso catálogo.

O problema descreve quando aplicar o padrão. Isso explica o problema e seu contexto. Pode
descrever problemas específicos de design, como para representar algoritmos como objetos.
Pode descrever classe ou objeto estruturas que são sintomáticas de um design inflexível. Às
vezes o problema incluirá uma lista de condições que devem ser atendidas antes de sentido
aplicar o padrão.

A solução descreve os elementos que compõem o design, seus relacionamentos,


responsabilidades e colaborações. A solução não descrever um projeto concreto específico ou
implementação, porque um padrão é como um modelo que pode ser aplicado em muitas
situações diferentes. Em vez de, o padrão fornece uma descrição abstrata de um problema de
design e como um arranjo geral de elementos (classes e objetos no nosso caso) resolve isto.

As consequências são os resultados e as compensações da aplicação do padrão. Embora as


consequências sejam frequentemente desencadeadas quando descrevemos decisões de
design, eles são críticos para avaliar alternativas de projeto e para entender os custos e
benefícios da aplicação do padrão. As consequências para os softwares frequentemente dizem
respeito a compensações de espaço e tempo. Pode abordar a linguagem e questões de
implementação também. Como a reutilização costuma ser um fator design orientado a objetos,
as consequências de um padrão incluem seu impacto na flexibilidade, extensibilidade ou
portabilidade de um sistema. Listando estes as consequências explicitamente ajudam você a
entendê-las e avaliá-las.
Padrões Grasp (General Responsibility Assignment Software Patterns)

É a base para atribuir responsabilidades a objetos. Os padrões GRASP (General Responsibility


Assignment Software Patterns), são responsáveis pela descrição de princípios de fundamental
importância para a atribuição de responsabilidades em projetos orientados a objetos,
oferecendo um melhor desempenho do código, e trabalhando acerca de solucionar problemas,
garantindo melhor interface do projeto.

Esses padrões são:

*Creator

Decide quem pode ser o criador com base na associação de objetos e sua interação.

Problema​: Quem deve ser responsável para instanciar alguma classe?


Se for feito incorretamente, essa escolha pode afetar coupling,clarity., encapsulação e a
reusabilidade.

Solução​: Abstratamente falando, a solução é de atribuir para uma classe B a responsabilidade


para criar uma instância da classe A.

Prós:

● Facilidade no desenvolvimento do projeto e compreensão.

* Information Expert (​Especialista na informação​)

É conhecido por ser o princípio fundamental para atribuir responsabilidade.

Problema: ​Qual é o princípio geral para atribuição de responsabilidades para objetos?


Solução: ​Atribuir uma responsabilidade ao especialista em informação, ou seja, a classe que
possui as informações necessárias para cumprir a responsabilidade.

Prós:

● Encapsulamento é mantido;
● Fraco acoplamento (facilidade de manutenção);
● Alta coesão (objetos fazem tudo relacionado à sua própria informação);

* High Cohesion

É um padrão de avaliação que tenta manter os objetos gerenciados e compreensíveis

Problema​: Como manter a complexidade sob controle?

Solução​: Atribuir uma responsabilidade para que a coesão se mantenha alta.

Prós:
● Melhor claridade e facilidade de compreensão do projeto;
● Simplificação da manutenção;

*​Low Coupling

É um padrão de avaliação, que determina como atribuir responsabilidades para apoiar.

Problema: ​Como prover baixa dependência entre classes, reduzir o impacto de mudanças e
obter alta reutilização?

Solução: ​Atribuir as responsabilidades de modo que o acoplamento entre classes permaneça


baixo.
Prós:

● Menor dependência entre as classes;


● Mudar de uma classe que tem menor impacto sobre outras classes;
● Maior potencial de reutilização.

*Controller

O padrão controlador atribui a responsabilidade de lidar com os eventos do sistema para uma
classe que representa a um cenário de caso de uso do sistema global.

Problema: ​Quem deve ser o responsável por lidar com um evento de uma interface de
entrada?

Solução: ​Atribuir responsabilidades para receber ou lidar com um evento do sistema para:
● Uma classe que representa todo o sistema ou subsistema;
● Uma classe que representa cenário de caso de uso.

Prós:
● Diminui a sensibilidade da camada de apresentação em relação à lógica de domínio;
● Oportunidade para controlar o estado do caso de uso;

*Polymorphism

É um princípio, no qual subclasses de uma superclasse são capazes de invocar métodos, que
comportam-se de maneira diferente para cada classe derivada.

Problema: ​Como tratar alternativas baseadas no tipo? Como criar componentes de software
“plugáveis”?
Solução: ​É aconselhável atribuir responsabilidades aos tipos usando operações polimórficas,
isso quando alternativas ou comportamento relacionados variam com o tipo da classe.
Prós:

Facilita a manutenção e inserção de um novo tipo de classe.

*​Pure Fabrication
É uma classe que não representa um conceito no domínio do problema deve atender as
seguintes características: baixo acoplamento e potencial de reutilização dos mesmos
derivados.

Solução: ​Quando não se quer violar “High Cohesion” e “Low Coupling” e o “Expert” não
oferece soluções apropriadas que objeto deve ter responsabilidade?

Problema: ​Criar classes artificiais de baixa coesão e alto acoplamento.

Prós:

Apresenta vantagens como a criação de classes muito coesas e remove características não
coesas das classes de domínios de negócios.

*​Indirection

Suporta baixo acoplamento e reusa potencial entre dois elementos, atribuindo a


responsabilidade de mediação entre eles a um objeto intermediário.7

Problema: ​Como evitar acoplamento direto entre duas ou mais classes? Como evitar baixo
acoplamento e manter alta possibilidade de reuso através do desacoplamento de objetos?

Solução: ​Para um objeto intermediário que faz mediação entre componentes e serviços de
modo que esses não sejam diretamente acoplados, será atribuída a responsabilidade.
Prós:

Visa atribuir responsabilidades, de modo que, olha para determinada responsabilidade


determinando assim, as informações necessárias para cumpri-la e, consecutivamente,
determina o local de armazenamento dessa informação.

*Protected Variations

É um princípio básico na motivação de grande parte dos mecanismos e padrões na


programação e no projeto, para fornecer flexibilidade e proteção contra variações.

Problema: ​Como projetar objetos,subsistemas e sistemas, de modo que, as variações ou


instabilidades nesses elementos não sejam responsáveis por impactos indesejáveis em outros
elementos?

Solução:
● Identificar pontos de variação e atribuir responsabilidades para criar uma interface
estável em volta desses pontos;
● Evitar o envio de mensagens a objetos muito distantes.

Prós:

Promove a contenção de variações e instabilidades, durante o projeto de objetos e sistemas,


para que não ocorra a expansão de impactos a outros elementos.
Padrões GoF

Em 1995, Erich Gamma, John Vlissides, Ralph Johnson e Richard Helm descreveram 23
padrões que podem ser aplicados ao desenvolvimento de sistemas de software orientados a
objetos.
- Gamma e seus colaboradores são conhecidos como a Gangue dos Quatro (Gand of Four, GoF).

Não são invenções. São documentação de soluções obtidas através da experiência. Foram
coletados de experiências de sucesso na indústria de software, principalmente de projetos em
C++ e SmallTalk.

Os padrões GoF são divididos entre 3 famílias, são elas:

● Padrões de criação​: Os padrões de criação são aqueles que abstraem e ou adiam o


processo criação dos objetos. Eles ajudam a tornar um sistema independente de como
seus objetos são criados, compostos e representados. Um padrão de criação de classe
usa a herança para variar a classe que é instanciada, enquanto que um padrão de
criação de objeto delegará a instanciação para outro objeto. Os padrões de criação
tornam-se importantes à medida que os sistemas evoluem no sentido de dependerem
mais da composição de objetos do que a herança de classes. O desenvolvimento
baseado na composição de objetos possibilita que os objetos sejam compostos sem a
necessidade de expor o seu interior como acontece na herança de classe, o que
possibilita a definição do comportamento dinamicamente e a ênfase desloca-se da
codificação de maneira rígida de um conjunto fixo de comportamentos, para a definição
de um conjunto menor de comportamentos que podem ser compostos em qualquer
número para definir comportamentos mais complexos. Há dois temas recorrentes
nesses padrões. Primeiro todos encapsulam conhecimento sobre quais classes
concretas são usadas pelo sistema. Segundo ocultam o modo como essas classes são
criadas e montadas. Tudo que o sistema sabe no geral sobre os objetos é que suas
classes são definidas por classes abstratas. Conseqüentemente, os padrões de criação
dão muita flexibilidade no que é criado, quem cria, como e quando é criado. Eles
permitem configurar um sistema com objetos “produto” que variam amplamente em
estrutura e funcionalidade. A configuração pode ser estática (isto é, especificada em
tempo de compilação) ou dinâmica (em tempo de execução).

● Padrões estruturais​: Os padrões estruturais se preocupam com a forma como classes


e objetos são compostos para formar estruturas maiores. Os de classes utilizam a
herança para compor interfaces ou implementações, e os de objeto ao invés de compor
interfaces ou implementações, eles descrevem maneiras de compor objetos para obter
novas funcionalidades. A flexibilidade obtida pela composição de objetos provém da
capacidade de mudar a composição em tempo de execução o que não é possível com a
composição estática (herança de classes).

● Padrões comportamentais​: Os padrões de comportamento se concentram nos


algoritmos e atribuições de responsabilidades entre os objetos. Eles não descrevem
apenas padrões de objetos ou de classes, mas também os padrões de comunicação
entre os objetos. Os padrões comportamentais de classes utilizam a herança para
distribuir o comportamento entre classes, e os padrões de comportamento de objeto
utilizam a composição de objetos em contrapartida a herança. Alguns descrevem como
grupos de objetos cooperam para a execução de uma tarefa que não poderia ser
executada por um objeto sozinho.

Criacional

● Singleton​: assegura que somente um objeto de uma determinada classe seja criado em
todo o projeto;
● Abstract Factory​: permite que um cliente crie famílias de objetos sem especificar suas
classes concretas;
● Builder​: encapsular a construção de um produto e permitir que ele seja construído em
etapas;
● Prototype​: permite você criar novas instâncias simplesmente copiando instâncias
existentes;
● Factory Method​: as subclasses decidem quais classes concretas serão criadas.
*Estruturais

● Decorator​: envelopa um objeto para fornecer novos comportamentos;


● Proxy​: envelopa um objeto para controlar o acesso a ele;
● FlyWeigth​: uma instância de uma classe pode ser usada para fornecer muitas
“instâncias virtuais”;
● Facade​: simplifica a interface de um conjunto de classes;
● Composite​: Os clientes tratam as coleções de objetos e os objetos individuais de
maneira uniforme;
● Bridge​: permite criar uma ponte para variar não apenas a sua implementação, como
também as suas abstrações;
● Adapter​: envelopa um objeto e fornece a ele uma interface diferente;

*Comportamental

● Template Method​: As subclasses decidem como implementar os passos de um


algoritimo;
● Visitor​: permite acrescentar novos recursos a um composto de objetos e o
encapsulamento não é importante;
● Command​: encapsula uma solicitação como um objeto;
● Strategy​: encapsula comportamentos intercambiáveis e usa a delegação para decidir
qual deles será usado;
● Chair of Responsability​: permite dar a mais de um objeto a oportunidade de processar
uma solicitação;
● Iterator​: fornece uma maneira de acessar seqüencialmente uma coleção de objetos
sem expor a sua implementação;
● Mediator​: centraliza operações complexas de comunicação e controle entre objetos
relacionados;
● Memento​: permite restaurar um objeto a um dos seus estados prévios, por exemplo,
quando o usuário seleciona um “desfazer”;
● Interpreter​: permite construir um intérprete para uma linguagem;
● State​: encapsula comportamentos baseados em estados e usa a delegação para
alternar comportamentos;
● Observer​: permite notificar outros objetos quando ocorre uma mudança de estado.
Os padrões freqüentemente são classificados com base num segundo atributo, se lidam ou não
com classes ou objetos.

Referências Bibliográficas

PIERIN, Felipe. ​Classificação dos Padrões de Projeto GoF​. 2011. Disponível em:
<https://brizeno.wordpress.com/2011/12/12/classificacao-dos-padroes-de-projeto-gof/>. Acesso
em: 14 jun. 2018.

SANTOS, Ismael. ​Introdução ao Grasp e GoF. Disponível em:


<https://webserver2.tecgraf.puc-rio.br/~ismael/Cursos/Cidade_FPSW/aulas/Modulo1_Intro_Gra
sp_GoF/Grasp/PadroesGRASP.pdf>.
Acesso em: 11 de jun. de 2018.

HELM, Richard et al. Builder. In: GAMMA, Erich et al. ​Design Patterns: Elements of Reusable
Object-Oriented Software​. [S.l.]: Addison-Wesley, 1994. p. 110-120. Disponível em:
<http://www.uml.org.cn/c++/pdf/DesignPatterns.pdf>. Acesso em: 12 jun. 2018.

Você também pode gostar