71
Diagramas de Colaboração e Projeto e Desenvolvimento de Sistemas de Informação UNIVERSIDADE ESTADUAL PAULISTA INSTITUTO DE BIOCIÊNCIAS, LETRAS E CIÊNCIAS EXATAS DEPARTAMENTO DE CIÊNCIAS DE COMPUTAÇÃO E ESTATÍSTICA Diagramas de Colaboração e Padrões GRASP

Diagramas de Colaboração e Padrões GRASPines/cursos/proj-si/materiais... · Padrões Desenvolvedores experientes em OO criaram um repertório de princípios gerais e boas soluções

Embed Size (px)

Citation preview

Diagramas de Colaboração e

Projeto e Desenvolvimento de Sistemas de Informação

UNIVERSIDADE ESTADUAL PAULISTAINSTITUTO DE BIOCIÊNCIAS, LETRAS E CIÊNCIAS EXATASDEPARTAMENTO DE CIÊNCIAS DE COMPUTAÇÃO E ESTATÍSTICA

Diagramas de Colaboração e Padrões GRASP

O que vimos até agora

� Diagramas de Caso de Uso� Casos de uso resumido e completo� Modelo Conceitual� Diagramas de Sequência do Sistema� Diagramas de Sequência do Sistema� Contratos de Operações� Notação dos Diagramas de

Comunicação

Atendente

nome

Leitor

nometipo : char

0..n1..1 0..n1..1

registra

Empréstimo/Devolução

data do empréstimosituação : Char0..n1..1 0..n1..1

faz

1..11..1 possui

Reserva

períodosituacao : char0..n

1..1

0..n

1..1

^

faz

0..1

0..1

0..1

0..1

corresponde a

0..10..1 corresponde a0..n0..n

LinhaDoEmpréstimo

data_prevista_devoluçãodata_entrega_real

1..n1..n

Bibliotecaria

nome

0..10..1

CopiaDoLivro

nro sequencialsituacao : charliberadoParaEmprestimo : char

1..1

0..n

1..1

0..n

< refere-se a

Livro

titulo : String[30]autor : String[30]ano : intISBN : string[20]editora : inttipo : char

0..n1..1 0..n1..1

registra

1..11..1refere-se a >

0..n

1..1

0..n

1..1possui

Objetivo ao final da fase de projeto

Mais a especificação

das interfaces

1

Leitornometipo

calcularDataDevolucao( )

0..*

1

Emprestimodata_do_emprestimosituacao : char

adicionarCopia( )devolverCopia( )

1 0..*

faz

1possui

das interfaces

(métodos)1..*

1

CopiaDoLivronro_sequencialsituacao : charliberadoParaEmprestimo : char

mudarSituacao( )codCopia( )sinalizarDevolucao( )

0..*

LinhaDoEmprestimodata_prevista_devoluçãodata_entrega_real

codCopia( )atualizarDataDev( )

1..*

10..*

refere-se a

Como projetar as responsabilidades de cada objeto

� Sabemos que os objetos precisam se comunicar para completar as operações.

� Os Diagramas de comunicação � Os Diagramas de comunicação mostram escolhas de atribuições de responsabilidades a objetos.

� Mas quem é o melhor candidato para realizar cada uma das operações ou métodos do sistema?

Como projetar as responsabilidades de cada objeto

� Responsabilidade:� Um contrato ou obrigação de um tipo ou uma classe(Booch

e Rumbaugh)� Responsabilidades estão relacionadas às obrigações de um

objeto em termos de seu comportamento.� Dois tipos de responsabilidades básicas:� Dois tipos de responsabilidades básicas:

� Fazer� Fazer algo (criar um objeto, executar uma operação, ...)� Iniciar ações em outros objetos(delegação).� Controlar e coordenar atividades em outros objetos.

� Conhecer� Conhecer dados privados encapsulados.� Conhecer objetos relacionados.� Conhecer dados/atributos que podem ser derivados ou calculados.

Responsabilidades e Diagramas de Interação

� Diagramas de interação mostram escolhas de atribuição de responsabilidade a objetos.

� Exemplo: atribuir aos objetos do tipo � Exemplo: atribuir aos objetos do tipo Venda a responsabilidade de imprimirem a si próprios.

:Vendaimprimir()

Responsabilidade de

imprimir a si própria

Exemplo: Motivação para aplicação de Padrões

� Implementação inchada ou concentradora

Diagrama de Comunicação para a operação

EmprestarFita(fcodigo)

� Implementação inchada ou concentradoraX

� Implementação leve, distribuída

Cod Cópia fita

Emprestar

:Atendente

:CWindowCamada de Interface

açãoExecutada(eventoDaAção)

Sistema Videolocadora

:CWindow

:????

Camada de Interface

Camada do Domínio

emprestarFita(fcodigo)

Videolocadora

Modelo Conceitual

Sistema Videolocadora

possui

10

possui

Comunicação entre os objetos

emprestarFita(fCodigo)----> :Videolocadora clienteCorrente: Cliente

2: emprestimoCorrente := getEmprestimoCorrente

3: criar()

Qual é o problema desta solução?

emprestimoCorrente: Emprestimo

fitas: Fita item: ItemDeEmprestimo

5: associarItem(item)1: fita:=get(fCodigo)

4: associarFita(fita)

Pseudo-código Concentrador VideoLocadora

Classe VideoLocadorafitas: Conjunto;clienteCorrente: Cliente

Método emprestarFita(fCodigo: String)fita:Fita;emprestimoCorrente: Emprestimo;emprestimoCorrente: Emprestimo;item: ItemDeEmprestimo;

fita := fitas.get(fCodigo);emprestimoCorrente := clienteCorrente.getEmprestimoCorrente();item := itemDeEmprestimo.new();Item.associarFita(fita);EmprestimoCorrente.associarItem(item);

Fim Método;FIM Classe;

Comunicação entre objetos (concentrador)

emprestarFita(fCodigo)----> :Videolocadora clienteCorrente: Cliente

5: associarItem(item)

2: emprestimoCorrente := getEmprestimoCorrente

1: fita:=get(fCodigo)

3: criar()

4: associarFita(fita)

emprestimoCorrente: Emprestimo

fitas: Fita item: ItemDeEmprestimo

5: associarItem(item) 4: associarFita(fita)

Diagrama de Comunicação não Concentrador

emprestarFita(fCodigo)----> :Videolocadora

emprestimoCorrente: Emprestimo

5: associarItem()

2: emprestar(fita)1: fita:=get(fCodigo)

clienteCorrente: Cliente

fitas: Fita

item: ItemDeEmprestimo

3: adicionar(fita)

4: criar()

6: associarFita(fita)

2: emprestar(fita)

Código com Responsabilidade Distribuída

Classe VideoLocadorafitas: Conjunto;clienteCorrente: Cliente;

Metodo emprestarFita(fCodigo:string)

fita:Fita;fita:=fitas.get(tCodigo);

Classe Emprestimo

Itens:Conjunto;

Metodo adicionar(fita:Fita);item: ItemDeEmprestimo;

fita:=fitas.get(tCodigo);clienteCorrente.empresta(fita)

Fim Metodo;Fim Classe;

Classe ClienteemprestimoCorrente: Empretimo;

Método emprestar(fita:Fita);emprestimoCorrente.adiciona(fita);

Fim Método;Fim Classe;

item := ItemDeEmprestimo.new();self.associaItem(item);item.associaFita(fita);

Fim Metodo;Fim Classe;

Discussão

� Qual dos códigos é mais fácil de entender e manter?

� Em qual dos códigos as responsabilidades das classes parecem mais intuitivas?

� Para desenvolver um bom projeto, precisamos de princípios para nos guiar na atribuição de responsabilidades -> padrões de projeto OO.

Responsabilidade

� Responsabilidade não é a mesma coisa que um método.� Métodos são implementados para

satisfazer as responsabilidades

� Responsabilidades são implementadas � Responsabilidades são implementadas usando métodos que agem sozinhos ou colaboram com outros métodos e objetos.

� Padrões de projeto são princípios para guiar a atribuição de responsabilidades aos objetos.

Padrões� Desenvolvedores experientes em OO criaram

um repertório de princípios gerais e boas soluções para guiar a construção de software.

� Essas soluções foram descritas em um formato padronizado (nome, problema, solução) e podem ser usadas em outros solução) e podem ser usadas em outros contextos(outros projetos).

� Surgiram com base no trabalho do arquiteto Christopher Alexander, 1977. (Padrões Arquitetônicos).

� Ganharam impulso após a publicação do livro sobre Padrões de Projeto (Design Patterns –Gamma e outros – GoF- 1994)

Padrões

� Padrões usualmente não contem novas idéias � Organizam conhecimentos e princípios existentes,

testados e consagrados.

� Padrão é uma descrição nomeada de um � Padrão é uma descrição nomeada de um problema e uma solução, que pode ser aplicado em novos contextos.

� Nomear padrões melhora a comunicação (cria-se um vocabulário, ou idioma)

Padrões GRASP� GRASP = General Responsability

Assignment Software Patterns.� Descrevem princípios fundamentais de

atribuição de responsabilidades a objetos.� A compreensão dos padrões de projeto � A compreensão dos padrões de projeto

durante a criação de diagramas de comunicação é importante, pois:� São princípios de bons projetos Orientado a

Objetos.� Levam a projetos OO de qualidade.

Padrões GRASP

� Alguns padrões GRASP principais:� Especialista (Expert)� Criador (Creator)� Coesão alta (High Cohesion)� Coesão alta (High Cohesion)� Acoplamento fraco (Low Coupling)� Controlador (Controller)

� Esses padrões abordam questões básicas comuns e tópicos fundamentais de desenvolvimento.

O padrão Especialista (Expert)

� Problema: qual é o princípio mais básico para atribuir responsabilidades em projeto orientado a objetos?em projeto orientado a objetos?

� Solução: Atribuir responsabilidade ao especialista da informação – a classe que tem a informação necessária para satisfazer a responsabilidade.

Exemplo

� No sistema biblioteca, quem seria o responsável por calcular a data de devolução de um livro?devolução de um livro?

Modelo Conceitual Biblioteca

Atendente

nome

Leitor

nometipo : char

0..n1 0..n1

registra

Empréstimo/Devolução

data do empréstimosituação : Char0..n1 0..n1

faz

11 possui

Reserva

períodosituacao : char0..n

1

0..n

1

^

faz

0..1

0..1

0..1

0..1

corresponde a

0..10..1 corresponde a

Livro

0..n

LinhaDoEmpréstimo

data_prevista_devoluçãodata_entrega_real

1..n1..n

Bibliotecaria

nome

0..10..1

CopiaDoLivro

nro sequencialsituacao : charliberadoParaEmprestimo : char

1

0..n

1

0..n

< refere-se a

Livro

titulo : String[30]autor : String[30]ano : intISBN : string[20]editora : inttipo : char

0..n1 0..n1

registra

11refere-se a >

0..n

1

0..n

1possui

Especialista

� A data de devolução ficará armazenada no atributo data_prevista_devolução do objeto LinhaDoEmprestimoobjeto LinhaDoEmprestimo

� Mas quem possui conhecimento necessário para calculá-la?

Modelo Conceitual Biblioteca

Atendente

nome

Leitor

nometipo : char

0..n1 0..n1

registra

Empréstimo/Devolução

data do empréstimosituação : Char0..n1 0..n1

faz

11 possui

Reserva

períodosituacao : char0..n

1

0..n

1

^

faz

0..1

0..1

0..1

0..1

corresponde a

0..10..1 corresponde a

Livro

0..n

LinhaDoEmpréstimo

data_prevista_devoluçãodata_entrega_real

1..n1..n

Bibliotecaria

nome

0..10..1

CopiaDoLivro

nro sequencialsituacao : charliberadoParaEmprestimo : char

1

0..n

1

0..n

< refere-se a

Livro

titulo : String[30]autor : String[30]ano : intISBN : string[20]editora : inttipo : char

0..n1 0..n1

registra

11refere-se a >

0..n

1

0..n

1possui

Especialista

� Pelo padrão especialista, Leitor deve receber essa atribuição, pois conhece o tipo de Leitor (por exemplo, aluno de tipo de Leitor (por exemplo, aluno de graduação, aluno de pós-graduação, professor, etc), que é utilizado para calcular a data em que o livro deve ser devolvido.

Especialista

: Emprestimo

2: criar(d, copiaLivro)

adicionarCopia(copiaLivro)--->

1: d:=calcularDataDevolução()

linh: LinhaDoEmprestimo:Leitor Uso do padrão

Especialista

Especialista: alternativa mais detalhada

: EmprestimoadicionarCopia(copiaLivro)---> copiaLivro: CopiaDoLivro

2: criar(d)

1: d:=calcularDataDevolução()

4: associarLinha(linh)adicionarCopia(CopiaLivro)�

Uso do padrão

Especialista

linh: LinhaDoEmprestimo

:Leitor3: associarCopia(copiaLivro)

1: d:=calcularDataDevolução()

Especialista

� Onde procurar pela classe especialista?� Começar pelas classes já estabelecidas durante o

projeto.� Se não encontrar, utilizar o Modelo Conceitual.

� Lembrar que existem especialistas parciais � Lembrar que existem especialistas parciais que colaboram numa tarefa� Informação espalhada -> comunicação via

mensagens

� Existe uma analogia no mundo real.

� Discussão� É o padrão mais utilizado� Tem uma analogia no mundo real� Coad: “Fazê-lo eu mesmo”� Lembrar que existem especialistas parciais

� Benefícios:� Mantém encapsulamento -> favorece o acoplamento fraco.� O Comportamento fica distribuído entre as classes que tem

a informação necessária (classes “leves”) -> favorece alta

Especialista

a informação necessária (classes “leves”) -> favorece alta coesão.

� Favorece o reuso.� Contra-indicações

� contra indicado quando aumenta acoplamento e reduz coesão

� Ex: quem é responsável por salvar um Empréstimo no banco de dados?

Padrão Criador (Creator)

� Problema: Quem deveria ser responsável pela criação de uma nova instância de alguma classe?

� Solução: atribua à classe B a responsabilidade de criar uma nova instância da classe A se uma das seguintes condições for verdadeira:� B agrega objetos de A� B contém objetos de A� B registra instâncias de objetos de A� B usa objetos de A� B tem os valores iniciais que serão passados para

objetos de A, quando de sua criação

Criador� No sistema da Biblioteca, quem é responsável

pela criação de uma linhaDoEmprestimo

: EmprestimoadicionarCopia(copiaLivro)--->

linh: LinhaDoEmprestimo

2: criar(d, copiaLivro)

:Leitor

1: d:=calcularDataDevolução()

Uso do padrão Criador: Emprestimo contém várias linhas de emprestimo

Empréstimo/Devolução

data do empréstimosituação : Char

CriarLinhaEmprest()

Criador

� Discussão� O padrão guia a atribuição de responsabilidades

relacionadas com a criação de objetos.� Escolha adequada favorece acoplamento fraco

� Objetos agregados, contêineres e registradores � Objetos agregados, contêineres e registradores são bons candidatos à responsabilidade de criar outros objetos

� Algumas vezes o candidato a criador é o objeto que conhece os dados iniciais do objeto a ser criado.

Acoplamento

� Acoplamento: dependência entre elementos (classes, subsistemas, ...). Normalmente resultante de colaboração para atender a uma responsabilidade.

� O acoplamento mede o quanto um objeto está conectado a, tem conhecimento de ou está conectado a, tem conhecimento de ou depende de outros objetos� Acoplamento fraco (ou baixo) – um objeto não

depende de muitos outros.� Acoplamento forte (ou alto) – um objeto depende

de muitos outros.

Acoplamento

� Problemas do acoplamento alto:� Mudanças em classes interdependentes

forçam mudanças locais.� Dificulta a compreensão do objetivo de

cada classe.cada classe.� Dificulta a reutilização.

� Acoplamento fraco é o desejável

Padrão Acoplamento Fraco

� Problema: como apoiar a baixa dependência entre classes e aumentar a reutilização ?

� Solução: Atribuir responsabilidade de � Solução: Atribuir responsabilidade de maneira que o acoplamento permaneça baixo.

Padrão Acoplamento Fraco

� Exemplo: No sistema de biblioteca, suponha que queremos realizar a devolução da cópia do livro. Qual classe deve ser responsável por essa tarefa?

� Alternativas:� Alternativas:� A classe Leitor

� A classe Livro

� A classe Empréstimo

Modelo Conceitual Biblioteca

Atendente

nome

Leitor

nometipo : char

0..n1 0..n1

registra

Empréstimo/Devolução

data do empréstimosituação : Char0..n1 0..n1

faz

11 possui

Reserva

períodosituacao : char0..n

1

0..n

1

^

faz

0..1

0..1

0..1

0..1

corresponde a

0..10..1 corresponde a

Livro

0..n

LinhaDoEmpréstimo

data_prevista_devoluçãodata_entrega_real

1..n1..n

Bibliotecaria

nome

0..10..1

CopiaDoLivro

nro sequencialsituacao : charliberadoParaEmprestimo : char

1

0..n

1

0..n

< refere-se a

Livro

titulo : String[30]autor : String[30]ano : intISBN : string[20]editora : inttipo : char

0..n1 0..n1

registra

11refere-se a >

0..n

1

0..n

1possui

Projeto 1: responsabilidade atribuída ao Leitor

devolveCopia(codCopia)--> leit: Leitor4: atualizarSituacao('devolvida')

cop:=busca(codCopia)devolver(dataDeHoje)

Leitor conhece copias do livro?

copias: CopiaDoLivrolinh: LinhaDoEmprestimo

1: cop:=busca(codCopia)

cop: CopiaDoLivro2: devolver(dataDeHoje)

3: atualizarDataDev(dataDeHoje)

Copia conhece linha do

empréstimo?

Projeto 2: responsabilidade atribuída ao Livro

devolveCopia(codCopia)-->

cop: CopiaDoLivro

3: atualizarSituacao('devolvida')liv: Livro

1: cop:=busca(codCopia)

2: devolver(dataDeHoje)

linh: LinhaDoEmprestimo

copias: CopiaDoLivro 4: atualizarDataDev(dataDeHoje)

Eficiente?

Cópia conhece a linha de

empréstimo?

devolverCopia(codCopia)---> : Emprestimo :LinhaDoEmprestimo

1: *[enquanto encontrou=false] linh:==proximo()

4: [encontrou] atualizaDataDev(dataDeHoje)

2: * [enquanto encontrou = false] cc:=obterCodigoCopia()

3: cc :=CodigoCopia()

6: mudarSituacao('devolvida')

Projeto 3: responsabilidade atribuída ao Empréstimo

linh: LinhaDoEmprestimo cop: CopiaDeLivro

5: sinalizaDevolucao()encontrou := falseenquanto encontrou == false

linh := proxima linha do emprestimo cc:=linh.obterCódigoCópia()encontrou:=(cc==codCopia)

fim-enquantose encontrou

linh.atualizaDataDevolucao(dataDeHoje)fim-se

Qual projeto é melhor?

� Qual dos projetos anteriores favorece o acoplamento fraco?� Projeto 1 e 2 – acoplamento aumenta

(entre cópia do livro e linha do empréstimo, (entre cópia do livro e linha do empréstimo, entre leitor e cópia do livro)

� Projeto 3 – não aumenta acoplamento

PREFERÍVEL

Formas de Acoplamentos

� Um objeto tem um atributo que referencia um objeto de outra classe.

� Um objeto tem um método que referencia um objeto de outra classe.� Parâmetro, variável local ou retorno� Parâmetro, variável local ou retorno

� Um objeto invoca os serviços de um objeto de outra classe.

� Uma classe é subclasse de outra, direta ou indiretamente.

Acoplamento Fraco

� Discussão:� Acoplamento fraco -> classes mais independentes.

� Reduz impacto de mudanças.� Favorece reuso de classes.

� Considerado em conjunto com outros padrões� Considerado em conjunto com outros padrões� Extremo de acoplamento fraco não é desejável

� Fere princípios da tecnologia de objetos – comunicação por mensagens

� Projeto pobre: objetos inchados e complexos, responsáveis por muito trabalho -> baixa coesão

Acoplamento Fraco

� Discussão:� Dica: concentre-se em reduzir o acoplamento em

pontos de evolução ou de alta instabilidade do sistema.

� Benefícios:� Benefícios:� Classes são pouco afetadas por mudanças em

outras partes.� Classes são simples de entender isoladamente.� Conveniente para reutilização.

Coesão� Mede o quanto as responsabilidade de um elemento

(classe, objeto, subsistema,...) são fortemente focalizadas e relacionadas. (coesão funcional)

� Objeto com Coesão Alta -> objetos cujas responsabilidades são altamente relacionadas e que não executa um volume muito grande de trabalho. não executa um volume muito grande de trabalho.

� Objeto com Coesão Baixa -> objeto que faz muitas coisas não relacionadas ou executa muitas tarefas.� Difícil de compreender, reutilizar e manter.� constantemente afetado por mudanças.

Coesão Alta

� Problema: Como manter a complexidade sob controle?

� Solução: Atribuir responsabilidade de tal forma que a coesão permaneça alta.tal forma que a coesão permaneça alta.

Coesão Alta

� Exemplo 1: ( o mesmo para o acoplamento fraco): No sistema de biblioteca, suponha que queremos realizar a devolução da cópia do livro. Qual classe deve ser responsável por essa tarefa?por essa tarefa?� Leitor� Livro� Empréstimo

Projeto 1: responsabilidade atribuída ao Leitor

devolveCopia(codCopia)--> leit: Leitor4: atualizarSituacao('devolvida')

cop:=busca(codCopia)devolver(dataDeHoje)

O Leitor fica parcialmente encarregado da devolução da cópia do livro. Neste exemplo, isso seria aceitável, mas o que aconteceria se houvesse 50 mensagens de outro tipo recebidas por Leitor?

copias: CopiaDoLivrolinh: LinhaDoEmprestimo

1: cop:=busca(codCopia)

cop: CopiaDoLivro2: devolver(dataDeHoje)

3: atualizarDataDev(dataDeHoje)

Projeto 2: responsabilidade atribuída ao Livro

devolveCopia(codCopia)-->

cop: CopiaDoLivro

3: atualizarSituacao('devolvida')liv: Livro

1: cop:=busca(codCopia)

2: devolver(dataDeHoje)

linh: LinhaDoEmprestimo

copias: CopiaDoLivro 4: atualizarDataDev(dataDeHoje)

cop:=busca(codCopia)devolver(dataDeHoje) Parece uma solução melhor. Mas se

houver inúmeras operações a serem feitas com o livro, ocorre o mesmo problema de Leitor.

Projeto 3: responsabilidade atribuída ao Empréstimo

devolverCopia(codCopia)---> : Emprestimo :LinhaDoEmprestimo

1: *[enquanto encontrou=false] linh:==proximo()

4: [encontrou] atualizaDataDev(dataDeHoje)

2: cc:=codigoCopia()

3: cc := codigoCopia()

6: mudarSituacao('devolvida')

Esta é a melhor solução. O objeto empréstimo representa eventos bem definidos no sistema de biblioteca (empréstimo e devolução), por isso é mais intuitivo que ele assuma esta responsabilidade.

linh: LinhaDoEmprestimo cop: CopiaDeLivro

5: sinalizaDevolucao()encontrou := falseenquanto encontrou == false

linh := proxima linha do emprestimo cc:= linh.obter o código da cópia()encontrou:=(cc==codCopia)

fim-enquantose encontrou

linh.atualizaDataDev(dataDeHoje)fim-se

Coesão Alta

� Discussão:� Coesão alta, assim como Acoplamento Fraco, são

princípios que devem ser considerados para a avaliação de projetos de objetos� Má coesão traz acoplamento e vice-versa� Má coesão traz acoplamento e vice-versa

� Regra prática: classe com coesão alta tem um número relativamente pequeno de métodos, com funcionalidades relacionadas, e não executa muito trabalho.

� Analogia com mundo real� Pessoas que assume muitas responsabilidades não

associadas podem tornar-se (e normalmente tornam-se) ineficientes.

Coesão Alta

� Benefícios:� Mais clareza e facilidade de compreensão

do projeto.� Simplificação de manutenção e de � Simplificação de manutenção e de

acréscimo de funcionalidade/melhorias.� Favorecimento do acoplamento fraco.� Aumento no potencial de reutilização

� Classe altamente coesa pode ser usada para uma finalidade bastante específica.

Será que a solução dada para o evento de devolução da cópia é ideal?

� Ainda temos um problema: quando ocorre o evento de devolução da cópia, o objeto empréstimo ao qual a cópia emprestada se refere ainda não é conhecido .refere ainda não é conhecido .

� Portanto, é preciso eleger alguma classe, que conheça os empréstimos, para receber a mensagem devolverCopia.

� Essa classe terá que identificar o objeto empréstimo cujo código de cópia seja igual ao parâmetro fornecido.

A pergunta anterior não está respondida nos slides a seguir. Voltaremos a ela no fim

deste assunto.deste assunto.

Controlador

� É um objeto de interface (entre sistema e mundo externo) responsável por tratar um evento externo (evento de sistema).

� Define (implementa) o método para a operação de sistema. operação de sistema.

Sistema

entrarItem()

terminarVenda()

efetuarPagamento()

Operações de sistema associadas aos eventos de sistema:

Sistema

iniciarDevo(idLei)

devolver(codCop)

FinalizarDevol()

Padrão Controlador

� Problema: Quem deve ser responsável por tratar um evento do sistema (gerado por um ator externo) ?

� Solução: A responsabilidade de receber ou tratar as mensagens de eventos do sistema (operações) pode ser atribuída uma classe que:� Representa o sistema todo, representa o negócio ou � Representa o sistema todo, representa o negócio ou

organização, um dispositivo ou um subsistema (chamado de controlador fachada)

� Representa algo no mundo real que é ativo (chamado de controlador do papel)

� Representa um tratador artificial de todos os eventos de sistema de um caso de uso (Controlador do caso de uso)� TratadorDe<NomeDoCasoDeUso>� ControladorDe<NomeDoCasoDeUso>

Padrão Controlador� Exemplo: Quem vai tratar os eventos do

sistema de biblioteca?

:Atendente:Atendente SistemaSistema

1: iniciarEmpréstimo(id_Leitor)

2: nome e situação do leitor

5: encerrarEmpréstimo()

3: emprestarLivro(id_Livro)

2: nome e situação do leitor

4: dataDeDevolução

* mais livros a emprestar

Cod Cópia Livro

Emprestar

:Atendente

:CWindowCamada de Interface

açãoExecutada(eventoDaAção)

:CWindow

:????

Camada de Interface

Camada do Domínio

emprestarLivro(codCopia)

Objeto de Interface

Exemplo1: Opções de Controlador

� todo o sistema (controlador fachada): Biblioteca

:BibliotecainiciarEmprestimo(…) :ControladorDe

� um tratador artificial do caso de uso: ControladorDeEmprestarLivro

iniciarEmprestimo(…)

61

:Biblioteca:ControladorDe

EmprestarLivro

:BibliotecaemprestarLivro(…)

:ControladorDe

EmprestarLivro

emprestarLivro(…)

:Biblioteca

encerrarEmprestimo() :ControladorDe

EmprestarLivro

encerrarEmprestimo()

Discussão : Controladores Fachada� Um controlador fachada deve ser um objeto

(do domínio) que seja o ponto principal para as chamadas provenientes da interface com o usuário ou de outros sistemas� pode ser uma abstração de uma entidade física –

ex: TerminalDeAtendimento

� pode ser um conceito que represente o sistema –� pode ser um conceito que represente o sistema –ex: Biblioteca

� São adequados quando não há uma quantidade muito grande de eventos de sistema

� Ou quando não é possível redirecionar mensagens do sistema para controladores alternativos (ex: outros subsistemas )

Discussão : Controladores de Caso de Uso

� Deve existir um controlador diferente para cada caso de uso� Por exemplo, o ControladorDeEmprestarLivro

será responsável pelas operações iniciarEmpréstimo, emprestarLivro e encerrarEmpréstimo

� Não é um objeto do domínio, e sim uma construção artificial para dar suporte ao sistema.

� Não é um objeto do domínio, e sim uma construção artificial para dar suporte ao sistema. Ex: ControladorDeEmprestarLivro, ControladorDeDevolverLivro

� Pode ser uma alternativa se a escolha de controladores fachada deixar a classe controladora com alto acoplamento e/ou baixa coesão (controlador inchado por excesso de responsabilidades)

� É uma boa alternativa quando existem muitos eventos envolvendo diferentes processos.

Controladores inchados� Classe controladora mal projetada - inchada

� coesão baixa – falta de foco e tratamento de muitas responsabilidades

� Sinais de inchaço: � uma única classe controladora tratando todos os

eventos, que são muitos. Comum com eventos, que são muitos. Comum com controladores fachada

� o próprio controlador executa as tarefas necessárias para atender o evento, sem delegar para outras classes (coesão alta, não especialista)

� controlador tem muitos atributos e mantém informação significativa sobre o domínio, ou duplica informações existentes em outros lugares

Possíveis soluções para controladores inchados

� Acrescentar mais controladores.� Projetar o controlador de forma que ele

possa delegar o atendimento da responsabilidade de cada operação de sistema a outros objetos.

� Cuidado: Controladores de papéis podem conduzir a maus projetos(armadilha de projetar objetos semelhantes a pessoas para fazer todo o trabalho – é preciso delegar)

Corolário do Padrão Controlador

� Objetos de interfaces HM ( como objetos “janela”) e da camada de apresentação não devem ter a apresentação não devem ter a responsabilidade de tratar eventos do sistema (arquitetura em camadas)

Benefícios do Padrão Controlador e seu corolário

� Benefícios:� aumento das possibilidades de reutilização

de classes e do uso de interfaces “plugáveis”. “plugáveis”.

� conhecimento do estado do caso de uso –controlador pode armazenar estado do caso de uso, garantindo a seqüência correta de execução de operações

Cod Cópia Livro

Devolver

:Atendente

:CWindowCamada de Interface

açãoExecutada(eventoDaAção)

devolverCopia?

????:Emprestimo

devolverCopia(codCopia)

:CWindowCamada de Interface

Camada do Domínio

devolverCopia(codCopia)

Voltando ao problema do slide 57....

� Qual era o problema:� devolverCópia x Empréstimo

� Qual é a solução?� Qual é a solução?� Classe Fachada ou Controladora

Cod Cópia Livro

Devolver

:Atendente

:CWindowCamada de Interface

açãoExecutada(eventoDaAção)

devolverCopia?

:Biblioteca:Emprestimo

devolverCopia(codCopia)

:CWindowCamada de Interface

Camada do Domínio

devolverCopia(codCopia)

Próximo assuntoRefinarPlano

Sincronizarartefatos

Analisar Projetar Construir Testar

Padrões GRASP

Estudo de Caso TPV : Projetar uma solução com objetos e

Padrões GRASP