Análise e Projeto
Orientados a Objeto
com UML e Padrões
© Nabor C. Mendonça 2001
1
Da Análise ao Projeto

Artefatos de análise capturam os resultados da
investigação do domínio do problema
Artefato
Questões Respondidas
Quais são os cenários usuário-sistema?
Casos de uso
Quais são os conceitos e seus relacionamentos?
Modelo conceitual
Diagramas de seqüência Quais são as operações do sistema?
Contratos

O que fazem as operações do sistema?
Artefatos de projeto capturam uma solução para o
problema baseada no paradigma de OO
–
Diagramas de colaboração e classe de projeto
–
Atribuição de responsabilidades e uso de padrões
© Nabor C. Mendonça 2001
2
Definindo Diagramas de Colaboração
Um Ciclo de Desenvolvimento
Refin.
Plano
© Nabor C. Mendonça 2001
Sinc.
Artefatos
Análise
Notas
Projeto
Impl.
a. em paralelo com
diag. interação
b. ordem variada
Teste
1. Definir Casos de
Uso Reais
2. Definir Rel. & IU
4. Definir Diag.
Colaboração
5. Definir Diag.
Classe
3. Refinar
Arquitetura
a
b
6. Definir Esquema
do BD
3
Diagramas de Colaboração

Um diagrama de colaboração ilustra as interações
de mensagens entre objetos do modelo do
domínio (diagrama de classe, simplificado), para
realizar uma operação de sistema
–
Atribuição de responsabilidades aos objetos
–
Ponto de partida é o cumprimento das póscondições especificadas no contrato da operação
Baseado na suposição de que as pré-condições da operação
são satisfeitas
© Nabor C. Mendonça 2001
4
Diagramas de Colaboração

Diagrama de colaboração
–
Ilustra interações num formato de grafo ou rede
message1()
:ClassAInstance
1: message2()
2: message3()
:ClassBInstance
–
A mensagem não-numerada (a primeira) é uma
operação de sistema
–
Note que mandar uma mensagem m() para um
objeto X corresponde a executar o código X.m(), isto
é, invocar o método m() de X
© Nabor C. Mendonça 2001
5
Diagramas de Colaboração

Exemplo para a operação fazerPagamento, do
sistema ProcessarVendas de um supermercado
direction of message
makePayment(cashTendered)
:POST
first internal message
1: makePayment(cashTendered)
link line
1.1: create(cashTendered)
first message
:Payment
instance
© Nabor C. Mendonça 2001
:Sale
parameter
6
Como Fazer um Diagrama de Colaboração

Regras úteis
1. Criar um diagrama em separado para cada uma das
operações de sistema sendo desenvolvidas na
iteração corrente
- Para cada mensagem de operação de sistema, criar um
diagrama com essa mensagem como mensagem inicial
2. Se um diagrama fica muito complexo (não cabe
facilmente num folha de papel A4), o diagrama deve
ser dividido em diagramas menores
3. Usar as pós-condições dos contratos de operação,
e a descrição dos casos de uso para projetar um
sistema cujo objetos interagem para cumprir as
tarefas exigidas, segundo o modelo do domínio
© Nabor C. Mendonça 2001
7
Diagramas de Colaboração e Outros Artefatos
Modelo do
Domínio
Cashier
System
Operation: enterItem
enterItem
(upc,
quantity)
Postconditions:
1. If a new sale, a new
Sale has been created...
enterItem(upc, qty)
:POST
endSale()
makePayment(amount)
Operation: makePayment
makePayment
(amount)
System
Sequence
Diagram
© Nabor C. Mendonça 2001
Postconditions:
1. ...
Contracts
:POST
Collaboration
Diagrams
8
Notação Básica

Classes e instâncias
Sale
:Sale
class

instance
s1: Sale
named instance
Links
msg1()
:POST
1: makePayment(cashTendered)
:Sale
link line
© Nabor C. Mendonça 2001
9
Notação Básica

Mensagens
1: message1()
2: message2()
3: message3()
msg1()
:POST
:Sale
all messages flow on the same link

Parâmetros
parameters
msg1()
1: makePayment(amount: Money)
:POST
© Nabor C. Mendonça 2001
:Sale
10
Notação Básica

Valor de retorno
return value type
msg1()
1: tot := total(): Real
:POST
:Sale
return value name
© Nabor C. Mendonça 2001
11
Notação Básica

Mensagem para “self” ou “this”
msg1()
:POST
1: clear()

Iteração
iteration
recurrence values omitted
msg1()
1*: li := nextLineItem(): SalesLineItem
:POST
© Nabor C. Mendonça 2001
:Sale
12
Notação Básica

Cláusula de iteração
iteration clause
msg1()
1*: [i := 1..10] li := nextLineItem(): SalesLineItem
:POST

:Sale
Iteração com múltiplas mensagens
msg1()
1*: [i := 1..10] msg2()
:A
myB :B
2*: [i := 1..10] msg3()
myC :C
msg1()
{
for i := 1 to 10
{
myB.msg2()
myC.msg3()
}
}
note that iteration
clauses are equal
© Nabor C. Mendonça 2001
13
Notação Básica

Criação de instância
create message, with
optional initializing
parameters
msg1()
1: create(cashier)
:POST
:Sale
new created instance
«new»
:Sale
"«new»" is optionally
allowed for emphasis
© Nabor C. Mendonça 2001
14
Notação Básica

Seqüenciamento de mensagens
not numbered
msg1()
:ClassA
1: msg2()
:ClassB
1.1: msg3()
legal numbering
© Nabor C. Mendonça 2001
:ClassC
15
Notação Básica

Seqüenciamento complexo de mensagens
first
second
third
msg1()
;ClassA
1: msg2()
:ClassB
1.1: msg3()
2.1: msg5()
2: msg4()
fourth
:ClassC
2.2: msg6()
fifth
sixth
:ClassD
© Nabor C. Mendonça 2001
16
Notação Básica

Mensagens condicionais
conditional message, with test
msg1()
1: [nova venda] create()
:TV
:Venda
1.1: create()
:LinhaDeVenda
© Nabor C. Mendonça 2001
17
Notação Básica

Caminhos condicionais mutuamente exclusivos
unconditional after
either msg2 or msg4
:ClassE
1a and 1b are mutually
exclusive conditional paths
2: msg6()
msg1()
1a: [test1] msg2()
:ClassA
:ClassB
1b: [not test1] msg4()
:ClassD
© Nabor C. Mendonça 2001
1b.1: msg5()
1a.1: msg3()
:ClassC
18
Notação Básica

Operação entrarItem() (diagrama parcial)
conditional message, with test
entrarItem()
1: [nova venda] create()
:TV
:Venda
2: [velha venda]
criarLinhaDeVenda()
3: create()
:LinhaDeVenda
Note que mensagens condicionais simulam IF ... THEN ... ELSE
© Nabor C. Mendonça 2001
19
Notação Básica

Coleções (multiobjects)
Sale
sales : Sale

multiobject
Mensagens para uma coleção
message sent to the
collection object itself
msg1()
1: s := size() : int
:Sale
© Nabor C. Mendonça 2001
SalesLineItem
:SalesLineItem
20
Notação Básica

Mensagens para uma coleção e um elemento
msg1()
1: create()
:Sale
2: addElement(sl)
sl: SalesLineItem
SalesLineItem
:SalesLineItem
msg1()
2: print()
:Sale
sl: SalesLineItem
1: sl := get(key)
© Nabor C. Mendonça 2001
SalesLineItem
:SalesLineItem
21
Responsabilidades e Métodos

Responsabilidade é “um contrato ou obrigação de
um tipo ou classe” [Booch et al.’97]
–

Relacionada com o comportamento dos objetos
Dois tipos básicos:
–
De conhecer (alguma coisa)
Ex.: dados privados encapsulados, objetos relacionados,
informação derivada ou calculada
–
De fazer (alguma coisa)
Ex.: Fazer algo individualmente, iniciar uma ação em outros
objetos, controlar ou coordenar atividades em outros objetos
© Nabor C. Mendonça 2001
22
Responsabilidades e Métodos

Responsabilidade são atribuídas aos objetos do
sistema durante o projeto OO
–
Exemplos:
“Uma Venda é responsável por imprimir a si própria”
(de fazer)
“Uma Venda é responsável por conhecer sua data”
(de conhecer)

Tradução para classes e métodos influenciada pela
granulosidade da responsabilidade
–
Um único método para “imprimir venda”
–
Dezenas de métodos para “prover um mecanismo
de acesso a SGBD relacionais”
© Nabor C. Mendonça 2001
23
Responsabilidades e Métodos

Métodos são implementados para cumprir
responsabilidades
–

Podem agir sozinhos ou em colaboração com outros
métodos e objetos
Exemplo
–
A classe Venda pode definir um método específico
para cumprir a responsabilidade de impressão
–
Esse método, por sua vez, pode precisar colaborar
com outros objetos, possivelmente enviando
mensagens de impressão para cada um dos objetos
Item-de-Venda associados à Venda
© Nabor C. Mendonça 2001
24
Responsabilidades e Diagramas de Interação

Diagramas de interação ilustram decisões na
atribuição de responsabilidades a objetos
–
Quais mensagens são enviadas para diferentes
classes e objetos?
implies Sale objects have a
responsibility to print
themselves
print()

1*: [i:= 1..N]] sli := next()
:Sale
2*: [i:=1..N] : print()
SalesLineItem
:SalesLineItem
sli:SalesLineItem
Guias práticos para facilitar a tomada de decisões
na atribuição de responsabilidades são oferecidos
pelos padrões GRASP
© Nabor C. Mendonça 2001
25
Padrões

Nome e descrição de um problema comum de
domínio e sua respectiva solução
–


Expresso de modo que o padrão possas ser
aplicado a novos contextos e circunstâncias
variadas
Capturam princípios fundamentais de engenharia
de software
Podem oferecer guias de como responsabilidades
devem ser atribuídas a objetos, dada uma
categoria específica de problema
© Nabor C. Mendonça 2001
26
Padrões

Em geral, não contêm novas idéias nem soluções
originais
–

Possuem nomes sugestivos
–

Codificam soluções existentes comprovadas
Suportam fácil incorporação ou abstração do
conjunto de conceitos representado pelo padão
Facilitam comunicação
–
Permitem a discussão de um princípio ou conceito
complexo através de um único nome
© Nabor C. Mendonça 2001
27
Padrões GRASP


Princípios gerais para atribuição de
responsabilidades a objetos
–
Cruciais no POO
–
Parte da criação de diagramas de interação
Cinco padrões mais comuns:
–
Especialista (“Expert”)
–
Criador (“Creator”)
–
Alta coesão (“High Cohesion”)
–
Baixo acoplamento (“Low Coupling”)
–
Controlador (“Controler”)
© Nabor C. Mendonça 2001
28
Padrão Especialista

Problema
–

Solução
–

Qual é o princípio mais básico pelo qual
responsabilidades são atribuídas no POO?
Atribuir responsabilidade para o especialista na
informação — a classe que tem a informação
necessária para cumprir a responsabilidade
Exemplo
–
Quem deve ser responsável por conhecer o total de
uma venda?
Informação necessária: conhecer todas as instâncias Item-deVenda da Venda e o subtotal de cada uma delas
© Nabor C. Mendonça 2001
29
Padrão Especialista

Exemplo (cont.)
–
Pelo padrão, a classe Venda deve ser a responsável
t := total()
Venda
:Venda
data
tempo
Novo método
–
total()
Mas quem dever ser responsável por conhecer o
subtotal de um Item-de-Venda?
Informação necessária: Item-de-Venda.quantidade e
Especificação-Produto.preço
© Nabor C. Mendonça 2001
30
Padrão Especialista

Exemplo (cont.)
–
Pelo padrão, a classe Item-de-Venda deve ser a
responsável
t := total()
1*: [i:=1..N]] sli := next()
:Venda
Venda
data
tempo
2*: [i:=1..N] st := subtotal()
total()
sli:LinhaDeVenda
SalesLineItem
:LinhaDeVenda
LinhaDeVenda
quantidade
New method
–
subtotal()
Porém, para cumprir essa responsabilidade um
Item-de-Venda precisa conhecer o preço do Item
© Nabor C. Mendonça 2001
31
Padrão Especialista

Exemplo (cont.)
–
Portanto, o Item-de-Venda deve mandar uma
mensagem para a Especificação-Produto para saber
o preço do item
t := total()
1*: [i:=1..N]] sli := next()
:Venda
Venda
data
tempo
2*: [i:=1..N] st := subtotal()
total()
sli:inhaDeVenda
SalesLineItem
:LinhaDeVenda
LinhaDeVenda
quantidade
2.1: p := preco()
subtotal()
:Especificacao
Produto
Especificacao
Produto
descricao
preco
UPC
New method
© Nabor C. Mendonça 2001
preco()
32
Padrão Especialista

Exemplo (cont.)
–
Concluindo, para cumprir a responsabilidade de
conhecer e comunicar o total da venda, três
responsabilidades foram atribuídas a três classes de
objetos
Classe
© Nabor C. Mendonça 2001
Responsabilidade
Venda
conhece total da venda
Item-de-Venda
conhece subtotal do item
Especificação-Produto
conhecer preço do produto
33
Padrão Especialista


Benefícios
–
Mantém encapsulamento (baixo acoplamento)
–
Comportamento é distribuído através das classes
que tem a informação necessária para cumprir a
responsabilidade (alta coesão)
Também conhecido como
–
“Quem sabe, faz”
–
“Faço eu mesmo”
–
“Cada serviço com seus atributos”
© Nabor C. Mendonça 2001
34
Padrão Criador

Problema
–

Quem deve ser responsável por criar uma nova
instância de alguma classe?
Solução
–
Atribuir à classe B a responsabilidade de criar uma
instância da classe A se:

B agrega instâncias de A

B contém instâncias de A

B registra instâncias de A

B usa bem de perto instâncias de A
B tem os dados de inicialização para criar instâncias de A
(B portanto é um especialista na criação de A)

© Nabor C. Mendonça 2001
35
Padrão Criador

Exemplo
–
Quem deve ser responsável por criar uma instância
de Item-de-Venda?
–
Pelo padrão, Venda deve ser responsável.
criarLinhaDeVenda(quantidade)
Venda
:Venda
1: create(quantidade)
New method
data
tempo
criarLinhaDeVenda()
total()
:LinhaDeVenda

Benefícios
–
Suporta baixo acoplamento
© Nabor C. Mendonça 2001
36
Padrão Baixo Acoplamento

Problema
–

Solução
–

Como conseguir menor dependência (entre as
classes) e maior reuso?
Atribuir a responsabilidade de modo que o
acoplamento (dependência entre classes)
permaneça baixo
Exemplo
–
Quem deve ser responsável por criar um Pagamento
e associá-lo à Venda?
–
Pelo padrão Criador, poderia ser POST (uma vez que
POST “registra” pagamentos no mundo real)
© Nabor C. Mendonça 2001
37
Padrão Baixo Acoplamento

Exemplo (cont.)
fazerPagto()
:TV
1: create()
p : Pagto
2: addPagto(p)
–
:Venda
Uma solução melhor, (que preserva baixo
acoplamento) é a própria Venda criar o Pagamento
fazerPagto()
:TV
1: fazerPagto()
:Venda
1.1. create()
:Pagto
© Nabor C. Mendonça 2001
38
Padrão Baixo Acoplamento

Benefícios
–
Responsabilidade não é (ou é pouco) afetada por
mudanças em outros componentes
–
Responsabilidade é mais simples de entender
isoladamente
–
Maior chance para reuso
© Nabor C. Mendonça 2001
39
Padrão Alta Coesão

Problema
–

Solução
–

Como manter a complexidade (das classes) em um
nível “controlável”?
Atribuir a responsabilidade de modo que a coesão
(força do relacionamento entre as responsabilidades
de uma classe) permaneça alta
Exemplo
–
–
Quem deve ser responsável por criar um Pagamento
e associá-lo à Venda?
Pelo padrão Criador, seria TV. Mas se TV for o
responsável pela maioria das operações do sistema,
ele vai ficar cada vez mais sobrecarregado e não
coeso
© Nabor C. Mendonça 2001
40
Padrão Alta Coesão

Níveis de coesão
–
Muito baixa
Um classe tem muitas responsabilidades em áreas funcionais
bastantes diferentes
–
Baixa
Um classe é responsável por uma tarefa complexa de uma
única área funcional
–
Moderada
Um classe tem moderadas responsabilidades em uma única
área funcional e colabora com outras classes para cumprir
suas tarefas
–
Alta
Um classe tem responsabilidades leves apenas em algumas
áreas que estão logicamente relacionadas com o conceito da
classe
© Nabor C. Mendonça 2001
41
Padrão Alta Coesão

Benefícios
–
Aumento da clareza e compreensão do projeto
–
Simplificação de manutenção
–
Baixo acoplamento
–
Reuso facilitado
© Nabor C. Mendonça 2001
42
Padrão Controlador

Problema
–

Quem deve ser responsável por tratar um evento do
sistema?
Solução
–
Atribuir a responsabilidade de tratar um evento do
sistema para uma classe “controladora”
representando:

o sistema como um todo (facade controller)

o negócio ou organização com um todo (facade controller)
uma coisa ou papel de uma pessoa do mundo real envolvida
diretamente com a tarefa (role controller)

um “tratador” (handler) artificial para todos os eventos de um
caso de uso (use-case controller)

© Nabor C. Mendonça 2001
43
Padrão Controlador

Exemplo
–
Pelos padrões Baixo Acoplamento e Alta Coesão, a
melhor escolha como controlador é POST
Sistema
terminarVenda()
entrarItem()
fazerPagto()
system operations
discovered during system
behavior analysis
© Nabor C. Mendonça 2001
TV
...
terminarVenda()
entrarItem()
fazerPagto()
allocation of system
operations during design,
using the Controller pattern
44
Download

Venda