MAC 413/5715 - Tópicos de Programação Orientada a
Objetos
Aula 5 - 21/08/2002
Padrões de Projeto de Software
- (ou padrões de desenho de software, ou simplesmente, padrões)
- A idéia de padrões foi apresentada por Christopher Alexander
em 1977 no contexto de Arquitetura (de prédios e cidades):
- Cada padrão descreve um problema que ocorre repetidamente
de novo e de novo em nosso ambiente, e então descreve
a parte central da solução para aquele problema de uma forma
que você pode usar esta solução um milhão de vezes,
sem nunca realiza-la duas vezes da mesma forma.
- Um padrão encerra o conhecimento de uma pessoa muito experiente
em um determinado assunto de uma forma que este conhecimento pode ser transmitido
para outras pessoas menos experientes.
- Outras ciências (p.ex. química) e engenharias possuem
catálogos de soluções
- Desde 1995, o desenvolvimento de software passou a ter o seu primeiro
catálogo soluções para projeto de software: o livro
GoF.
- Passamos a ter um vocabulário comum para conversar sobre projetos
de software. Soluções que não tinham nome passam a ter
nome.
- Ao invés de discutirmos um sistema em termos de pilhas, filas,
árvores e listas ligadas, passamos a falar de coisas de muito mais
alto nível como Fábricas, Fachadas, Observador, Estratégia,
etc.
- A Gangue dos Quatro: o livro surgiu a partir da tese de doutorado do
Erich Gamma; Ralph Johnson
, professor na UIUC é um dos maiores nomes de OO no mundo; John Vlissides
é um especialista em sistemas OO da IBM TJ Watson e Richard Helm eu
não conheço :-)
- A maioria dos autores eram entusiastas de Smalltalk, principalmente
o Ralph Johnson.
- Mas acabaram baseando o livro em C++ para que o impacto junto à
comunidade de CC fosse maior. E o impacto foi enorme, o livro vendeu centenas
de milhares de cópias.
- Existem outros tipos de padrões mas na aula de hoje nos concentramos
nos padrões do GoF
- Todo padrão inclui
- Nome
- Problema
- Solução
- Conseqüências / Forças
- Especificamente os padrões do GoF contém, em geral, as
seguintes seções:
- Nome (inclui número da página)
- um bom nome é essencial para que o padrão caia na
boca do povo
- Objetivo / Intenção
- Também Conhecido Como
- Motivação
- um cenário mostrando o problema e a necessidade da solução
- Aplicabilidade
- como reconhecer as situações nas quais o padrão
é aplicável
- Estrutura
- uma representação gráfica da estrutura de
classes do padrão (usando OMT91)
- às vezes, diagramas de interação (Booch 94)
- Participantes
- as classes e objetos que participam e quais são suas responsabilidades
- Colaborações
- como os participantes colaboram para exercer as suas responsabilidades
- Conseqüências
- vantagens e desvantagens, trade-offs
- Implementação
- com quais detalhes devemos nos preocupar quando implementamos o
padrão
- aspectos específicos de cada linguagem
- Exemplo de Código
- no caso do GoF, em C++ (a maioria) ou Smalltalk
- Usos Conhecidos
- exemplos de sistemas reais de domínios diferentes onde o
padrão é utilizado
- Padrões Relacionados
- quais outros padrões devem ser usados em conjunto com esse
- quais padrões são similares a este, quais são
as dierenças
- Classes de Padrões do GoF
- Padrões de Criação
- Padrões Estruturais
- Padrões Comportamentais
- Vamos ver um exemplo de cada um deles, respectivamente.
Fábrica Abstrata (Abstract Factory (87)) - padrão
de Criação de objetos
- Objetivo: prover uma interface para criação de
famílias de objetos relacionados sem specificar sua classe concreta.
- Motivação: considere uma aplicação
com interface gráfica que é implementada para plataformas diferentes
(Motif para UNIX e outros ambientes para Windows e MacOS). As classes implementando
os elementos gráficos não podem ser definidas estaticamente
no código. Precisamos de uma implementação diferente
para cada ambiente. Até em um mesmo ambiente, gostaríamos de
dar a opção ao usuário de implementar diferentes aparências
(look-and-feels).
Podemos solucionar este problema definindo uma classe abstrata para cada
elemento gráfico e utilizando diferentes implementações
para cada aparência ou para cada ambiente.
Ao invés de criarmos as classes concretas com o operador new
, utilizamos uma Fábrica Abstrata para criar os objetos em tempo de
execução.
O código cliente não sabe qual classe concreta utilizamos.
- Aplicabilidade: use uma fábrica abstrata quando
- um sistema deve ser independente da forma como seus produtos são
criados e representados
- um sistema deve poder lidar com uma família de vários
produtos diferentes
- você quer prover uma bibliteca de classes mas não quer
revelar a sua implementação, quer revelar apenas as suas interfaces
- Estrutura
- Participantes:
- AbstractFactory (WidgetFactory)
- ConcreteFactory (MotifWidgetFactory, WindowsWidgetFactory)
- AbstractProduct (Window, ScrollBar)
- ConcreteProduct (MotifWindow, MotifScrollBar, WindowsWindow,
WindowsScrollBar)
- Client - usa apenas as interfaces declaradas pela AbstractFactory
e pelas classes AbstratProduct
- Colaborações:
- Normalmente, apenas uma instância de ConcreteFactory
é criada em tempo de execução. Esta instância
cria objetos através das classes ConcreteProduct correspondentes
a uma família de produtos.
- Uma AbstractFactory deixa a criação de objetos
para as suas subclasses ConcreteFactory.
- Conseqüências: o padrão
- isola as classes concretas dos clientes.
- facilita a troca de famílias de produtos (basta trocar uma
linha do código pois a criação da fábrica concreta
aparece em um único ponto do programa).
- promove a consistência de produtos (não há o
perigo de misturar objetos de famílias diferentes).
- dificulta a criação de novos produtos (pois temos que
modificar a fábrica abstrata e todas as fábricas concretas.
- Implementação:
- Fábricas abstratas em geral são implementadas como
Singleton (127)
- Na fábrica abstrata, cria-se um método fábrica
para cada tipo de produto.Cada fábrica concreta implementa o código
que cria os objetos de fato
- Definindo fábricas extensíveis.
- normalmente, cada tipo de produto tem o seu próprio método
fábrica; isso torna a inclusão de novos produtos difícil.
- solução: usar apenas um método fábrica
(FamilyProduct make (string type) ).
- isso aumenta a flexibilidade mas torna o código menos seguro
(não teremos verificação de tipos pelo compilador).
- Exemplo de Código:
- Usos Conhecidos:
- InterViews usa fábricas abstratas para encapsular diferentes
tipos de aparências para sua interface gráfica
- ET++ usa fábricas abstratas para permitir a fácil portabilidade
para diferentes ambientes de janelas (XWindows e SunView, por exemplo)
- Sistema de captura e reprodução de vídeo feito
na UIUC usa fábricas abstratas para permitir portabilidade entre diferentes
placas de captura de vídeo.
- Padrões Relacionados:
- Fábricas abstratas são normalmente implementadas com
métodos fábrica (FactoryMethod (107)) mas podem
também ser implementados usando Prototype (117).
- Uma fábrica concreta é normalmente um Singleton
(127)
Composite (163) - padrão Estrutural
- Objetivo: compor objetos em árvores representando hierarquias
todo-parte. Permite que clientes tratem objetos individuais e composições
de objetos da mesma forma.
- Usos conhecidos: compiladores, interpretadores, interfaces gráficas,
controle de estoque, etc.
Estratégia (Strategy (315)) - padrão Comportamental
- Objetivo: definir uma família de algoritmos, encapsular cada
um deles em uma classe e torná-los intercambiáveis. Estratégia
permite que o algortimo varie independentemente dos clientes que o utilizam.
- Usos conhecidos: verificação ortográfica multi-lingüe,
separação silábica, highlight de documentos no
Emacs, sistemas adaptativos, etc.
Outros Padrões que vale a pena estudar
- Singleton (*)
- Adapter
- Bridge
- Decorator
- Façade (*)
- Chain of Responsibility
- Command
- Observer
- State (*)
- Visitor
- na verdade, vale a pena ler o livro inteiro
Referência
- The Gang of Four Book, ou GoF:
Próxima Aula
Aula Anterior
Página de MAC 5715
Página do Fabio
Página do DCC