Apoo Jacques Ufcg

221
Análise e Projeto de Sistemas Orientados a Objeto Objetivos Gerais Aprender a analisar, projetar e implementar sistemas usando a orientação a objeto (OO). Ao terminar a disciplina, o aluno terá desenvolvido um projeto prático completo utilizando os conceitos gerais apresentados. Objetivos Específicos Introduzir os conceitos básicos relacionados com a orientação a objeto, incluindo sua aplicabilidade a Análise Orientada a Objeto (OOA), o Projeto Orientado a Objeto (OOD) e a Programação Orientada a Objeto (OOP) Apresentar a linguagem de modelagem padrão de mercado Unified Modeling Language (UML) largamente utilizada para a Análise e Projeto de sistemas de software de grande escala Apresentar um processo completo de desenvolvimento de software utilizável com a linguagem UML Exemplificar OOA, OOD, OOP, UML e o processo de desenvolvimento através de um estudo de caso completo Apresentar técnicas básicas de Projeto Orientado a Objeto. O enfoque é mostrar em que consiste um bom projeto. Apresentar Padrões de Projeto, chaves para o bom projeto de software. Apresentar rapidamente assuntos mais "quentes" relacionados com a tecnologia OO. Permitir que o aluno aprofunde seu conhecimento dos conceitos apresentados através da elaboração de um sistema completo apoo-1 programa próxima Page 1 of 1 Análise e Projeto de Sistemas Orientados a Objeto 04/02/2012 file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\apoo1.htm

Transcript of Apoo Jacques Ufcg

Page 1: Apoo Jacques Ufcg

Análise e Projeto de Sistemas Orientados a Objeto

Objetivos Gerais Aprender a analisar, projetar e implementar sistemas usando a orientação a objeto (OO). Ao terminar a disciplina, o aluno terá desenvolvido um projeto prático completo utilizando os conceitos gerais apresentados.

Objetivos Específicos Introduzir os conceitos básicos relacionados com a orientação a objeto, incluindo

sua aplicabilidade a Análise Orientada a Objeto (OOA), o Projeto Orientado a Objeto (OOD) e a Programação Orientada a Objeto (OOP)

Apresentar a linguagem de modelagem padrão de mercado Unified Modeling Language (UML) largamente utilizada para a Análise e Projeto de sistemas de software de grande escala

Apresentar um processo completo de desenvolvimento de software utilizável com a linguagem UML

Exemplificar OOA, OOD, OOP, UML e o processo de desenvolvimento através de um estudo de caso completo

Apresentar técnicas básicas de Projeto Orientado a Objeto. O enfoque é mostrar em que consiste um bom projeto.

Apresentar Padrões de Projeto, chaves para o bom projeto de software. Apresentar rapidamente assuntos mais "quentes" relacionados com a tecnologia

OO. Permitir que o aluno aprofunde seu conhecimento dos conceitos apresentados

através da elaboração de um sistema completo

apoo-1 programa próxima

Page 1 of 1Análise e Projeto de Sistemas Orientados a Objeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\apoo1.htm

Page 2: Apoo Jacques Ufcg

Análise e Projeto de Sistemas Orientados a Objeto

Programa 1. Introdução à Análise e Projeto de Sistemas Orientados a Objeto

1.1 Análise e projeto orientados a objeto (Capítulo 1 do livro de Larman) 1.2 Introdução a um processo de desenvolvimento (Capítulo 2) 1.3 Modelos e artefatos (Capítulo 3)

2. Fase de Planejamento e Elaboração

2.1 Estudo de caso: Terminal Ponto de Venda (PDV) (Capítulo 4) 2.2 Entendendo requisitos (Capítulo 5) 2.3 Use cases: descrição de processos (Capítulo 6) 2.4 Priorização de use cases (Capítulo 7)

3. Fase de Análise 1

3.1 Elaboração de um modelo conceitual (Capítulo 9) 3.2 Modelo conceitual: adição de associações (Capítulo 10) 3.3 Modelo conceitual: adição de atributos (Capítulo 11) 3.4 Construção do glossário (Capítulo 12) 3.5 Comportamento dinâmico: diagramas de sequência (Capítulo 13) 3.6 Comportamento dinâmico: contratos (Capítulo 14)

4. Fase de Projeto 1

4.1 Da análise ao projeto (Capítulo 15) 4.2 Projeto arquitetural (Capítulo 22) 4.3 Descrição de use cases reais (Capítulo 16) 4.4 Diagramas de colaboração (Capítulo 17) 4.5 Padrões para atribuir responsabilidades (Capítulo 18) 4.6 Projeto de soluções com objetos e padrões (Capítulo 19) 4.7 Visibilidade (Capítulo 20) 4.8 Diagramas de classe para a fase de projeto (Capítulo 21) 4.9 Esquema de banco de dados e mapeamento OO-Relacional (Capítulo 38)

5. Fase de Implementação

5.1 Mapeamento do projeto para código (Capítulo 23) 5.2 Programa exemplo em Java (Capítulo 24) 5.3 Testes de unidade 5.4 Adicionando uma interface com o usuário

6. Fase de Análise 2

6.1 Escolha de requisitos da segunda iteração (Capítulo 25) 6.2 Relacionando múltiplos use cases (Capítulo 26) 6.3 Extensão do modelo conceitual (Capítulo 27) 6.4 Generalização (Capítulo 28) 6.5 Organizando o modelo conceitual com packages (Capítulo 29) 6.6 Refinamento do modelo conceitual (Capítulo 30) 6.7 Modelo conceitual no estudo de caso (Capítulo 31)

Page 1 of 2Análise e Projeto de Sistemas Orientados a Objeto: Programa

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\apoo2.htm

Page 3: Apoo Jacques Ufcg

6.8 Comportamento do sistema: Diagramas de sequência e contratos na Segunda Iteração (Capítulo 32) 6.9 Comportamento do sistema: Diagramas de estado (Capítulo 33)

7. Fase de projeto 2

7.1 Polimorfismo 7.2 Interfaces 7.3 Composição versus herança 7.4 Padrões de Projeto (Design Patterns)

7.4.1 O que são Design Patterns? 7.4.2 Elementos essenciais de um Design Pattern 7.4.3 Design Pattern: Factory Method 7.4.4 Design Pattern: Iterator 7.4.5 Design Pattern: Composite 7.4.6 Design Pattern: Strategy 7.4.7 Design Pattern: Decorator 7.4.8 Design Pattern: Template Method 7.4.9 Design Pattern: Observer 7.4.10 Comentários finais sobre Design Patterns

8. Tópicos avançados

8.1 Refactoring 8.2 Extreme Programming 8.3 Frameworks 8.4 Componentes

apoo-2 home

Page 2 of 2Análise e Projeto de Sistemas Orientados a Objeto: Programa

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\apoo2.htm

Page 4: Apoo Jacques Ufcg

1. Introdução à Análise e Projeto de Sistemas Orientados a Objeto

Análise e projeto orientados a objeto Introdução a um processo de desenvolvimento Modelos e artefatos

intro programa

Page 1 of 11. Introdução à Análise e Projeto de Sistemas Orientados a Objeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\intro\index.htm

Page 5: Apoo Jacques Ufcg

Análise e Projeto Orientados a Objeto

Objetivos

Comparar e contrastar Análise e Projeto Definir Análise e Projeto Orientados a Objeto

O que vamos fazer na disciplina?

Saber uma linguagem de programação orientada a objeto (OO) não é suficiente para criar sistemas OO

Tem que saber Análise e Projeto OO (APOO) Isto é, Análise e Projeto usando uma perspectiva de objetos

Usaremos um estudo de caso para concretizar a discussão Usaremos a linguagem UML (Unified Modeling Language) para criar modelos (de

análise e de projeto) Um modelo é uma representação abstrata dos aspectos essenciais de um

sistema O que é "essencial" depende do momento da modelagem A UML usa uma representação principalmente gráfica para representar os

modelos UML é muito popular hoje em dia para modelar sistemas

Usaremos Design Patterns (padrões de projeto) para mostrar soluções abstratas para problemas que surgem frequentemente durante o projeto de sistemas OO

Os patterns tratarão principalmente de: Como atribuir responsabilidades a objetos (uma das atividades mais difícil

no desenvolvimento de sistemas OO) Como separar o que muda do que é constante numa determinada situação,

com o objetivo de ganhar flexibilidade Para evitar "o efeito gelatina"

Explicaremos e seguiremos um processo de desenvolvimento que mostra claramente quais são as etapas a seguir para produzir software de qualidade

Veremos também quais artefatos devem ser produzidos na várias fases e etapas do processo

O que é Análise e Projeto?

Diferenças entre análise e projeto: tem mais do que uma definição empregada Primeira alternativa:

A análise modela o problema e consiste das atividades necessárias para entender o domínio do problema (o que deve ser feito). É uma atividade de investigação.

O projeto modela a solução e consiste das atividades de criação (como pode ser feito)

Page 1 of 4Análise e Projeto Orientados a Objeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\intro\intro1.htm

Page 6: Apoo Jacques Ufcg

Segunda alternativa: A análise consiste de todas as atividades feitas com ou para o conhecimento

do cliente. A informação produzida é aquela que o cliente deve discutir e aprovar

O projeto inclui as atividades que resultam em informação que interessa apenas ao programador

Com essa definição, a análise invade um pouco o "lado da solução", pois o cliente deve discutir alguns tipos de interações que ocorrerão na interface do usuário, etc.

Observe portanto que não definição binária que isole "análise" de "projeto" Nesta disciplina, adotaremos a segunda alternativa, pois queremos associar as

palavras "análise" e "projeto" aos artefatos (deliverables) entregues nos final de cada fase

Um modelo de análise deve ser aprovado pelo cliente e pode incluir alguma (pequena) discussão da solução, principalmente no que diz respeito à interface com usuário, etc.

Apesar do nome da disciplina, vamos ver também as fases de requisitos, implementação e testes

A obtenção de requisitos é frequentemente incluída na fase de análise ("análise de requisitos")

Page 2 of 4Análise e Projeto Orientados a Objeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\intro\intro1.htm

Page 7: Apoo Jacques Ufcg

O que é Análise e Projeto Orientados a Objeto (APOO)?

A perspectiva empregada é de objetos (coisas, conceitos ou entidades) Durante a Análise OO, a ênfase está em achar e descrever objetos (ou conceitos)

no domínio do problema Por exemplo, num sistema de informação para uma biblioteca, alguns dos

conceitos são Livro, Biblioteca, Usuário. Tais objetos podem ter atributos e responsabilidades

Durante o projeto orientado a objeto, a ênfase está em achar objetos lógicos de software que poderão ser eventualmente implementados usando uma linguagem de programação OO

Tais objetos pode ter atributos e métodos Durante a construção (programação OO), os objetos do projeto são implementados

e testados

APOO versus AP Orientados a Funções (APOF)

Com ambas as técnicas, usa-se decomposição (chamado modularização em APOF) para lidar com a complexidade

A APOF (também chamados de Análise e Projeto Estruturados), a decomposição é por função ou processo

Page 3 of 4Análise e Projeto Orientados a Objeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\intro\intro1.htm

Page 8: Apoo Jacques Ufcg

Por que queremos Orientação a Objeto? Quais são as vantagens?

As abstrações podem corresponder às coisas do domínio do problema O nível é mais natural É mais fácil comunicar-se com o usuário ou domain expert na linguagem dele

Os mesmos objetos existem em todas as fases e uma notação única (objetos) facilita portanto a integração entre fases de desenvolvimento (passar de uma fase para a outra)

Fases posteriores adicionam novos objetos mas os objetos do domínio do problema permanecem: são estáveis

Isso ajuda o rastreamento de decisões de projeto e implementação É mais fácil entender o domínio do problema quando esta é quebrado em pedaços:

gerenciamento da complexidade através da modularização O mesmo pode ser dito no domínio do computador (projetando e programando

com objetos) A abstração controla a complexidade (escondendo algo através da separação da

interface e da implementação) A encapsulação facilita as mudanças (através do isolamento) A hierarquia (grafo de herança) permite uma melhor reutilização Hierarquia promove a flexibilidade de fazer mudanças de forma localizada

Exemplo: novos trechos de programas podem usar uma sub-classe nova e código antigo continua usando a superclasse e não toma conhecimento das mudanças

Porém, há problemas de acoplamento com herança que veremos em outro capítulo

A reutilização de pedaços é mais difícil usando paradigmas anteriores (modularização via funções) porque não posso usar coisas pré-existentes tão facilmente

Com objetos, posso dizer: "me dê dois daqueles" porque objetos têm estado Não posso fazer isso com funções porque elas não encapsulam estado

intro-1 programa próxima

Page 4 of 4Análise e Projeto Orientados a Objeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\intro\intro1.htm

Page 9: Apoo Jacques Ufcg

Modelos e Artefatos

Objetivos

Definir os modelos e artefatos a serem produzidos durante o proceso de desenvolvimento de software

Os modelos e outros artefatos (deliverables)

Artefatos da fase de elaboração Documento de business case (investigação preliminar) Documento de orçamento e cronograma Documento de especificação de requisitos

Requisitos funcionais (Modelo de use case) Requisitos não funcionais

Modelo conceitual inicial Glossário Projeto arquitetural (poderá incluir un Modelo de componentes)

Fase de construção Refinamento dos requisitos funcionais (Modelo de use case) Refinamento do modelo conceitual (Modelo conceitual)

Inclui vários tipos de diagramas UML Refinamento do projeto arquitetural (poderá incluir un Modelo de componentes) Refinamento do glossário Projeto de baixo nível (Modelo de projeto)

Inclui vários tipos de diagramas UML Esquema de banco de dados

Planos de testes Fase de implantação

Planos de publicação Planos de testes alfa, beta Planos de treinamento

intro-3 programa anterior

Page 1 of 1Modelos e Artefatos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\intro\intro3.htm

Page 10: Apoo Jacques Ufcg

2. Fase de Planejamento e Elaboração Estudo de caso: Terminal Ponto de Venda (PDV) Entendendo requisitos Use cases: descrição de processos Priorização de use cases

plan programa

Page 1 of 12. Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\index.htm

Page 11: Apoo Jacques Ufcg

Estudo de caso: Terminal Ponto de Venda (PDV)

Objetivos

Introduzir o estudo de caso utilizado na disciplina

O Terminal de Ponto de Venda (PDV)

Nosso estudo de caso envolve um Terminal PDV Um sistema computadorizado que registra vendas e trata de pagamentos Tipicamente usado numa loja de varejo Tipicamente está acoplado a um leitor de código de barra

Trataremos do desenvolvimento do software que controla o terminal usando um processo de desenvolvimento iterativo-incremental

Falaremos de requisitos, análise, projeto e implementação Este sistema envolve um sistema de informação típico e nos fará cruzar com

muitas situações típicas

Arquitetura em camadas e ênfase do estudo

Um sistema de informação típico é organizado usando as camadas apresentadas abaixo

As camadas arquiteturais apresentadas são:

Page 1 of 2Estudo de caso: Terminal Ponto de Venda (PDV)

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan1.htm

Page 12: Apoo Jacques Ufcg

Apresentação Interface gráfica, janelas

Lógica de aplicação - Objetos do domínio de problema Objetos representando conceitos do domínio (business objects) Contém o que se chama também business logic

Lógica de aplicação - Objetos de serviço Objetos que não pertencem ao domínio do problema mas oferecem serviços

tais como interfaceamento para um banco de dados, etc. Armazenamento

Mecanismos de armazenamento persistente (SGBDOO, SGBDR, SGBDOR) Usam-se Análise e Projeto OO principalmente nas camadas de lógica de aplicação Falaremos em mais detalhes sobre arquiteturas em camadas na seção 4.2 (Projeto

arquitetural) Boa parte da disciplina tratará do business logic A seção 4.9 tratará de objetos para serviços de persistência

plan-1 programa próxima

Page 2 of 2Estudo de caso: Terminal Ponto de Venda (PDV)

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan1.htm

Page 13: Apoo Jacques Ufcg

Entendendo Requisitos

Objetivos

Descrever os artefatos do processo de desenvolvimento relacionados aos requisitos Identificar e categorizar requisitos funcionais do sistema Identificar e categorizar requisitos não-funcionais do sistema (atributos do sistema)

Requisitos

Requisitos são uma descrição de necessidades ou desejos para um produto. Motivo da fase de levantamento de requisitos: saber que sistema deve ser construido Se houver sucesso no levantamento de requisitos, não haverá surpresas desagradáveis para o

usuário na entrega do sistema Artefatos típicos a serem criados

Breve descrição do sistema Descrição dos clientes alvo

Pode incluir como eles operam hoje e quais problemas eles enfrentam Descrição das metas do sistema Descrição dos requisitos funcionais do sistema Descrição dos requisitos não funcionais do sistema

Usaremos o estudo de caso (Terminal PDV) para exemplificar a obtenção de requisitos

Breve descrição do sistema

O objetivo do projeto é de criar um sistema para um Terminal Ponto de Venda (TPDV) a ser usado no comércio varejista.

Descrição dos clientes alvo

O cliente é Xpto, Ltda., que vende TPDVs a lojas varejistas.

Descrição das metas do sistema

A meta básica é de melhorar a automação do balcão de vendas, incluindo: Checkout mais rápido para o cliente Análise rápida e precisa das vendas Automatizar o controle de estoque

Observe que, no Brasil, haveria outras considerações de ordem legal, incluindo o recolhimento

Page 1 of 3Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan2.htm

Page 14: Apoo Jacques Ufcg

de impostos

Descrição dos requisitos funcionais do sistema

Requisitos funcionais descrevem o que o sistema deve fazer As categorias de requisitos funcionais são:

Funcionalidade básica A lista abaixo não é exaustiva mas servirá de exemplo para explicar as atividades do

processo de desenvolvimento Observe que o levantamento dos requisitos funcionais deve ser completado usando use

cases (discutidos no próximo capítulo) Use cases descrevem os processos do domínio do problema A lista abaixo pode servir para nortear o levantamento de use cases Alguns desenvolvedores usam apenas use cases para levantar os requisitos funcionais De toda forma, a tabela abaixo exemplifica o que se entende por requisito funcional

Funcionalidade associada ao pagamento

Descrição dos requisitos não funcionais do sistema

Requisitos não funcionais incluem requisitos das seguintes categorias Facilidade de uso necessária Tipo de interface desejada Quem utilizará o produto Volume de utilização (número de usuários, número de transações, ...) Hardware e software alvo para o produto Qualidade/robustez

Categoria de funcionalidade Significado

Evidente Usuário está ciente de que a função está sendo feita

Escondida Embora a função seja feita, ela é invisível ao usuário. Tal funcionalidade frequentemente é esquecida ao levantar requisitos

Friso Funcionalidade opcional; sua adição não afeta outras funções ou o custo significativamente

Referência Funcionalidade Categoria

R1.1 Registrar a vanda corrente (os itens comprados) Evidente

R1.2 Calcular o total de venda, incluindo impostos e descontos aplicáveis Evidente

R1.3

Capturar a informação do item sendo comprado através de um leitor de código de barra, ou manualmente usando um código de produto tal como o Universal Product Code (UPC)

Evidente

R1.4 Dar baixa no inventário ao terminar uma venda Escondida

R1.5 Manter um log de vendas feitas Escondida

R1.6 O caixa deve fazer login com uma identificação e uma senha antes de usar o sistema Evidente

R1.7 Deve prover um mecanismo persistente de armazenamento Escondida

R1.8 Prover integração com outros sistemas Escondida

R1.9 Exibir a descrição e o preço do item sob consideração Evidente

Referência Funcionalidade Categoria

R2.1 Tratar de pagamentos à vista com dinheiro, capturando o valor entregue e calculando o troco Evidente

R2.2

Tratar de pagamentos por cartão de crédito, capturando a informação do cartão através de um leitor de cartões ou por digitação manual e autorizando o pagamento usando o serviço de autorização de crédito da loja (um sistema externo) usando uma conexão via modem

Evidente

R2.3

Tratar de pagamentos por cheque, capturando a informação de identidade/CPF por digitação manual e autorizando o pagamento usando o serviço de verificação de cheques da loja (um sistema externo) usando uma conexão via modem

Evidente

R2.4Lançar os pagamentos via cartão de crédito no sistema de contas a receber, já que o serviço de cartão de crédito deve dinheiro à loja

Escondida

Page 2 of 3Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan2.htm

Page 15: Apoo Jacques Ufcg

Tolerância a falha Desempenho Segurança Compatibilidade com outros produtos/versões e necessidades de migração Necessidades de internacionalização do produto Necessidades de customização do produto pelo cliente Suporte Preço da solução Documentação necessária Uso de padrões Aspectos legais Integração com outros produtos Packaging Requisitos de instalação Riscos aceitáveis

Os requisitos não funcionais também são chamados de atributos do sistema Alguns exemplos seguem

plan-2 programa anterior próxima

Atributo Detalhes ou condição limite

Tempo de resposta (Condição limite) Ao registrar um item sendo vendido, a descrição e preço devem aparecer em 2 segundos

Tipo de interface(Detalhe) Usar formulários para entrada de dados e dialog boxes

(Detalhe) Maximizar a facilidade de uso via teclado e não via mouse

Tolerância a falhas (Condição limite) Deve fazer log dos pagamentos autorizados via cartão de crédito em 24 horas, mesmo com falhas de energia ou de dispositivo

Plataformas operacionais (Detalhe) Microsoft Windows 95, Windows, 98, Windows NT e Windows 2000

Page 3 of 3Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan2.htm

Page 16: Apoo Jacques Ufcg

Use Cases: Descrição de Processos

Objetivos

Identificar e escrever use cases Diagramar use cases Constrastar use cases de alto nível e expandidos Contrastar use cases essenciais e reais

Introdução

Use cases são usados para descrever os processos do domínio de problema São uma excelente forma de explorar e documentar os requisitos funcionais Antes de elaborar use cases, pode valer a pena elaborar uma tabela de funções básicas como vimos na

seção anterior

Use cases

Um use case é um documento narrativo que descreve uma sequência de eventos feitos por um ator no uso de um sistema para completar um processo de interesse deste ator.

Use cases são "estórias" ou "casos" no uso de um sistema As estórias acabam revelando as funcionalidade desejada do sistema

Em UML, um use case é representado assim:

Exemplo de um Use Case de alto nível: Comprar item Segue uma breve descrição do processo de comprar um item numa loja quando um TPDV é utilizado

Use case: Comprar item Atores: Cliente, Caixa Tipo: primário (a ser explicado logo) Descrição: Um cliente chega ao caixa com itens a comprar. O caixa registra os itens comprados e recebe pagamento. No fim, o cliente sai com os itens comprados.

UML não força o formato exato de um Use Case. A clareza na descrição é o essencial. Iniciamos acima com um Use Case de alto nível, fornecendo poucos detalhes

Útil para entender rapidamente os processos principais envolvidos

Exemplo de um Use Case expandido: Comprar item com dinheiro vivo Ignoramos a questão de dar baixa no inventário aqui

Use case: Comprar item com dinheiro Atores: Cliente (iniciador), Caixa Propósito: Capturar uma venda e seu pagamento em dinheiro Resumo: Um cliente chega ao caixa com itens a comprar. O caixa registra os itens comprados e recebe pagamento. No fim, o cliente sai com os itens comprados. Tipo: primário e essencial Referência cruzada: R1.1, R1.2, R1.3, R1.7, R1.9, R2.1 (pode fazer referência a outros use Cases)

Sequência típica de eventos

Ação do ator Resposta do sistema

1. O Use Case inicia quando um cliente chega a um caixa munido de TPDV com itens a comprar

2. O caixa registra a identificação de cada item 3. Determina o preço do item e adiciona a informação ao total da transação de

venda

Page 1 of 4Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan3.htm

Page 17: Apoo Jacques Ufcg

Sequências alternativas: Linha 2: Entrada de um identificador inválido. Indica erro. Linha 7: Cliente não tinha dinheiro suficiente. Cancela transação de venda.

Atores

Um ator é uma entidade externa ao sistema que, de alguma forma, participa das estórias relatadas no Use Case

Um ator tipicamente estimula o sistema com eventos de entrada ou recebe algo so sistema Atores são representados pelo papel que desempenham (e não por nome de pessoa, etc.) Em UML, o ícone que representa um ator é o seguinte:

Para cada Use Case, um dos atores é o iniciador e outros atores podem ser participantes Atores correspondem frequentemente a papeis de seres humanos mas, às vezes, outros sistemas ou

dispositivos elétricos ou mecânicos podem ser atores

O motivo de usar Use Cases

Para decidir e descrever a funcionalidade de comum acordo com o cliente Servem de documento básico de referência durante todo o processo sobre o que foi prometido Serve como base para elaborar os testes funcionais do sistema final Para poder rastrear requisitos funcionais dentro dos modelos de análise, projeto e implementação

Sabemos que requisitos causaram o aparecimento de determinadas soluções

Um erro frequente ao criar Use Cases

Iniciantes costumam representar cada etapa, operação ou transação como Use Case separado (exemplo: login como Use Case)

Um Use Case deve representar uma iteração completa e útil para os atores Use Cases são geralmente processos inteiros, cabo-a-rabo e normalmente envolvem muitas etapas ou

transações Eles modelam os Business Processes do negócio

Etapas comuns a vários Use Cases podem ser agrupados em Use Cases Abstratos, no sentido de minimizar a duplicação de informação

Falaremos mais sobre isso em outro capítulo Exemplos de processo:

Sacar dinheiro num caixa eletrônico Fazer pedido de um produto Cadastrar-se num curso numa escola Verificar a grafia de um documento num processador de texto Atender uma chamada telefônica

Identificação de Use Cases

De forma geral, deve-se verificar a lista de requisitos levantados e usar técnicas de brainstorming Duas formas comuns:

Se houver mais itens, o caixa pode informar a quantidade também

A descrição e preço do item corrente são exibidos

4. Ao completar a entrada dos itens, o caixa indica este fato ao TPDV 5. Calcula e apresenta o total da venda

6. O caixa informa o total da venda ao cliente

7. O cliente efetua o pagamento com dinheiro, possivelmente maior que o total da venda

8. O caixa registra a quantidade de dinheiro recebida 9. Mostra o valor do troco ao cliente

Gera um recibo impresso

10. O caixa deposita o dineiro recebido e extrai o troco a devolver O caixa entrega o troco e o recibo impresso ao cliente

11. Faz log da venda completada

12. O cliente sai da loja com os itens comprados

Page 2 of 4Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan3.htm

Page 18: Apoo Jacques Ufcg

Foco nos atores Identificar os atores relacionados com o sistema Para cada ator, identificar os processos que eles iniciam ou dos quais participam Para identificar atores, faça as seguintes perguntas sobre o sistema:

Quem vai usar a funcionalidade principal do sistema (atores principais)? Quem vai precisar do suporte do sistema para desempenhar suas tarefas do dia-a-dia? Quem deverá manter e administrar o sistema (atores secundários)? Que dispositivos de hardware o sistema precisa manusear? Com que outros sistemas este interage? Quem ou o que tem interesse nos resultados (valores produzidos) do sistema?

Foco nos eventos Identificar os eventos externos aos quais um sistema deve responder Relacione os eventos aos atores e Use Cases

Diagramas de Use Case

Em UML, um diagrama de Use Case tem o formato seguinte:

O diagrama identifica e relaciona os Use Cases e os relaciona com os atores Observe que o diagrama de Use Case determina com precisão o que é o "sistema"

Use Cases Primários, Secundários e Opcionais

Use Cases primários: representam processos importantes e/ou comuns (comprar itens) Use Cases secundários: representam processos menos importantes ou raros (Pedido de reposição de

estoque) Use Cases opcionais: representam processos que talvez não sejam considerados

Use Cases Essenciais versus Reais

Use Cases essenciais: possui uma descrição breve, muito abstrata, sem detalhes, sem mencionar tecnologias empregadas (poderia incluir uma frase: "cliente se identifica" sem maiores detalhes porque a forma de identificação pode mudar com tempo e com a disponibilidade de tecnologia)

Use Cases reais: muito mais concretos, mencionando tecnologias correntemente usadas ("cliente se identifica passando seu Smart Card no leitor")

Use Cases essenciais são usados mais cedo no processo (antes do design) e Use Cases podem ser transformados em Use Cases reais durante o design

Durante o processo de desenvolvimento: Durante o levantamento de requisitos

Crie Use Cases em formato de alto nível Crie um diagrama de Use Cases, indicando os relacionamentos Selecione os Use Cases mais críticos, que deverão influenciar o sistema mais ou que envolvam

mais risco e escreva uma versão Expandida Essencial Priorize os Use Cases (próximo capítulo)

Durante a fase de análise Escreva uma versão Expandida Essencial dos Use Cases sendo atacados na iteração corrente (se já

não estiver pronta) Durante a fase de projeto

Escreva uma versão Expandida Real dos Use Cases sendo atacados na iteração corrente

Estudo de Caso: O sistema TPDV

Identificar o sistema, atores e Use Cases O sistema será a combinação de hardware (o terminal) e software executando nele

Page 3 of 4Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan3.htm

Page 19: Apoo Jacques Ufcg

Os atores relevantes e alguns processos que eles iniciam são:

Escrever Use Cases em formato de alto nível

Use case: Comprar item Atores: Cliente (iniciador), Caixa Tipo: primário Descrição: Um cliente chega ao caixa com itens a comprar. O caixa registra os itens comprados e recebe pagamento. No fim, o cliente sai com os itens comprados.

Use case: Start Up Atores: Gerente Tipo: primário Descrição: Um gerente liga um TPDV para o preparar para uso pelos Caixas. O gerente verifica que a data e horas estão corretas. O sistema está pronto para uso pelos Caixas

Elaborar um diagrama de Use Cases

Escrever alguns Use Cases no formato Expandido Essencial Favor ver livro, seção 6.16.5

Priorizar os Use Cases Ver próximo capítulo

plan-3 programa anterior próxima

Caixa Fecha caixa

Cliente Compra itens Devolve itens

Gerente Start Up Shut Down

Administrador do sistema Adiciona novos usuários

Page 4 of 4Fase de Planejamento e Elaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan3.htm

Page 20: Apoo Jacques Ufcg

Priorização de Use Cases

Objetivos

Priorizar Use Cases Quando necessário, criar versões simplificadas de Use Cases Alocar os Use Cases às iterações de desenvolvimento

Introdução

De forma geral, cada iteração da fase de construção vai tratar de um ou mais Use Cases identificados Às vezes, um Use Case pode ser tratado em duas ou mais iterações, com versões simplificadas tratadas

primeiro

Priorização de Use Cases

Normalmente, quem prioriza os Use Cases é o cliente (ou Domain Expert) Os técnicos podem ajudá-lo fornecendo estimativas de esforço de desenvolvimento para os vários Use Cases Mas lembre que é o cliente que sabe o Business Value de cada Use Case

Alguns parâmetros que podem aumentar a prioridade de um Use Case Afetam muito a arquitetura

O primeiro incremento deveria ser um teste arquitetural (uma validação da viabilidade da arquitetura) O processo de desenvolvimento deve ser "architecture-centric"

Pouco esforço dando muito insight sobre o projeto do sistema Use Cases que envolvem muito risco, são críticos no tempo

O processo de desenvolvimento deve ser "risk-confronting" Envolvem business processes fundamentais

Deixe o cliente falar! Podem aumentar significativamente o lucro ou diminuir as despesas/custos

Deixe o cliente falar!

O estudo de caso

Uma possibilidade de priorização

O Use Case Start Up poderia ser feito numa versão mínima se ele for necessário ao funcionamento do resto Escalonamento final dos Use Cases no estudo de caso

Teremos que atacar Comprar Itens na primeira iteração além de uma versão reduzida de Start Up Como Comprar Itens é complexo, pode-se quebrá-lo em várias versões incrementais:

Comprar Itens versão 1: Pagamento em dinheiro apenas Sem atualização de estoque Loja stand-alone, sem integração a uma organização maior Entrada manual de UPC, sem leitor de código de barras Sem cálculo de impostos

Prioridade Use Case Justificativa

Alta Comprar itens Satisfaz quase todos os critérios de aumento de prioridade

MédiaAdicionar novos usuários Login Devolver itens

Afeta a segurança Afeta a segurança Processo importante; afeta a contabilidade

BaixaFechamento de caixa Start Up Shut Down

Efeito mínimo na arquitetura Definição depende de outros Use Cases Efeito mínimo na arquitetura

Page 1 of 2Priorização de Use Cases

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan4.htm

Page 21: Apoo Jacques Ufcg

Sem descontos especiais Sem log in Sem manutenção de perfil de usuário (preferências, ...) Sem controle contábil do valor em caixa Recibo não contém informação completa (sem ID do Caixa, ID do TPDV)

Comprar Itens versão 2: (todas as formas de pagamentos) Comprar Itens versão 3: (versão completa)

As três versões (além dos outros Use Cases) são distribuídas ao longo dos incrementos

plan-4 programa anterior

Page 2 of 2Priorização de Use Cases

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\plan\plan4.htm

Page 22: Apoo Jacques Ufcg

3. Fase de Análise 1 Elaboração de um modelo conceitual Modelo conceitual: adição de associações Modelo conceitual: adição de atributos Construção do glossário Comportamento dinâmico: diagramas de sequência Comportamento dinâmico: contratos

anal1 programa

Page 1 of 13. Fase de Análise 1

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\index.htm

Page 23: Apoo Jacques Ufcg

Início de uma Iteração de Construção Para iniciar uma iteração, lembre que certos refinamentos são feitos antes de iniciar a

análise detalhada da funcionalidade desejada na iteração O capítulo que inicia agora trata de análise, ou da elaboração de um modelo conceitual

Elaboração de um Modelo Conceitual

Objetivos

Criar um modelo conceitual inicial Distinguir entre atributos corretos e incorretos Adicionar conceitos de descrição, quando apropriado Comparar e contrastar os termos conceito, tipo, interface e classe

Introdução

O modelo conceitual é o artefato mais importante criado durante a análise O modelo conceitual ilustra os conceitos importantes do domínio do problema, suas

associações e atributos Falaremos de associações e atributos nos próximos capítulos Levantar um conjunto rico e expressivo de conceitos (objetos) durante a análise ajuda

muito a conduzir as fases de projeto e implementação É importante lembrar que os conceitos levantados aqui são do domínio do problema e

não conceitos associados a software

Modelos conceituais

Ao fazer análise OO, a decomposição do domínio do problema utiliza objetos e não funções ou processos como na análise estruturada

Exemplo de um modelo conceitual (com conceitos, associações e atributos) Apenas a parte diagramática está sendo mostrada UML permite associar descrições mais detalhadas dos conceitos, atributos, etc.

Page 1 of 6Início de uma Iteração de Construção

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal1.htm

Page 24: Apoo Jacques Ufcg

Criar o modelo conceitual ajuda a elaborar o glossário, definindo os termos importantes do domínio do problema

Muito importante para a comunicação entre os envolvidos (clientes e desenvolvedores)

Modelos conceituais não representam entidades de software mas conceitos do domínio do negócio

Exemplo correto

Exemplos errados

Cuidado! Alguns profissionais acham correto introduzir responsabilidades (ou operações) no modelo conceitual

Embora ninguém ache certo introduzir métodos (que implementam operações) no modelo conceitual

Estratégias para identificar conceitos (objetos)

Regra fundamental: é melhor ter conceitos demais (muitos conceitos de granularidade pequena) do que conceitos de menos no modelo conceitual

Novos conceitos podem ser descobertos com tempo (quando se está identificando associações ou atributos, por exemplo) e a elaboração de um modelo conceitual é portanto uma atividade iterativa

Na modelagem de dados para bancos de dados, há um critério de modelagem que diz que algo sobre o qual não precisamos lembrar nada não precisa entrar no modelo conceitual

Page 2 of 6Início de uma Iteração de Construção

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal1.htm

Page 25: Apoo Jacques Ufcg

Com o ponto de visto de persistência, a regra faz sentido Mas na modelagem OO, objetos com apenas comportamento (sem atributos)

também são importantes (embora raros) e não devem ser excluídos do modelo

Usando a lista de categoria de conceitos Conceitos são comumente descobertos nas categorias da tabela seguinte

Os exemplos são referentes aos domínios de uma loja e reserva de passagem aérea

Achando conceitos através de substantivos Uma técnica simples para a identificação de conceitos é de isolar os substantivos nas

descrições textuais dos Use Cases Muitos dos substantivos serão conceitos ou atributos

Categoria de Conceito Exemplos

Objetos físicos ou tangíveis Terminal Ponto De Venda (TPDV) Aeronave

Especificações, projetos ou descrições de coisas Especificação de produto Descrição de um vôo

Lugares Loja Aeroporto

Transações (um momento notável) Venda, Pagamento Reserva

Detalhes de transação (Line item) Item de detalhe de uma venda

Papeis de pessoas Caixa Piloto

Coleções de outras coisas (containers) Loja, Prateleira Aeronave

Coisas dentro das coleções Item Passageiro

Outros sistemas externos a nosso sistema Sistema de autorização de cartão de crédito Sistema de controle de tráfego aéreo

Conceitos abstratos Fome Acrofóbia (medo de altura)

Organizações Departamento de vendas Voamos Baixo, Ltda.

Eventos Venda, Roubo, Reunião Vôo, Desastre, Aterrissagem

Processos (frequentemente não é representado como conceito, mas pode ocorrer)

Fazer a venda de um produto Fazer uma reserva de lugar num vôo

Regras e políticas Política de devolução Política de cancelamento

Catálogos Catálogo de produtos Catálogo de peças

Registros de assuntos financeiros, de trabalho, de contratos, legais

Recibo, Plano de contas, Contrato de emprego Log de manutenção

Instrumentos e serviços financeiros Linha de crédito Estoque

Manuais, livros Manual do empregado Manual de reparos

Page 3 of 6Início de uma Iteração de Construção

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal1.htm

Page 26: Apoo Jacques Ufcg

Exemplo: Use Case expandida "Comprar Item com Dinheiro Vivo"

Alguns desses substantivos são conceitos (objetos), outros são atributos de conceitos Falaremos mais sobre as diferenças em outro capítulo Uma regra útil: Se pensarmos sobre um conceito X como número ou texto no mundo

real, ele pode ser um atributo; caso contrário, sempre será um conceito Na dúvida, crie um conceito separado Exemplo: Destino é um atributo de um vôo ou um conceito separado?

É um conceito separado (pensamos no destino como sendo um aeroporto)

Conceitos candidatos para o domínio do TPDV

Usando as técnicas acima, temos a seguinte relação de candidatos:

Relatórios são objetos? Um recibo é um relatório Deveria ser um conceito (objeto) A favor de excluir:

Um recibo é apenas um relatório de uma venda Incluí-lo no modelo conceitual não seria útil porque toda sua informação é derivada

de outros objetos A favor de incluir

Um recibo tem um papel importante nas regras de negócio porque permite que o cliente devolva itens comprados

Ação do ator Resposta do sistema

1. O Use Case inicia quando um cliente chega a um caixa munido de TPDV com itens a comprar

2. O caixa registra a identificação de cada item Se houver mais itens, o caixa pode informar a quantidade também

3. Determina o preço do item e adiciona a informação ao total da transação de venda A descrição e preço do item corrente são exibidos

4. Ao completar a entrada dos itens, o caixa indica este fato ao TPDV 5. Calcula e apresenta o total da venda

6. O caixa informa o total da venda ao cliente

7. O cliente efetua o pagamento com dinheiro, possivelmente maior que o total da venda

8. O caixa registra a quantidade de dinheiro recebida 9. Mostra o valor do troco ao cliente

Gera um recibo impresso

10. O caixa deposita o dinheiro recebido e extrai o troco a devolver O caixa entrega o troco e o recibo impresso ao cliente

11. Faz log da venda completada

12. O cliente sai da loja com os itens comprados

TPDV Especificação de produto

Item Item de detalhe de uma venda

Loja Caixa

Venda Cliente

Pagamento Gerente

Catálogo de produtos

Page 4 of 6Início de uma Iteração de Construção

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal1.htm

Page 27: Apoo Jacques Ufcg

Na primeira iteração de desenvolvimento, os Use Cases não consideram a devolução do produto e não incluiremos o objeto Recibo

Em outra iteração, poderá ser incluído

Modelagem do mundo não real

Em certos domínios de problema, os conceitos são muito abstratos Exemplo: domínio de redes de computadores ou telecomunicações

Conceitos possíveis são: Mensagem, Conexão, Diálogo, Protocolo, etc.

Modelando descrições

Não se deve incluir como atributos descrições de conceitos a instâncias desses conceitos por dois motivos

Repetição de informação A descrição some se não houver instância

Exemplo: Não está correto incluir a descrição de um produto no conceito Produto É melhor criar um novo conceito DescriçãoDeProduto que descreve instâncias de

Produtos

Outro exemplo: O conceito Vôo deveria incluir toda a descrição do vôo? Não! Se nenhum vôo RG321 ocorrer, a descrição do vôo RG321 deve continuar em

algum lugar: é um conceito à parte

Termos empregados na UML

UML não emprega a palavra "conceito" As alternativas são tipo e classe

Page 5 of 6Início de uma Iteração de Construção

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal1.htm

Page 28: Apoo Jacques Ufcg

A diferença entre tipo e classe é que um tipo é abstrato (sem implementação) enquanto a classe sempre inclui alguma implementação

Portanto, o tipo é uma especificação e a classe é uma implementação (de um tipo) A diferença entre as duas coisas se torna mais importante durante a fase de Projeto

Por enquanto, basta dizer que usaremos "conceito" para falar do domínio do problema e "classe" para falar de entidades de software

anal1-1 programa próxima

Page 6 of 6Início de uma Iteração de Construção

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal1.htm

Page 29: Apoo Jacques Ufcg

Comportamento Dinâmico: Diagramas de Sequência Ainda estamos em Análise

Objetivos

Identificar eventos e operações do sistema Criar diagramas de sequência do sistema para Use Cases

Introdução

O modelo conceitual visto no capítulo anterior é um modelo estático Agora, vamos considerar um modelo do comportamento dinâmico do sistema Um diagrama de sequência do sistema ilustra eventos partindo de atores e estimulando

o sistema Como ainda estamos investigando o que o sistema faz (e não como), tais diagramas

fazem parte do modelo de análise Cuidado! Embora o autor do livro texto (Larman) indique que diagramas de sequência do

sistema são utilizados apenas na análise, eles podem ser utilizados no projeto também Os diagramas de sequência do sistema são altamente dependentes dos Use Cases, pois

é a partir deles que criamos os diagramas Trataremos o sistema como "caixa preta", isto é, investigando o que ele faz, mas não

como

Diagramas de sequência do sistema

Os Use Cases sugerem como atores interagem com o sistema Os atores geram eventos para o sistema, pedindo que alguma operação seja feita

Exemplo: quando o caixa entrega o UPC do item sendo comprado ao sistema, o caixa pede que o sistema registre a compra deste item

Queremos entender o sistema melhor examinando as operações que um ator requisita do sistema

Um diagrama de sequência do sistema mostra, para um cenário particular de um Use Case, os eventos gerados pelos atores externos, sua ordem, além de eventos envolvendo outros sistemas

Todos os sistemas são tratados como caixas preta Portanto, os eventos cruzam fronteiras de sistemas

Page 1 of 3Comportamento Dinâmico: Diagramas de Sequência

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal5.htm

Page 30: Apoo Jacques Ufcg

Diagramas de sequência do sistema são elaborados para os Use Cases mais importantes e as alternativas mais cruciais dos Use Cases

Cuidado! Não gere diagramas de sequência do sistema para situações óbvias ou de fácil entendimento

Exemplo de um diagrama de sequência

No diagram abaixo, o tempo flui para baixo Eventos podem incluir parâmetros

Operações do sistema

Para cada evento, há uma operação correspondente que o sistema desempenha Podemos enxergar o sistema como possuindo operações, necessárias para descrever um

comportamento dinâmico No modelo conceitual, isso não era necessário pois estávamos descrevendo um

modelo estático Exemplo:

Mostrando o texto dos Use Cases nos diagramas de sequência

Útil para mostrar a relação entre as operações e a descrição dos Use Cases Exemplo:

Page 2 of 3Comportamento Dinâmico: Diagramas de Sequência

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal5.htm

Page 31: Apoo Jacques Ufcg

Cuidado! Só utilize diagramas de sequência para esclarecer iterações mais complexas entre os atores e o sistema

O exemplo mostrado aqui é simples demais e não merece um diagrama de sequência

anal1-5 programa anterior próxima

Page 3 of 3Comportamento Dinâmico: Diagramas de Sequência

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal5.htm

Page 32: Apoo Jacques Ufcg

Modelo Conceitual: Adição de Associações Ainda estamos em Análise

Objetivos

Identificar associações num modelo conceitual Diferenciar associações de conhecimento e associações de entendimento de modelo

Introdução

Queremos associar conceitos de forma a: Satisfazer as necessidades de acesso a informação dos conceitos Deixar o modelo conceitual mais fácil de entender

Associações

Uma associação é um relacionamento estrutural entre conceitos que indica uma conexão interessante e útil

Critério de associações úteis Associações "de conhecimento" (need-to-know) representam a conhecimento de um

relacionamento que deve ser preservado por algum tempo Entre quais objetos precisamos ter memória de um relacionamento? Exemplo: Um "Item de detalhe de uma venda" tem uma associação com uma

instância de uma Venda Caso contrário, não poderíamos calcular o total da venda, emitir o recibo, etc.

Vão implicar em algum tipo de navegação no projeto e na implementação

Page 1 of 6Modelo Conceitual: Adição de Associações

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal2.htm

Page 33: Apoo Jacques Ufcg

Outras associações que podem ser úteis são aquelas que melhoram o entendimento do modelo conceitual

Notação UML para associações

Associações são sempre bi-direcionais Não há informação de navegabilidade num modelo conceitual Conceitualmente, a navegabilidade existe nos dois sentidos Escolher o verbo para representar uma direção ou outra é arbitrário

Prefere-se manter a voz ativa no verbo É melhor "Registra-a-atual" do que "É-registrada-por"

Não há implicação sobre a existência de ponteiros, chaves estrangeiras, etc. A seta de direção de leitura é opcional e indica como ler o nome da associação

A seta não possui informação semântica Pode haver informação de multiplicidade nas extremidades das associações

Como achar associações: a lista de associações comuns

Os exemplos são dos domínios de uma Loja e da reserva de passagem aérea Categoria de Associação Exemplos

A é uma parte física de B Gaveta-TPDV Asa-Aeronave

A é uma parte lógica de B Item de detalhe de vanda-Venda Trecho de vôo-Rota de vôo

A é fisicamente contido em B TPDV-Loja, Item-Prateleira Passageiro-Aeronave

A é logicamente contido em B Descrição de item-Catálogo Vôo-Schedule de vôo

Page 2 of 6Modelo Conceitual: Adição de Associações

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal2.htm

Page 34: Apoo Jacques Ufcg

Algumas categorias de associações sempre são úteis num modelo conceitual A é uma parte física ou lógica de B A está fisicamente ou logicamente contido em B A é registrado em B

Nível de detalhamento das associações

Não inclua associações demais no modelo É muito mais importante achar conceitos do que associações

Nomes de associações

Use uma frase com verbo que facilite a leitura quando juntada com os conceitos em cada extremidade

Exemplo: Loja Estoca Item Associações são normalmente lidas da esquerda para a direita e de cima para baixo

A é uma descrição de B Descrição de item-Item Descrição de vôo-Vôo

A é uma linha de detalhe de uma transação ou relatório B Item de detalhe de vanda-Venda Tarefa de manutenção-Log de manutenção

A é conhecido/logado/registrado/reportado/capturado por ou em B

Venda-TPDV Reserva-Lista de passageiros

A é um membro de B Caixa-Loja Piloto-Viação aérea

A é uma subunidade organizacional de B Departamento-Loja manutenção-Viação aérea

A usa ou gerencia B Caixa-TPDV Piloto-Aeronave

A se comunica com B Cliente-Caixa Agente de reserva-Passageiro

A está relacionado com uma transação B Cliente-Pagamento Passageiro-Ticket

A é uma transação relacionada com outra transação B Pagamento-Venda Reserva-Cancelamento

A é vizinho de B TPDV-TPDV Cidade-Cidade

A pertence a B TPDV-Loja Aeronave-Viação aérea

Page 3 of 6Modelo Conceitual: Adição de Associações

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal2.htm

Page 35: Apoo Jacques Ufcg

Associações múltiplas entre dois tipos

Exemplo segue

Associações e implementação

Durante a análise associações não implicam em fluxos de dados ou informação de navegabilidade

A implementação de uma associação será frequentemente uma referência entre dois objetos

Porém, algumas associações da análise não serão implementadas Novas associações que forem implementadas (na fase de implementação) devem ser

adicionadas ao modelo conceitual (foram esquecidas durante a modelagem conceitual)

Associações no Domínio do TPDV

Usam-se as duas técnicas mostradas acima para identificar associações Associações de conhecimento (que implicam que um objeto deve conhecer o outro) Usando a lista de associações comuns

Associações de conhecimento na loja As seguintes associações são do tipo "conhecimento"

Usando a lista de associações comuns

Associação Por que implica em conhecimento

TPDV Captura Venda Para poder conhecer a venda corrente, calcular o total e imprimir um recibo

Venda Paga-com PagamentoPara poder saber se a venda foi paga, comparar o valor recebido do cliente com o total e imprimir um recibo

CatálogoDeProduto Registra EspecificaçãoDeItem

Para poder obter uma especificação de item, dado um código UPC

Page 4 of 6Modelo Conceitual: Adição de Associações

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal2.htm

Page 36: Apoo Jacques Ufcg

Examinemos a aplicabilidade de cada categoria

O modelo conceitual para o domínio TPDV

Ver modelo conceitual parcial (sem atributos) abaixo

Categoria de Associação Sistema TPDV

A é uma parte física de B não se aplica

A é uma parte lógica de B Item de detalhe de venda-Venda

A é fisicamente contido em B TPDV-Loja Item-Loja

A é logicamente contido em B Especificação de produto-Catálogo de produtos Catálogo de produto-Loja

A é uma descrição de B Especificaão de produto-Item

A é uma linha de detalhe de uma transação ou relatório B Item de detalhe de venda-Venda

A é conhecido/logado/registrado/reportado/capturado por ou em B

Venda (completada)-Loja (é logada por) Venda (atual)-TPDV (é capturada por)

A é um membro de B Caixa-Loja

A é uma subunidade organizacional de B não aplicável

A usa ou gerencia B Caixa-TPDV Gerente-TPDV Gerente-Caixa (mas provavelmente não aplicável no sistema)

A se comunica com B Cliente-Caixa

A está relacionado com uma transação B Cliente-Pagamento Caixa-Pagamento Reserva-Cancelamento

A é uma transação relacionada com outra transação B Pagamento-Venda

A é vizinho de B TPDV-TPDV (mas provavelmente não aplicável no sistema)

A pertence a B TPDV-Loja

Page 5 of 6Modelo Conceitual: Adição de Associações

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal2.htm

Page 37: Apoo Jacques Ufcg

Pode-se debater cada associação para verificar a utilidade de ser incluída no modelo Uma associação que implica conhecimento normalmente fica As demais ficam se esclarecerem o modelo

Não há modelo único "correto" Podemos argumentar que algumas associações do modelo poderiam sumir

Exemplos Nenhuma das associações seguintes implica em conhecimento

Venda Entrada-por Caixa Isso mudaria se precisássemos da identificação do caixa no recibo

TPDV Iniciado-por Gerente Venda Iniciada-por Cliente Loja Estoca Item LinhaDetalheVenda Registra-Venda-de Item

anal1-2 programa anterior próxima

Page 6 of 6Modelo Conceitual: Adição de Associações

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal2.htm

Page 38: Apoo Jacques Ufcg

Modelo Conceitual: Adição de Atributos Ainda estamos em Análise

Objetivos

Identificar atributos num modelo conceitual Distinguir entre atributos corretos e incorretos

Introdução

Precisamos identificar os atributos que servirão para satisfazer as necessidades de informação dos Use Cases sob consideração na iteração corrente

Lembre que os atributos são do domínio do problema

Atributos

Um atributo é um valor de dado lógico de um objeto (ou instância de conceito) Os atributos são identificados primariamente localizando a necessidade de lembrar

informação Exemplo: Uma Venda tem atributos data e hora

Notação UML para atributos

Os tipos podem ser opcionalmente mostrados

Atributos válidos

Manter os atributos de tipos simples Atributos são normalmente de tipos básicos

Boolean, Date, Number, String (ou Text), Time

Page 1 of 3Modelo Conceitual: Adição de Atributos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal3.htm

Page 39: Apoo Jacques Ufcg

Podem ser de outros tipos comuns tais como Endereço, Cor, Geométricos (Point, Rectangle, ...), Fone, CPF, UPC (Universal

Product Code), SKU (Stock Keeping Unit), CEP Não se deve representar associações como atributos

Repetição de um exemplo anterior em que um destino de vôo não é um atributo

Valores puros de dados Um valor é puro quando não possuem identidade

Não precisamos distinguir entre instâncias de mesmo valor Exemplos: não precisamos distinguir entre

Instâncias separadas do Number 5 Instâncias separadas do String "mamãe" Instâncias separadas de Fone contendo o mesmo número de telefone Instâncias separadas de Endereço contendo o mesmo endereço

Por outro lado, duas Pessoas chamadas "Sicrano da Silva" devem ser distinguida (têm identidade diferente), apesar do nome igual

Resultado: apenas um valor puro de dado pode ser representado como atributo

Não usar chaves estrangeiras como atributos Na construção de esquemas lógicos de bancos de dados, é comum usar chaves

estrangeiras como atributos Isso não deve ser feito num modelo conceitual (OO ou não)

Exemplo

Page 2 of 3Modelo Conceitual: Adição de Atributos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal3.htm

Page 40: Apoo Jacques Ufcg

Uso de tipos não primitivos Pode-se escolher entre usar tipos não primitivos que representem valores puros como

associação ou como atributo, conforme o desejo do analista ou a situação particular O importante é que a comunicação das idéias sobre o modelo esteja clara

Exemplo

Modelagem de quantidades e unidades Cuidado! Certos atributos parecem "números" mas podem ter algo mais associado

Valores financeiros podem ter uma moeda, além do valor Uma quantidade pode ter uma unidade (velocidade em km/s), além do valor

Atributos para o sistema TPDV

Só estamos considerando os Use Cases da primeira iteração Para achar os atributos, lêem-se os requisitos, Use Cases da iteração, outros

documentos explicativos Muitos atributos poderão não ser descobertos na análise e serão identificados apenas no

projeto ou na implementação Podemos ver o modelo conceitual final com os atributos abaixo

anal1-3 programa anterior próxima

Page 3 of 3Modelo Conceitual: Adição de Atributos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal3.htm

Page 41: Apoo Jacques Ufcg

Comportamento Dinâmico: Contratos Ainda estamos em Análise

Objetivos

Criar contratos para as operações do sistema

Introdução

Estamos continuando a investigar o comportamento dinâmico do sistema Contratos descrevem os efeitos que as operações têm no sistema Em UML, contratos são especificados usando pré-condições e pós-condições Contratos são estabelecidos depois temos o modelo conceitual, que fizemos os

diagramas de sequência e que identificamos as operações no sistema Continuamos com uma visão de caixa preta para o sistema (queremos caracterizar o que

o sistema faz e não como o faz)

Contratos

O diagrama de sequência não menciona a funcionalidade das operações Isto é, o comportamento do sistema

Um contrato é um documento que descreve o que uma operação promete cumprir As pré- e pós-condições descrevem as mudanças de estado do sistema Contratos podem ser associados a operações do sistema como um todo ou a métodos

individuais (na fase de projeto) Consideraremos apenas contratos de operações de sistema

Exemplo de um contrato

Page 1 of 3Comportamento Dinâmico: Contratos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal6.htm

Page 42: Apoo Jacques Ufcg

Segue um contrato possível para a operação entrarItem

Alguns comentários O tipo pode ser Sistema, Classe de software ou Interface, dependendo do tipo de

contrato que se está elaborando As anotações podem indicar dicar para a fase de projeto, algoritmos especiais

desejados, etc. A saída indica informação que sai do sistema (mensagens, registros, ...), sem incluir

a interface com o usuário As pré-condições mencionam as suposições sobre o estado do sistema antes da

execução da operação Muitas dessas coisas poderão ser testadas durante a implementação

(programação defensiva) As pós-condições mencionam as alterações ao estado do sistema como resultado da

execução da operação (isto, é depois que a operação terminou) As pós-condições podem ser descobertas nas seguintes categorias:

Criação e destruição de instâncias Modificação de atributos Associações formadas e quebradas

Não mencione ações que são feitas na operação mas mudanças que ocorreram no estado do sistema

Tire uma foto do sistema antes e depois da operação e descreva a diferença entre as duas fotos

Descrevemos o que ocorreu e não como ocorreu Outros contratos podem ser vistos no livro de Larman

Relação com outros artefatos

Nome entrarItem(upc:número, quantidade:integer)

Responsabilidades Registrar a venda de um item a adicionar seu valor ao total da venda. Exibir a descrição do item e seu preço

Tipo Sistema

Referências cruzadas Funções do sistema: R1.1, R1.3, R1.9

Anotações

Exceções Se o UPC não for válido, indicar erro

Saída Faz log da venda completada

Pré-condições UPC é conhecido pelo sistema

Pós-condições

Se for uma nova venda, uma Venda foi criada (criação de instância) Se for uma nova venda, a nova Venda foi associada ao TPDV (formação de associação) Uma LinhaDetalheVenda foi criada (criação de instância) A LinhaDetalheVenda foi associada à Venda (formação de associação) LinhaDetalheVenda.quantidade recebeu o valor quantidade (mudança de atributo) A LinhaDetalheVenda foi associada com uma EspecificaçãoProduto, baseado no casamento de

UPC (formação de associação)

Page 2 of 3Comportamento Dinâmico: Contratos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal6.htm

Page 43: Apoo Jacques Ufcg

anal1-6 programa anterior

Page 3 of 3Comportamento Dinâmico: Contratos

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal6.htm

Page 44: Apoo Jacques Ufcg

Construção do Glossário Ainda estamos em Análise

Objetivos

Expressar termos num glossário

Introdução

Um glossário é um documento simples que descreve termos A definição de termos do domínio do problema é importantíssimo para manter limpa a

comunicação entre desenvolvedores e clientes Para reduzir o risco de falahas de entendimento Para ajudar a introduzir novos membros na equipe no meio do projeto

O glossário é elaborado em paralelo com outras fases e é elaborado ao longo da vida do projeto Pode incluir definições de tipos, business rules, Use Cases, atributos, etc.

Eu particularmente não gosto de repetir informação aqui que esteja em outro lugar Exemplo: descrição de atributos que poderão estar em outro documento

Serve como dicionário particular do projeto

Exemplo de glossário (incompleto) para o domínio TPDV

anal1-4 programa anterior próxima

Termo Categoria Comentário

Comprar Itens Use Case Descrição do processo que envolve a compra de itens por um cliente numa loja

EspecificaçãoProduto.descrição atributo Uma descrição curta de um item de venda

Item tipo Um item à venda numa Loja

Pagamento tipo Um pagamento em dinheiro vivo

LinhaDetalheVenda.quantidade atributo A quantidade de um tipo de item comprado

Venda tipo Uma transação de venda

LinhaDetalheVenda tipo O detalhamento da venda de um item particular numa Venda

Loja tipo O lugar onde vendas de itens ocorrem

Venda.total atributo O valor total de uma Venda

EspecificaçãoProduto.UPC atributo O Universal Product Code do item

Page 1 of 1Construção do Glossário

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal1\anal4.htm

Page 45: Apoo Jacques Ufcg

4. Fase de Projeto 1 Da análise ao projeto Projeto arquitetural Descrição de use cases reais Diagramas de colaboração Padrões para atribuir responsabilidades Projeto de soluções com objetos e padrões Visibilidade Diagramas de classe para a fase de projeto Esquema de banco de dados e mapeamento OO-Relacional

proj1 programa

Page 1 of 14. Fase de Projeto 1

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\index.htm

Page 46: Apoo Jacques Ufcg

Da Análise ao Projeto A análise se concentra na questão "O quê?"

Entendimento dos requisitos, conceitos e operações relacionados a um sistema A próxima fase é a de Projeto, onde a questão "Como?" é abordada O projeto de um sistema é dividido em duas partes

Projeto arquitetural (ou Projeto de Alto Nível) Projeto detalhado (ou Projeto de Baixo Nível)

O projeto arquitetural lida com questões "macro" O projeto detalhado lida com objetos individuais e suas interações

Procura-se resolver o problema de atribuir responsabilidades às classes Também trata de resolver as questões de persistência de objetos Padrões de Projeto (Design Patterns) são extremamente úteis durante o Projeto

detalhado

proj1-1 programa próxima

Page 1 of 1Da Análise ao Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj1.htm

Page 47: Apoo Jacques Ufcg

Projeto Arquitetural

Resumo da seção

Projeto de uma arquitetura Decomposição do sistema: partições e camadas Arquiteturas em n camadas Uso de UML para modelar a arquitetura Estruturas de controle Opções de persistência Reutilização: Frameworks e componentização Resumo: Perguntas a fazer ao elaborar um projeto arquitetural

Projeto de uma arquitetura

O que é um projeto arquitetural? Decisões estratégicas que terão consequências profundas As decisões são tomadas num alto nível

Exemplos de decisões Modularização do projeto em subsistemas Escolha de uma estrutura de comunicação e controle entre os subsistemas Escolha da divisão de trabalho entre membros de uma equipe ou entre equipes de

desenvolvimento Definição das interfaces entre subsistemas para possibilitar o trabalho paralelo de

desenvolvimento Escolha de uma estratégia de persistência Escolha do paradigma de DBMS a usar Determinação de oportunidades para o reuso de software Atendimento a requisitos especiais de desempenho Atendimento a outros requisitos (custo, mobilidade, uso de padrões, etc.) Exposição das interfaces para facilitar a futura integração de aplicações (Enterprise

Application Integration - EAI) etc.

Observe que sempre deve-se ter um olho na satisfação dos requisitos levantados Veremos vários aspectos do projeto arquitetural

A discussão é direcionada mais a sistemas de informação

Page 1 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 48: Apoo Jacques Ufcg

Decomposição do sistema: partições e camadas

Uma estrutura elegante pode frequentemente ser elaborada usando camadas e partições Uma camada é um subsistema que adiciona valor a subsistemas de menor nível de

abstração Uma partição é um subsistema "paralelo" a outros subsistemas

Lembre que subsistemas devem ser coesos (trata de responsabilidades fortemente relacionadas)

Tem forte acoplamento dentro de um subsistema Tem fraco acoplamento entre subsistemas

Para minimizar o acoplamento, camadas frequentemente se comunicam apenas com as camadas "vizinhas"

A decomposição pode terminar quando você atingir subsistemas com temas claros que sejam simples de entender

Alguns sistemas muito pequenos não necessitam de camadas e partições

Arquiteturas em n camadas

Para sistemas de informação que incluam uma interface com o usuário e persistência (isto é, quase todos!), usa-se frequentemente uma arquitetura em 3 camadas (3-tier architecture)

As camadas verticais são: Apresentação: janelas, relatórios, etc.

Também chamada de Camada de Interface com o Usuário, Camada de Serviços do Usuário

Page 2 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 49: Apoo Jacques Ufcg

Lógica da Aplicação: tarefas e regras que governam o processo Também chamada de Camada de Aplicação, Ccamada de Serviços de Aplicação

Dados: mecanismo de armazenamento persistente Também chamada de Camada de Gerência de Dados, Camada de Serviços de

Dados, Camada de Armazenamento O que vai em cada camada pode mudar ligeiramente

Exemplo: é possível (e pode ser desejável) ter alguma lógica de aplicação na camada de dados usando Stored Procedures

Exemplo: é possível (mas em geral indesejável) ter alguma lógica de aplicação na camada de apresentação usando linguagens de scripts

Em que máquina cada camada roda pode variar, mas hoje em dia, a distribuição física completa é comum

Por que uma arquitetura em 3 camadas? Sistemas em camadas surgiram para aproveitar os PCs da empresa e oferecer

sistemas com interface gráficas amigáveis e integradas ao desktop Os primeiros sistemas cliente-servidor eram de duas camadas (juntando as camadas

de apresentação e de aplicação) mas sofriam de vários problemas: Falta de escalabilidade (conexões a bancos de dados) Enormes problemas de suporte (mudanças à lógica de aplicação forçava

instalações) Nenhum suporte a Thin Clients (PDA, celulares, smart cards, quiosques, ...) Dificuldade de acessar fontes heterogêneas (legado CICS, 3270, ...) Dificuldade de criar software reutilizável para rodar em clientes

Além do mais, a arquitetura em 3 camadas permite: Usar o browser como cliente universal, levando ao conceito de Intranet Evitar instalação em computadores de clientes, parceiros, fornecedores, etc. Implementar serviços automáticos de persistência, tolerência a falhas com fail-

over, gerência de transações, balanceamento de carga, resource pooling, etc. Enterprise JavaBeans, COM+

Arquitetura em n camadas Podemos dividir a camada de aplicação em mais de uma camada

Frequentemente feito separando as aspectos relacionados ao domínio do problema e os aspectos de serviços

Podemos também dividir a camada de dados em mais camadas (usando um datawarehouse, por exemplo)

Uso de UML para modelar a arquitetura

UML provê o conceito de package para agrupar elementos Este mecanismo pode ser utilizado para evidenciar os subsistemas e suas dependências Um package em UML:

Page 3 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 50: Apoo Jacques Ufcg

A arquitetura em camadas pode ser representada em UML:

A arquitetura detalhada e as dependências (acoplamento) entre packages podem ser representadas em UML:

Estruturas de controle

O paradigma de controle externo da aplicação deve ser escolhido O paradigma diz como uma aplicação é controlada "de fora" e como interage com

seus usuários e outras aplicações O controle interno dos objetos da aplicação não é visível fora da aplicação

Page 4 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 51: Apoo Jacques Ufcg

Há vários paradigmas de controle externo Controle orientado a procedimento

Tem um único thread no programa Métodos executam chamadas para obter dados de entrada e esperam os dados O estado do programa pode ser guardado em variáveis locais aos procedimentos

(na pilha de execução) Vantagem: fácil de implementar com linguagens convencionais Desvantagem: qualquer paralelismo inherente aos objetos deve ser mapeado a

um fluxo de controle sequencial Frequentemente usado em aplicações que possuem uma interface não gráfica

Controle orientado a evento Um dispatcher é provido pela linguagem, SGBD, linguagem ou sistema

operacional Métodos da aplicação são amarrados a eventos

Quando o evento ocorre, o método correspondente é chamado Todos os métodos retornam o controle para o dispatcher em vez de esperar que

os dados de entrada cheguem O estado do programa deve ser guardado em variáveis globais já que os métodos

retornam o controle (e não ficam com ele) Vantagem: ajuda a separar a lógica da aplicação da interface com o usuário Frequentemente usado com SGBD munido de linguagem de quarta geração Muito usado com bancos de dados Quase sempre usado para controlar uma interface gráfica

Controle concorrente O controle fica com vários objetos autônomos, cada um respondendo a eventos A concorrência é provida pelo sistema operacional

Usando paralelismo em hardware ou não Observe que estamos nos referindo a controle concorrente dentro da aplicação e

não entre aplicações Este último é muito comum (sessões paralelas de acesso a BD, por exemplo)

Infrequentemente usado, embora seu uso tenda a crescer com o CORBA (framework de objetos distribuídos)

Controle declarativo O programa usa um fluxo de controle implícito beaseado em statements

declarativos Usado em sistemas especialistas baseados em regras

Dois padrões de controle frequentemente utilizados na arquitetura são: Observer Pattern (ou Publish-Subscribe) para acoplar objetos ou subsistemas Model-View-Controller (MVC) para separar os objetos de domínio dos objetos de

interface Serão descritos em outro capítulo (sobre Design Patterns)

Opções de persistência

Tratamos aqui apenas dos aspectos arquiteturais da persistência Um capítulo à frente trata mais detalhadamente do mapeamento de projetos OO para

esquemas de BD relacionais Três grandes pontos devem ser tratados com respeito à persistência de objetos:

Escolha da forma básica de persistência (na memória, em arquivos, usando um SGBD)

Escolha do paradigma de SGBD (se usar um SGBD) Determinação da estratégia de interação entre a aplicação e os dados

Page 5 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 52: Apoo Jacques Ufcg

Escolha da forma básica de persistência As alternativas básicas são:

Dados na memória Dados em arquivos Dados sob controle de um BD

Muitas aplicações requerem necessariamente os serviços de um BD, mas algumas podem funcionar bem com uma alternativa mais simples

Os seguintes pontos devem ser avaliados para tomar a decisão sobre a forma de persistência:

Persistência de dados Arquivos e SGBDs são fortes Ficar com os dados na mamória requer um suporte especial de memória e fontes

de alimentação para prevenir a perda de informação Custo de aquisição

Um SGBD pode ser muito caro Se houver um site license já em uso, o custo incremental pode ser pequeno

O hardware para manter dados na memória pode ser caro Arquivos nada custam pois são inherentemente suportados pelo sistema

operacional Custo total de posse (Total Cost of Ownership)

Custos incluem a aquisição, treinamento, desenvolvimento, implantação, operação e manutenção

Qualquer uma das 3 alternativas pode ganhar aqui Exemplo: SGBD pode reduzir custos de desenvolvimento mas aumenta custos

de operação (incluindo recursos humanos) Exemplo: arquivos não têm custo de aquisição mas têm um alto custo de

manutenção Quantidade de dados

SGBDs podem armazenar gigantescas quantidades de informação Recursos de hardware limitam a quantidade de dados que pode ser armazenada

na memória Arquivos são limitados em tamanho pelo sistema operacional

Cuidado com sistemas que limitam arquivos a 32 bits (4 GBytes) Desempenho

xdados na memória são acessados mais rapidamente SGBDs têm algoritmos e estruturas de dados especiais para lidar com grandes

quantidades de dados Arquivos podem ser rápidos se couberem na memória ou se forem eficientemente

acessados sequencial ou randomicamente Extensibilidade

SGBDs oferecem independência de dados de forma que o desenvolvedor pode se concentrar nos aspectos lógicos dos dados, sem preocupação imediata com detalhes de implementação física

Acesso concorrente A granularidade de travamento pode afetar o desempenho Tipicamente, arquivos são travados por completo

Travamento de registros de arquivos requer muita programação A granularidade é melhor com dados na memória SGBDs podem ter boa granularidade (record locking) ou menos boa (page

locking) Além do mais, SGBDs podem escalonar travamentos e resolver conflitos

Page 6 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 53: Apoo Jacques Ufcg

automaticamente sem programação adicional Recuperação de crash

Arquivos: Arquivos de backup são necessários SGBDs: têm lógica sofisticada para recuperação de crash Memória: requer o uso de shadow memory

Integridade Apenas SGBDs oferecem o suporte a regras de integridade (definidas pelo

programador) Suporte a transações

Apenas SGBDs oferecem suporte a transações Distribuição

Apenas (alguns) SGBDs oferecem suporte à distribuição de dados e vários sites Linguagem de consulta

SGBDs oferecem linguagens de consulta para facilitar o manuseio de dados Alguns produtos do mercado oferecem linguagens de consulta simples para dados

em arquivos Segurança

Arquivos podem ser protegidos pelo sistema operacional (mas sem sofisticaão) SGBDs podem implementar segurança com passwords, views, etc.

Metadados SGBDs permitem a manipulação da estrutura dos dados (metadados) em tempo

de execução Um sumário segue:

Em suma, algumas aplicações naturalmente se beneficiam de cada alternativa de persistência:

Dados na memória Dados para dispositivos eletrônicos (celulares, PDAs, ...) Dados para smart cards, cartuchos de jogos Dados para aplicações que não podem tolerar o custo ou falta de confiabilidade

de um disco Arquivos

Dados na memória Arquivos SGBDs

Persistência de dados Requer hardware especial Bom suporte Bom suporte

Custo de aquisição Custo do hardware especial Não há Pode ser caro

Custo total de posse Variável Variável Variável

Quantidade de dados Limitado pelo hardwareLimitado pelo sostema operacional; A memória limita files em cache

Essencialmente sem limite

Desempenho Muito rápidoRápido para acesso sequencial, certos acessos randômicos e para arquivos em cache

Rápido

Estensibilidade Limitada Limitada Excelente

Acesso concorrente Locking de objetos Locking de arquivos

Locking de objetos ou de registros; Alguns SGBDs só têm locking de páginas

Recuperação de crash Shadow memory Arquivos de backup Bom suporte

Integridade Não há Não há Projetista pode especificar regras

Suporte a transações Não há Não há Transações curtas

Distribuição Não há Não há Às vezes

Linguagem de consulta Não há Parcial Poderosa

Segurança Não há Proteção simples do sistema operacional Pode ser simples ou sofisticado

Metadados Não há Não há Sim

Page 7 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 54: Apoo Jacques Ufcg

Dados de grande volume, com pouca densidade de informação (archival files, registros históricos detalhados, logs, ...)

Dados crus que devem ser sumarizados num BD (exe.: aquisição de dados, telemetria, ...)

Quantidades modestas de dados com estrutura simples (quando não tem SGBD ou este seria complexo demais para a empresa manter)

Dados acessados sequencialmente Dados que são lidos por inteiro na memória

SGBDs Dados que requerem atualização com níveis finos de granularidade por múltiplos

usuários Dados que devem ser acessados por várias aplicações Grandes quantidades de dados que devem ser eficientemente manipulados Dados de longa duração e muito valiosos a uma organização Dados que devem ser acessados com sofisticado controle de segurança Dados sujeitos a análise sofisticada para o apoio à decisão

Finalmente, observe que é comum utilizar mais do que uma única alternativa para dados diferentes

Escolha do paradigma de SGBD Se usar um SGBD, ainda deve-se escolher entre SGBDs relacionais, objeto-relacionais e

orientados a objeto Os detalhes fogem do escopo desta disciplina Resumindo:

SGBDRs são maduros mas sofrem de um problema sério: impedance mismatch entre objetos e relações

As grandes desvantagens são: Navegação lenta (usando joins de tabelas) Protocolos de travamento inflexíveis (por serem automáticos) Poucos tipos de dados Tudo tem que ser uma tabela

Mostraremos como mapear um projeto OO para um esquema relacional num capítulo à frente

SGBDOOs não são tão maduros mas não sofrem de impedance mismatch e apresentam recursos avançados (evolução de esquema, controle de versões, long transactions, notificações de mudanças, ...)

Oferecem navegação rápida mas ainda carecem até de uma teoria completa! Há ainda a alternativa de SGBDs Objeto-Relacionais que mantêm o paradigma relacional

mas resolvem algumas questões (tais como melhor suporte a tipos de dados)

Determinação da estratégia de interação entre a aplicação e os dados Quais são as estratégias para conectar sua aplicação a um SGBD? Pré-processador e pós-processador batch

Em alguns casos, é melhor que a aplicação não acesse o BD Aplicações batch existentes podem fazer uso de um BD de forma indireta Pode ser útil em algos (raros?) casos em que se usa software legado ou sem código

fonte dentro de uma aplicação (como subsistema)

Page 8 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 55: Apoo Jacques Ufcg

Arquivos de script Para certas aplicações simples, basta executar um ou mais arquivos contendo

comandos de uma linguagem de consulta (SQL, OQL, ...) Bom para certas situações tais como criar esquemas, popular um BD, prorotipagem

Comandos embutidos da linguagem de manipulação de dados de um SGBDOO Neste caso, a aplicação acessa o BD diretamente Parece natural devido ao casamento entre a linguagem hospedeira (digamos Java) e

um SGBDOO Cuidado! Ao proceder assim, o acoplamento com o SGBDOO fica muito forte e pode

ser difícil mudar de SGBD posteriormente Use o padrão ODMG para melhorar a portabilidade

Comandos SQL estáticos embutidos Código SQl estático é conhecido em tempo de compilação É relativamente simples de usar, mas:

Sem muitos cuidados (batching, etc.), pode resultar numa execução lenta Acopla muito o código da aplicação ao esquema do BD Resulta em código difícil de se ler

Em suma, tenta-se desta forma resolver o impedance mismatch com código estático Implementar uma API customizada de acesso aos dados

Os acessos ao BD são encapsulados em poucos métodos da aplicação Ajuda a manter a consistência dos dados Ajuda a manter o escopo de transações Ajuda a não contaminar a aplicação com um monte de código de acesso ao BD Técnica muito usada

Métodos armazenados no BD Stored procedures Boa forma de reuso para várias aplicações Certos cuidados ao usar Stored Procedures serão tratados num capítulo posterior

sobre persistência Cuidado! Stored Procedures não são implementados de forma portável pelos vários

SGBDs do mercado O padrão SQL não é obedecido pelos fabricantes

Linguagem de quarta geração SGBDRs normalmente vêm com uma linguagem 4GL Podem reduzir o esforço de desenvolvimento, mas não são portáveis

Page 9 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 56: Apoo Jacques Ufcg

Camada Genérica Orientada a Objeto Uma camada OO é escrita para completamente esconder o BD Ela pode ser genérica (para qualquer objeto, qualquer aplicação) com bastante

esforço Geralmente sofre com desempenho

Interação baseada em Metamodelo A camada de acesso ao BD acessa o metamodelo e constroi a consulta

dinamicamente A consulta resultante acessa o BD Solução frequentemente usada com frameworks Cuidado! Essa técnica requer muito esforço!

É melhor usar uma solução pronta, tal como Toplink

Uso de Middleware Os serviços de persistência podem ser obtidos automaticamente usando Middleware

Enterprise JavaBeans COM+

Vantagem: muitos serviços são obtidos além da persistência: Gerência de transações distribuídas Directory/Naming Segurança Tolerância a falha com Failover Balanceamento de carga Resource pooling Monitoring, logging, ...

Reutilização: Frameworks e componentização

Devido à sua importância, dedicamos um capítulo à frente sobre o tema de reutilização Frameworks

Criação de uma aplicação quase pronta que permite rapidamente criar várias aplicações de um mesmo domínio de problema

Componentes Pedaços de software que permitem a composição visual de aplicações em tempo

Page 10 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 57: Apoo Jacques Ufcg

de design

Resumo: Perguntas a fazer ao elaborar um projeto arquitetural

Sobre entidades externas ao sistema Quais sistemas externos devem ser acessados? Como serão acessados? Há integração com o legado a ser feita? Como?

Determinação de oportunidades para o reuso de software Há interesse/conveniência/tempo em aproveitar tais oportunidades? Como isso pode ser feito?

Com componentes? Construindo um framework?

Sobre a organização geral do sistema O sistema é centralizado ou distribuído? Como modularizar em subsistemas? Como minimizar acoplamento entre os pedaços? Lembrando que um sistema pode ser visto como sendo composto de três grandes

camadas lógicas ... Tais camadas serão lógicas ou terão existência física separada? Onde colocar o business logic (como dividir entre as camadas)? Qual é o nível de acoplamento, frequência de interações, volumes de dados trocados

entre as camadas? Qual seria a estrutura de comunicação e controle entre os subsistemas (como ligar as

camadas)? Usando o Observer Pattern? Usando o Model-View-Controller Pattern?

Quais são as interfaces importantes entre os pedaços? Qual é o formato das mensagens (xml, ...)? Como é feita a comunicação remota? CORBA? RPC? RMI? Message Queue?

A programação será feita com qual paradigma? OO? Que linguagens e ferramentas serão usadas?

Sobre a camada de interface O sistema será acessado usando que tipos de clientes?

Browser? Uso de applet? Uso de script cliente?

Como fazer a interface gráfica? Com que ferramentas? Com que componentes visuais?

Serão desenvolvidos? comprados? Javascript ou outra linguagem de script do lado cliente será usada?

Que modelo de componentes visuais será usado? Activex? Javabeans?

Se a interface usar um browser, como será feita a geração de HTML dinâmico? Servlets? JSP? ASP?

Page 11 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 58: Apoo Jacques Ufcg

Que ferramentas usar para a formatação de relatórios? Há packages a desenvolver que poderiam ser comuns a várias partes da interface?

Sobre a camada de lógica da aplicação Escolha de middleware: qual modelo de componentes de servidor será usado?

COM+? EJB?

Quais são os componentes principais a fazer? Serão componentes persistentes? Serão componentes com ou sem estado? De que forma atender aos requisitos para uso multiusuário?

Soluções para resolver a concorrência Que APIs serão usadas para acesso a:

Dados persistentes? Serviço de mail? Serviço de nomes?

Há packages a desenvolver que poderiam ser comuns a várias partes da lógica da aplicação?

Qual é a organização interna dos modulos executáveis? Determinar sub-camadas e partições

Quais são as interfaces importantes entre os pedaços? Onde verificar os business rules?

No SGBD? No middleware?

Como implementar aspectos de segurança? Como implementar os requisitos de auditoria?

Sobre a camada de dados persistentes Quais são as fontes de dados? externas? internas? existentes? novas? Como acessa-las? Que estratégia de persistência será usada:

Na memória (com recursos especiais como pilha)? Em arquivos? Usando um SGBD?

Qual paradigma de SGBD usar? Relacional? O-R? O-O?

Onde usar stored procedures para implementar os business rules ou garantir a integridade dos dados?

Qual será a estratégia de interação entre a aplicação e os dados? De que forma atender aos requisitos para uso multiusuário (concorrência)? Como resolver o impedance mismatch entre a camada de lógica de aplicação e o

esquema de persistência? Para grandes escalas, como oferecer connection pooling? Como implementar a segurança no SGBD? Como será feita a população dos bancos de dados?

Sobre requisitos de desempenho Há necessidade de bolar formas especiais de atender aos requisitos de desempenho?

Como prover escala? Como prover failover?

Page 12 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 59: Apoo Jacques Ufcg

O que deve ser produzido? Quais são os módulos executáveis a produzir?

Executáveis, DLLs, ... Quais são os arquivos importantes (de configuração, etc.) e seu formato (xml, ...)? Como será resolvida a instalação do produto? O que será comprado, feito, modificado? O que será gerado automaticamente com uma ferramenta especial?

Exemplo: geração de esquema através de ferramentas CASE, ...

Sobre a integração futura Que interfaces devem ser expostas para facilitar a futura integração de aplicações

(Enterprise Application Integration - EAI)? Pode-se usar uma camada de API para expor a camada de business logic, colocar

uma camada de script acima disso e ainda camada(s) de interface para ativar a business logic através de scripts.

Vantagens: Fácil criação de macros e outras formas de automação Fácil criação de testes de regressão Clara separação de business logic da interface para o usuário

Como será feita a exposição? Com XML? Através de uma API?

Perguntas adicionais Que ferramentas de desenvovimento serão geradas? Como será o atendimento a outros requisitos (custo, mobilidade, uso de padrões, etc.) Há considerações especiais de administração a levar em conta?

Como será a troca de versões? Como será a distribuição do software?

Via Internet/Intranet? Via mídia?

Pergunta final Você já verificou que a arquitetura bolada pode atender a todos os requisitos

levantados?

proj1-2 programa anterior próxima

Page 13 of 13Projeto Arquitetural

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj2.htm

Page 60: Apoo Jacques Ufcg

Descrição de Use Cases Reais

Use Cases reais são uma redefinição de Use cases essenciais mostrando o projeto do Use case em termos de tecnologias específicas de entrada e saída

Exemplo: se uma GUI é usada, as telas com todos seus campos podem ser usadas para detalhar o Use Case, mostrando as interações de baixo nível

Use Cases reais normalmente não são criados, só sendo necessários quando o cliente exige uma alto grau de detalhamento da interface com o usuário

Normalmente, basta ter um esboço das telas com os detalhes sendo aprontados durante a implementação

Exemplo

Use Case: Comprar item - versão 1 (pagamento à vista)

Atores: Cliente (iniciador), Caixa

Objetivo: Capturar uma venda e seu pagamento à vista

Resumo: Um Cliente chega ao caixa de saída com itens sendo comprados. O Caixa registra os itens comprados e recebe pagamento em espécie. No final, o Cliente sai com os itens.

Tipo: Primário e real

Referências cruzadas: Funções: R1.1, R1.2, R1.3, R1.7, R1.9, R2.1

Sequência Típica de Eventos

Ação do ator Resposta do Sistema

1. O Use Case inicia quando um Cliente chega ao TPDV com itens sendo comprados

2. Para cada item, o Cliente digita o Código Universal de Produto (UPC) no campo A acima. Se houver mais de um item, a

3. Adiciona o preço do item ao valor total da compra.

Page 1 of 2Descrição de Use Cases Reais

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj3.htm

Page 61: Apoo Jacques Ufcg

proj1-3 programa anterior próxima

quantidade é digitada no campo E. H é pressionado apõs a entrada de cada item

A descrição e preço do item corrente são exibidos nos campos B e F

4. Ao completar a entrada dos itens, o Cliente indica o fato pressionando I 5. Calcula e exibe o total da venda em C

6. ...

Page 2 of 2Descrição de Use Cases Reais

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj3.htm

Page 62: Apoo Jacques Ufcg

Diagramas de Colaboração

Introdução

Dois tipos de diagramas podem ser usados para mostrar as interações (mensagens) entre objetos

Diagramas de Sequência Diagramas de Colaboração

Os dois tipos de diagramas são chamados diagramas de interação O objetivo é de mostrar como as pós-condições dos contratos serão realizadas O diagrama de sequência é mais simples de usar quando se deseja mostrar apenas as

sequências de interações O diagrama de colaboração é mais adequado quando se deseja expressar mais detalhes

da colaboração entre objetos Exemplo de um diagrama de sequência:

Exemplo de um diagrama de colaboração

Page 1 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 63: Apoo Jacques Ufcg

No exemplo acima: A mensagem façaPagamento é enviada a uma instância de uma TPDV O TPDV envia a mensagem façaPagamento a uma instância de Venda O objeto da classe Venda cria uma instância de um Pagamento

Sobre a importância de diagramas de interação

Uma das coisas mais difíceis de fazer no projeto de um sistema é a atribuição de responsabilidades a objetos e a consequente colaboração entre objetos

Os diagramas de interação ajudam muito a construir o sistema e uma boa parcela do tempo deve ser dedicado à sua construção

É principalmente aqui que bons princípios de projeto serão usados Esta seção discute apenas a notação empregada em diagramas de colaboração Seções subsequentes tratarão da distribuição de responsabilidades entre objetos e

apresentar padrões de projeto

Como criar diagramas de colaboração

1. Criar um diagrama separado para cada operação do sistema sendo desenvolvida na iteração corrente. Para cada mensagem de operação do sistema, um diagrama é consttuído com essa mensagem inicial

2. Se o diagrama ficar complexo (não cabe numa única página), quebre-o em diagramas menores

3. Usando o contrato das operações (principalmente as pós-condições) e os Use Cases como ponto de partida, projete um sistema de objetos interagindo entre si para realizar as tarefas. Aplique padrões de projeto para desenvolver um bom projeto

Relação entre diagramas de colaboração e outros artefatos

Page 2 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 64: Apoo Jacques Ufcg

O Use Cases sugerem os eventos do sistema, os quais são mostrados explicitamente nos diagramas de sequência do sistema

Uma primeira aproximação do efeito das operações do sistema é descrita nos contratos As operações do sistema são mensagens que iniciam um diagrama de interação, o qual

ilustra como os objetos realizam a tarefa

Notação básica para diagramas de colaboração

Classe e instâncias

Links Um link é uma conexão entre dois objetos

É uma instância de uma associação Indica alguma forma de navegabilidade e visibilidade

Mensagens Observe o número de sequência das mensagens

Parâmetros O tipo do parâmetro é opcional

Page 3 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 65: Apoo Jacques Ufcg

Valor de retorno

Sintaxe de mensagem Pode-se usar a sintaxe UML (como acima) ou de outra linguagem (Java, por exemplo)

Mensagens a "this"

Iteração A iteração é mostrada com um número de sequência e um *

A mensagem é enviada repetidamente

Valores de recorrência podem ser incluídos

Mais de uma mensagem pode ser enviada na iteração

Page 4 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 66: Apoo Jacques Ufcg

Criação de instâncias A mensagem de criação independente de linguagem é "create" O estereótipo «new» pode ser usado

Sequenciamento de mensagens A primeira mensagem não é numerada

Tem várias alternativas para numerar as demais mensagens, incluindo um esuqema hierárquico

Page 5 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 67: Apoo Jacques Ufcg

Mensagens condicionais A mensagem só é enviada se o teste resultar em TRUE

Caminhos condicionais mutuamente exclusivos

Coleções Um conjunto de instâncias (multiobjeto)

Mensagens para coleções Na UML 1.1, uma mensagem enviada para uma coleção vai para o objeto-coleção e não

para todos os objetos da coleção Na UML 1.0, a mensagem ia para todos os objetos

Page 6 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 68: Apoo Jacques Ufcg

Outros exemplos de mensagens para objetos e coleções

Mensagens para a classe (métodos estáticos) Classe não está sublinhada

proj1-4 programa anterior próxima

Page 7 of 7Diagramas de Colaboração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj4.htm

Page 69: Apoo Jacques Ufcg

Padrões Para Atribuir Responsabilidades

Introdução

Um sistema OO é composto de objetos que enviam mensagens uns para os outros Uma mensagem é um método executado no contexto de um objeto

Escolher como distribuir as responsabilidades entre objetos (ou classes) é crucial para um bom projeto Uma má distribuição leva a sistemas e componentes frágeis e difíceis de entender, manter, reusar e estender

Mostraremos alguns padrões de distribuição de responsabilidades Padrões GRASP (General Responsibility Assignment Software Patterns) São padrões de Larman

Ao mostrar padrões, apresentaremos princípios de um bom projeto OO Veremos mais padrões de projeto em outros capítulos Os padrões são utilizados enquanto se cria diagramas de interação

Responsabilidades

Responsabilidades são obrigações de um tipo ou de uma classe Obrigações de fazer algo

Fazer algo a si mesmo Iniciar ações em outros objetos Controlar ou coordenar atividades em outros objetos

Obrigações de conhecer algo Conhecer dados encapsulados Conhecer objetos relacionados Conhecer coisas que ele pode calcular

Exemplos Uma Venda tem a responsabilidade de criar linha de detalhe (fazer algo) Uma Venda tem a responsabilidade de saber sua data (conhecer algo)

Granularidade Uma responsabilidade pode envolver um único método (ou poucos)

Exemplo: Criar uma linha de detalhe Uma reponsabilidade pode envolver dezenas de classes e métodos

Exemplo: Responsabilidade de fornecer acesso a um BD Uma responsabilidade não é igual a um método

Mas métodos são usados para implementar responsabilidades

Diagramas de interação evidenciam responsabilidades

O diagrama indica que objetos da classe Venda têm responsabilidade de criar linhas de detalhe de venda Eles devem colaborar com objetos da classe LinhaDetalheVenda

Page 1 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 70: Apoo Jacques Ufcg

Padrões

Uma definição informal: "Cada padrão descreve um problema que ocorre frequentemente e então descreve o cerne da solução ao problema

de forma a poder reusar a solução milhões de vezes em situações diferentes" Observe que o que é reutilizado são as classes e suas colaborações

Reuso de idéias, não código Consistem de micro-arquiteturas de classes, objetos, suas responsabilidades e suas colaborações

Contêm o somatório da experiência dos melhores projetistas O-O! Estão revolucionando o projeto de software desde 1995 quando o famoso livro da "Gang of Four" (GoF) apareceu com

o primeiro catálogo de 23 padrões Ver bibliografia Tem muito mais padrões aparecendo sempre OOPSLA é uma grande fonte de padrões

Ficará mais claro com alguns exemplos Design Patterns iniciaram a febre de padrões

Analysis Patterns Testing Patterns Business Patterns Pedagogical Patterns e mais ...

Os padrões GRASP são de Larman e são do tipo Design Patterns Veremos padrões GRASP e GoF (em outro capítulo)

Elementos essenciais de um Design Pattern

Um Nome Descreve o problema de projeto, suas soluções e consequências em poucas palavras Permite projetar num nível mais alto de abstração Permite falar com outros sobre soluções e documentar código, já que os nomes de padrões estão ficando padronizados

"Todo mundo" conhece os 23 padrões da GoF É equivalente a padronizar "lista encadeada", "pilha", etc. no mundo das estruturas de dados Cuidado! Nem todo mundo conhece os padrões de Larman

O Problema Descreve quando aplicar o padrão Descreve o problema e o contexto Pode descrever problemas específicos de projeto

Exemplo: como representar algoritmos como objetos? Pode descrever estruturas de objetos ou de classes que são sintomas de um projeto inflexível Às vezes, o padrão lista condições que devem se aplicar para usar o padrão

A Solução Descreve os elementos constituintes do projeto, seus relacionamentos, responsabilidades e colaborações A solução não descreve um projeto ou implementação concretos porque um padrão é um gabarito de solução para

várias situações

As Consequências Os resultados e trade-offs da aplicação do padrão Diz respeito a trade-offs de espaço, tempo, flexibilidade, extensibilidade, portabilidade

Os padrões GRASP deste capítulo

Expert Creator Low Coupling High Coesion Controller

Expert

Problema Qual é o princípio mais fundamental para atribuir responsabilidades?

Solução Atribuir uma responsabilidade ao expert de informação - a classe que possui a informação necessária para preencher a

responsabilidade

Exemplo No estudo de caso, alguma classe precisa saber o total de uma venda Podemos dizer isso sobre a forma de uma responsabilidade:

Page 2 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 71: Apoo Jacques Ufcg

Quem deveria ser reponsável pelo conhecimento do total de uma venda? Pelo padrão Expert, escolhemos a classe que possui a informação necessária para determinar o total Considere uma parte do modelo conceitual:

Qual é a informação necessária? Precisamos conhecer (ter acesso a) todos os LinhaDetalheVenda Qual é information expert? É a classe Venda

Podemos agora fazer parte do diagrama de colaboração e do diagrama de classes

Ainda não terminamos. Qual informação é necessária para determinar o subtotal para um item (uma linha de detalhe)? Precisamos de LinhaDeVenda.quantidade e de EspecificaçãoDeProduto.preço Quem é o information expert? É a classe LinhaDeVenda

Chegamos aos seguintes diagramas:

Qual é o information expert para saber o preço de um produto? É EspecificaçãoDeProduto

Chegamos aos seguintes diagramas:

Discussão É o padrão mais usado de todos para atribuir responsabilidades A informação necessária frequentemente está espalhada em vários objetos

Portanto, tem muitos experts parciais Exemplo: determinar o total de uma venda requer a colaboração de 3 objetos, em 3 classes diferentes

Mensagens são usadas para estabelecer as colaborações O resultado final é diferente do mundo real

No mundo real, uma venda não calcula seu próprio total Isso seria feito por uma pessoa (se não houvesse software) Mas no mundo de software, não queremos atribuir essa responsabilidade ao Caixa ou ao TPDV!

Page 3 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 72: Apoo Jacques Ufcg

No mundo de software, coisas inertas (ou até conceitos como uma venda) podem ter responsabilidades: Tudo está vivo!

Consequências A encapsulação é mantida, já que objetos usam sua própria informação para cumprir suas responsabilidades

Leva a fraco acoplamento entre objetos e sistemas mais robustos e fáceis de manter Leva a alta coesão, já que os objetos fazem tudo que é relacionado à sua própria informação

Também conhecido como "Colocar as responsabilidades com os dados" "Quem sabe, faz" "Animação" "Eu mesmo faço" "Colocar os serviços junto aos atributos que eles manipulam"

Creator

Problema Quem deve criar novas instâncias de uma classe?

Solução Atribuir à classe B a responsabilidade de criar instância da classe A se uma das seguintes condições se aplicar:

B agrega objetos da classe A B contém objetos da classe A B registra instâncias da classe A B usa muito objetos da classe A B possui os dados usados para inicializar A

B é um criador (creator) de objetos da classe A Se mais de uma opção se aplica, escolha o B que agregue ou contenha objetos da classe A

Exemplo No estudo de caso, quem deveria criar uma instância de LinhaDetalheVenda? Pelo padrão Creator, precisamos achar alguém que agrega, contém, ... instâncias de LinhaDetalheVenda Considere o modelo conceitual parcial abaixo:

Venda agrega instâncias de LinhaDetalheVenda e é portanto um bom candidato para criar as instâncias Chegamos aos seguintes diagramas:

Discussão Escolhemos um criador que deve estar conectado ao objeto criado, de qualquer forma, depois da criação Isso leva a fraco acoplamento Exemplo de criador que possui os valores de inicialização

Uma instância de Pagamento deve ser criada A instância deve receber o total da venda Quem tem essa informação? Venda Venda é um bom candidato para criar objetos da classe Pagamento

Consequências Fraco acoplamento, já que o objeto criado deve normalmente ser visível ao criador, depois da criação

Low Coupling

Problema Como minimizar dependências e maximizar o reuso?

Page 4 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 73: Apoo Jacques Ufcg

O acoplamento é uma medida de quão fortemente uma classe está conectada, possui conhecimento ou depende de outra classe

Com fraco acoplamento, uma classe não é dependente de muitas outras classes Com uma classe possuindo forte acoplamento, temos os seguintes problemas:

Mudanças a uma classe relacionada força mudanças locais à classe A classe é mais difícil de entender isoladamente A classe é mais difícil de ser reusada, já que depende da presença de outras classes

Solução Atribuir responsabilidades de forma a minimizar o acoplamento

Exemplo Considere o seguinte diagrama parcial de classes no estudo de caso

Suponha que temos que criar um Pagamento e associá-lo a uma Venda Que classe deveria ter essa responsabilidade? Alternativa 1: No mundo real, um TPDV "registra" um pagamento e o padrão Creator sugere que TPDV poderia criar

Pagamento TPDV deve então passar o pagamento para a Venda Veja o resultado abaixo

Alternativa 2: Criar o Pagamento com Venda e associá-lo à Venda Veja o resultado abaixo

Supondo que a Venda deva ter conhecimento do pagamento (depois da criação) de qualquer jeito, a alternativa 2 tem menos acoplamento (TPDV não está acoplado a Pagamento)

Dois padrões (Creator e Low Coupling) sugeriram diferentes soluções Minimizar acoplamento ganha

Discussão Minimizar acoplamento é um dos princípios de ouro do projeto OO Acoplamento de manifesta de várias formas:

X tem um atributo que referencia uma instância de Y X tem um método que referencia uma instância de Y

Pode ser parâmetro, variável local, objeto retornado pelo método X é uma subclasse direta ou indireta de Y X implementa a interface Y

A herança é um tipo de acoplamento particularmente forte Uma seção futura esmiuça o assunto

Não se deve minimizar acoplamento criando alguns poucos objetos monstruosos (God classes) Exemplo: todo o comportamento numa classe e outras classes usadas como depósitos passivos de informação

Tipos de acoplamentos (do menos ruim até o pior) Acoplamento de dados Acoplamento de controle Acoplamento de dados globais Acoplamento de dados internos

Acoplamento de dados Situações

Saída de um objeto é entrada de outro Uso de parâmetros para passar itens entre métodos

Ocorrência comum: Objeto a passa objeto x para objeto b Objeto x e b estão acoplados

Uma mudança na interface de x pode implicar em mudanças a b

Page 5 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 74: Apoo Jacques Ufcg

Exemplo:

class Servidor { public void mensagem(MeuTipo x) { // código aqui x.façaAlgo(Object dados); // dados e x estão acoplados // (se interface de dados mudar x terá que mudar) // mais código } }

Exemplo pior: Objeto a passa objeto x para objeto b x é um objeto composto ou agregado (contém outro(s) objeto(s)) Objeto b deve extrair objeto y de dentro de x Há acoplamento entre b, x, representação interna de x, y Exemplo: ordenação de registros de alunos por matrícula e nome

class Aluno { String nome; long matrícula; public String getNome() { return nome; } public long getMatrícula() { return matrícula; } // etc. } ListaOrdenada listaDeAlunos = new ListaOrdenada(); Aluno novoAluno = new Aluno(...); //etc. listaDeAlunos.add(novoAluno);

Agora, vamos ver os problemas

class ListaOrdenada { Object[] elementosOrdenados = new Object[tamanhoAdequado]; public void add(Aluno x) { // código não mostrado long matrícula1 = x.getMatrícula(); long matrícula2 = elementosOrdenados[k].getMatrícula(); if(matrícula1 < matrícula2) { // faça algo } else { // faça outra coisa } }

O problema da solução anterior é que há forte acoplamento ListaOrdenada sabe muita coisa de Aluno

O fato de que a comparação de alunos é feito com a matrícula O fato de que a matrícula é obtida com getMatrícula() O fato de que matrículas são long (representação de dados) Como comparar matrículas (com <)

O que ocorre se mudarmos qualquer uma dessas coisas? Solução 2: mande uma mensagem para o próprio objeto se comparar com outro

class ListaOrdenada { Object[] elementosOrdenados = new Object[tamanhoAdequado]; public void add(Aluno x) { // código não mostrado if(x.lessThan(elementosOrdenados[K])) { // faça algo } else { // faça outra coisa } }

Reduzimos o acoplamento escondendo informação atrás de um método Problema: ListaOrdenada só funciona com Aluno Solução 3: use interfaces para desacoplar mais ainda

Interface Comparable { public boolean lessThan(Object outro);

Page 6 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 75: Apoo Jacques Ufcg

public boolean greaterThan(Object outro); public boolean equal(Object outro); } class Aluno implements Comparable { public boolean lessThan(Object outro) { // compare registro de aluno com outro } } class ListaOrdenada { Object[] elementosOrdenados = new Object[tamanhoAdequado]; public void add(Comparable x) { // código não mostrado if(x.lessThan(elementosOrdenados[K])) { // faça algo } else { // faça outra coisa } }

Em C++, teria outras soluções Apontador de função Apontador de função com tipos genéricos (templates)

Acoplamento de controle Passar flags de controle entre objetos de forma que um objeto controle as etapas de processamento de outro

objeto Ocorrência comum:

Objeto a manda uma mensagem para objeto b b usa um parâmetro da mensagem para decidir o que fazer

class Lampada { public static final ON = 0; public void setLampada(int valor) { if(valor == ON) { // liga lampada } else if(valor == 1) { // desliga lampada } else if(valor == 2) { // pisca } } } Lampada lampapa = new Lampada(); lampada.setLampada(Lampada.ON); lampada.setLampada(2);

Solução: decompor a operação em múltiplas operações primitivas

class Lampada { public void on() { // liga lampada } public void off() { // desliga lampada } public void pisca() { // pisca } } Lampada lampada = new Lampada(); lampada.on(); lampada.pisca();

Ocorrência comum: Objeto a manda mensagem para objeto b b retorna informação de controle para a Exemplo: retorno de código de erro

class Teste { public int printFile(File toPrint) { if(toPrint está corrompido ) { return CORRUPTFLAG; } // etc. etc. } } Teste umTeste = new Teste(); int resultado = umTese.printFile(miniTeste); if(resultado == CORRUPTFLAG) { // oh! oh! } else if(resultado == -243) { // etc. etc.

Solução: use exceções

class Teste { public int printFile(File toPrint) throws PrintExeception { if(toPrint está corrompido ) {

Page 7 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 76: Apoo Jacques Ufcg

throw new PrintExeception(); } // etc. etc. } } try { Teste umTeste = new Teste(); umTeste.printFile(miniTeste); } catch(PrintException printError) { // faça algo }

Acoplamento de dados globais Dois ou mais objetos compartilham estruturas de dados globais É um acoplamento muito ruim pois está escondido

Uma chamada de método pode mudar um valor global e o código não deixa isso aparente Um tipo de acoplamento muito ruim

Acoplamento de dados internos Um objeto altera os dados locais de um outro objeto Ocorrência comum:

Friends em C++ Dados protected ou públicos de java

Use com cuidado!

Consequências Uma classefracamente acoplada não é afetada (ou pouco afetada) por mudanças em outras classes Simples de entender isoladamente Reuso mais fácil

High Coesion

Problema Como gerenciar a complexidade? A coesão mede quão relacionados ou focados estão as responsabilidades da classe

Também chamado coesão funcional (ver à frente) Uma classe com baixa coesão faz muitas coisas não relacionadas e leva aos seguintes problemas:

Difícil de entender Difícil de reusar Difícil de manter "Delicada": constantemente sendo afetada por outras mudanças

Uma classe com baixa coesão assumiu responsabilidades que pertencem a outras classes e deveriam ser delagadas

Solução Atribuir responsabilidades que mantenham alta coesão

Exemplo Mesmo exemplo usado para Low Coupling Na primeira alternativa, TPDV assumiu uma responsabilidade de efetuar um pagamento (método façaPagamento())

Até agora, não há problema Mas suponha que o mesmo ocorra com várias outras operações de sistema

TPDV vai acumular um monte de métodos não muito focados Resultado: baixa coesão

A segunda alternativa delega façaPagamento() para a classe Venda Mantém maior coesão em TPDV

Discussão Alta coesão é outro princípio de ouro que deve ser sempre mantido em mente durante o projeto

Page 8 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 77: Apoo Jacques Ufcg

Tipos de coesão entre módulos Coincidental (pior) Lógico Temporal Procedural De comunicação Sequencial Funcional (melhor)

Coesão coincidental Há nenhuma (ou pouca) relação construtiva entre os elementos de um módulo No linguajar OO:

Um objeto não representa nenhum conceito OO Uma coleção de código comumente usado e herdado através de herança (provavelmente múltipla)

class Angu { public static int acharPadrão(String texto, String padrão) { // ... } public static int média(Vector números) { // ... } public static outputStream abreArquivo(string nomeArquivo) { // ... } } class Xpto extends Angu { // quer aproveitar código de Angu ... }

Coesão lógica Módulo faz um conjunto de funções relacionadas, uma das quais é escolhida através de um parâmetro ao chamar o

módulo Semelhante a acoplamento de controle Cura: quebrar em métodos diferentes

public void faça(int flag) { switch(flag) { case ON: // coisas para tratar de ON break; case OFF: // coisas para tratar de OFF break; case FECHAR: // coisas para tratar de FECHAR break; case COR: // coisas para tratar de COR break; } }

Coesão temporal Elementos estão agrupados no mesmo módulo porque são processados no mesmo intervalo de tempo Exemplos comuns:

Método de inicialização que provê valores defaults para um monte de coisas diferentes Método de finalização que limpa as coisas antes de terminar

procedure inicializaDados() { font = "times"; windowSize = "200,400"; xpto.nome = "desligado"; xpto.tamanho = 12; xpto.localização = "/usr/local/lib/java"; }

Cura: depender de construtores e destrutores

Page 9 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 78: Apoo Jacques Ufcg

class Xpto { public Xpto() { this.nome = "desligado"; this.tamanho = 12; this.localização = "/usr/local/lib/java"; } }

Outro exemplo: arquivo de configuração típico

[Macintosh] EquationWindow=146,171,406,661 SpacingWindow=0,0,0,0 [Spacing] LineSpacing=150% MatrixRowSpacing=150% MatrixColSpacing=100% SuperscriptHeight=45% SubscriptDepth=25% LimHeight=25% LimDepth=100% LimLineSpacing=100% NumerHeight=35% DenomDepth=100% FractBarOver=1pt FractBarThick=0.5pt SubFractBarThick=0.25pt FenceOver=1pt SpacingFactor=100% MinGap=8% RadicalGap=2pt EmbellGap=1.5pt PrimeHeight=45% [General] Zoom=200 CustomZoom=150 ShowAll=0 Version=2.01 OptimalPrinter=1 MinRect=0 ForceOpen=0 ToolbarDocked=1 ToolbarShown=1 ToolbarDockPos=1 [Fonts] Text=Times Function=Times Variable=Times,I LCGreek=Symbol,I UCGreek=Symbol Symbol=Symbol Vector=Times,B Number=Times [Sizes] Full=12pt Script=7pt ScriptScript=5pt Symbol=18pt SubSymbol=12pt

Page 10 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 79: Apoo Jacques Ufcg

Coesão procedural Associa elementos de acordo com seus relacionamentos procedurais ou algorítmicos Um módulo procedural depende muito da aplicação sendo tratada

Junto com a aplicação, o módulo parece razoável Sem este contexto, o módulo parece estranho e muito difícil de entender

"O que está acontecendo aqui!!!????!!" Não pode entender o módulo sem entender o programa e as condições que existem quando o módulo é chamado Cura: reprojete o sistema

Coesão de comunicação Todas as operações de um módulo operam no mesmo conjunto de dados e/ou produzem o mesmo tipo de dado de

saída Cura: isole cada elemento num módulo separado "Não deveria" ocorrer em sistemas OO usando polimorfismo (classes diferentes para fazer tratamentos diferentes

nos dados) Coesão sequencial

A saída de um elemento de um módulo serve de entrada para o próximo elemento Cura: decompor em módulos menores

Coesão funcional (a melhor) Um módulo tem coesão funcional se as operações do módulo puderem ser descritas numa única frase de forma

coerente Num sistema OO:

Cada operação na interface pública do objeto deve ser funcionalmente coesa Cada objeto deve representar um único conceito coeso

Exemplo: um objeto que esconde algum conceito ou estrutura de dados ou recurso e onde todos os métodos são relacionados por um conceito ou estrutura de dados ou recurso

Meyer chama isso de "information-strength module"

Consequências Melhor claridade e facilidade de compreensão do projeto Simplificação da manutenção Frequentemente vai mão na mão com acoplamento fraco Com granularidade baixa e funcionalidade bem focada, aumenta o reuso

Controller

Problema Quem deveria receber a responsabilidade de tratar eventos do sistema? Um evento do sistema é um evento de alto nível gerado por um ator externo Estão associados a operações do sistema que já vimos nos Diagramas de Sequência do Sistema Exemplo do estudo de caso: Caixa pressiona "Fim de venda"

Solução Use um controlador

Um controlador é um objeto que não é de interface GUI responsável pelo tratamento de eventos do sistema Um controlador define métodos para as operações do sistema

Atribuir a responsabilidade pelo tratamento de eventos do sistema a uma classe de acordo com uma das alternativas abaixo:

Representa o "sistema" como um todo (facade controller) Representa o negócio ou organização como um todo (facade controller) Representa algo no mundo real que é ativo (por exemplo, o papel de uma pessoa) que poderia estar envolvido na

tarefa (role controller) Representa um handler artificial de todos os eventos do sistema para um Use Case particular, normalmente

chamado "<NomeDoUseCase>Handler" (use case controller)

Exemplo No estudo de caso, há várias operações de sistema:

Quem deveria ser o controlador para os eventos do sistema?

Page 11 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 80: Apoo Jacques Ufcg

Pelo padrão Controller, temos as seguintes alternativas: Representa o "sistema": TPDV Representa o negócio ou organização: Loja Representa algo no mundo real ...: Caixa Representa um handler artificial ...: CompraItemHandler

A escolha particular depende de fatores discutidos na seção Discussão Por exemplo, se fosse TPDV, teríamos:

Discussão De forma geral, o mesmo controlador deve ser usado para todas as operações de um mesmo Use Case de forma a

manter a informação de estado do Use Case A informação de estado pode ser útil para detectar sequências erradas de eventos de sistema

Exemplo: façaPagamento() antes de fimDeVenda() Não coloque toda a inteligência no controlador

Delegue para outros objetos,para manter coesão Use um Handler artificial quando as outras alternativas exibem acoplamento alto ou coesão baixa

Quando está surgindo um "God class" Usado em sistemas mais complexos

Observe que classes "Window", "Applet", "Application", "View", "Document" não devem ser controladores Tais classes podem receber o evento e delegá-lo ao controlador Não se deve colocar business logic num objeto de interface com o usuário Um design correto seria:

Um design incorreto seria:

Page 12 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 81: Apoo Jacques Ufcg

O Role Controller pode levar a um mau projeto O fato de algo ser feito por uma pessoa no mundo real não necessariamente significa que isso é uma boa

alternativa em software É mais comum "dar vida aos objetos" (não animados)

Consequências Maior possibilidade de reuso, já que o business logic não está nos objetos de interface

Exemplo: embutir o business logic num objeto de interface não permitiria fazer EAI (Enterprise Application Integration)

Ajuda a verificar o sequenciamento das operações do sistema, através do estado do controlador

Responsabilidades, Role Playing e Cartões CRC

Embora não faça parte de UML, uma técnica chamada Cartões CRC é muito usada para atribuir responsabilidades durante o projeto

CRC = Class-Responsibility-Collaborations CRC cards inventadas por Ward Cunningham e Kent Beck (Tektronix)

Cartão CRC é um cartão pequeno (para só escrever o essencial) para cada classe Escreve-se o nome da classe, suas responsabilidades e colaborações

Só pense nas responsabilidades de alto nível

São desenvolvidos em pequenos grupos em que cada pessoa assume o papel (Role) de uma ou mais classes Mais detalhes aqui:

Designing Object-Oriented Software, Wirfs-Brock, Wilkerson e Wiener; Prentice Hall, 1990. Algumas pessoas acham que é melhor usar ferramentas gráficas em vez de CRC

proj1-5 programa anterior próxima

Page 13 of 13Padrões Para Atribuir Responsabilidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj5.htm

Page 82: Apoo Jacques Ufcg

Projeto de Soluções com Objetos e Padrões

Introdução

O aluno é responsável por estudar o capítulo 19 do livro-texto (Larman) Trazer dúvidas para a aula

O capítulo utiliza padrões para atribuir responsabilidades e construir diagramas de colaboração para os seguintes Use Cases do estudo de Caso

Comprar Itens, com os seguintes eventos de sistema: entraItem fimDeVenda façaPagamento

Start Up, com o seguinte evento de sistema: startUp

Os diagramas de colaboração são resumidos abaixo

Diagramas de Colaboração

entraItem

Page 1 of 4Projeto de Soluções com Objetos e Padrões

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj6.htm

Page 83: Apoo Jacques Ufcg

fimDeVenda

totalDeVenda Não é operação de sistema, mas necessário para o cumprir o contrato

façaPagamento Incluindo log da venda

Page 2 of 4Projeto de Soluções com Objetos e Padrões

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj6.htm

Page 84: Apoo Jacques Ufcg

troco Não é operação de sistema, mas necessário para o cumprir o contrato

startUp Criação do objeto inicial de domínio e demais objetos

Conexão entre camadas de apresentação e de domínio

Page 3 of 4Projeto de Soluções com Objetos e Padrões

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj6.htm

Page 85: Apoo Jacques Ufcg

proj1-6 programa anterior próxima

Page 4 of 4Projeto de Soluções com Objetos e Padrões

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj6.htm

Page 86: Apoo Jacques Ufcg

Visibilidade

Introdução

Mensagens entre objetos só podem ocorrer se o receptor for visível ao remetente Há quatro formas básicas de visibilidade

Visibilidade de atributos Visibilidade de parâmetros Visibilidade declarada localmente Visibilidade global

Visibilidade de atributos

No estudo de caso, para que TPDV possa enviar uma mensagem a CatálogoDeProdutos, usa-se um atributo em TPDV

public class TPDV { private CatálogoDeProdutos catálogo; ... }

Visibilidade de parâmetros

Page 1 of 3Visibilidade

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj7.htm

Page 87: Apoo Jacques Ufcg

Um objeto tem visibilidade para outro se este for recebido como parâmetro No estudo de caso, para criar uma linha de detalhe de venda, TPDV chama

criaLinhaDetalhe de Venda, passando a especificação do produto Assim, Venda tem visibilidade para a especificação de produto

A visibilidade de parâmetro frequentemente é convertida para visibilidade de atributo Exemplo: LinhaDetalheVenda recebe a especificação de produto como parâmetro no

construtor e a especificação é armazenada como atributo de LinhaDetalheVenda

Visibilidade declarada localmente

Um objeto é visível a partir de uma variável local de um método Pode inicializar a variável local com um novo objeto, receber como valor de retorno

de alguma chamada, etc. Exemplo do estudo de caso:

Page 2 of 3Visibilidade

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj7.htm

Page 88: Apoo Jacques Ufcg

Visibilidade global

Um objeto global é visível a todos Não uma boa forma de ter visibilidade Se for obrigado a ter objetos globais, é melhor usar o padrão de projeto Singleton (GoF)

Visibilidade em UML

Uso de Stereotypes Não é usado em diagramas, normalmente

Visibilidade em Java

public para definir acesso a métodos públicos Que fazem parte da interface ao objeto para quem vai chamá-lo Não usa para atributos

private para acesso estritamente privado ao objeto (na realidade à classe) protected para definir acesso a métodos ou atributos que devem ficar disponíveis para

quem estende a classe (acessível a subclasses) "package" (sem modificador) para acesso quase público a todas as classes do package

Semelhante a friend de C++ usar com cuidado

proj1-7 programa anterior próxima

Page 3 of 3Visibilidade

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj7.htm

Page 89: Apoo Jacques Ufcg

Diagramas de Classe para a Fase de Projeto

Introdução

Ao completar os diagramas de interação, pode-se completar o diagrama de classes Na realidade, o diagrama de classes é criado em paralelo com os diagramas de interação

No final, falta incluir alguns detalhes finais

Exemplo de um Diagrama de Classes

Diagrama de classes na fase de projeto

Deve especificar as classes de software e as interfaces da aplicação Não somente das entidades conceituais

Informação tipicamente incluída: Classes, associações e atributos Interfaces, incluindo métodos e constantes Métodos Informação de tipo de atributos Navegabilidade Dependências

Page 1 of 6Diagramas de Classe para a Fase de Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj8.htm

Page 90: Apoo Jacques Ufcg

Como construir um diagrama de classes

1. Identificar todas as classes que participam da solução em software

Isso é feito pela análise dos diagramas de interação

2. Inclui-las num diagrama de classes

3. Duplicar os atributos, a partir das entidades associadas no modelo conceitual

4. Adicionar nomes de métodos descobertos nos diagramas de interação

5. Adicoonar informação de tipo aos atributos e métodos

6. Adicionar as associações necessárias para a visibilidade de atributos

7. Adicionar setas às associações para indicar a diração da visibilidade de atributos

8. Adicionar linhas de relações de dependência para indicar a visibilidade que não seja de atributo

Modelo conceitual versus diagrama de classes da fase de projeto

Para ambos, UML usa o diagrama de classes No modelo conceitual, uma entidade não representa uma classe de software mas um

conceito do domínio do problema No diagrama de classes da fase de projeto, as classes são de software

Criação dos diagramas de classe do estudo de caso

Identificar as classes de software Verificar todos os diagramas de interação para identificar classes Adicioná-las ao diagrama de classes, junto com os atributos Não precisa incluir classes que não participam da iteração atual

Page 2 of 6Diagramas de Classe para a Fase de Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj8.htm

Page 91: Apoo Jacques Ufcg

Adicionar nomes de métodos Analisar os diagramas de interação para descobrir os métodos de cada classe Alguns detalhes sobre métodos

O método create() de UML não aparece em muitas linguagens, pois é uma chamada a um construtor

Muitas vezes, não se incluem os métodos acessores (getAtributo() e setAtributo()) Se classes de bibliotecas (ex. Vector em Java) são mostrados no diagrama, não se

precisa mencionar seus métodos Pode-se usar a sintaxe da linguagem de programação final, se desejado

Diagrama até agora:

Adição de informação de tipo

Este passo é opcional

Page 3 of 6Diagramas de Classe para a Fase de Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj8.htm

Page 92: Apoo Jacques Ufcg

Se o diagrama de classes está sendo criado numa ferramenta CASE (ex. Rational Rose), e a ferramenta será usada para gerar código, todos os detalhes de tipos devem ser dados

Se o diagrama for preparado apenas para leitura por desenvolvedores, o nível de detalhamento pode ser menor

O seguinte diagrama contém toda a informação de tipo

Adicionar Associações e Navegabilidade

A navegabilidade implica visibilidade da fonte para o destino Normalmente navegabilidade de atributo, incluída na implementação

As associações devem ser apenas aquelas necessárias para a visibilidade de objetos Isso é diferente das associações no modelo conceitual, as quais podem ser incluídas

para melhorar o entendimento Os diagramas de interação são usados para descobrir a visibilidade, associações e

navegabilidade Situações comuns que levam a associações:

A envia uma mensagem a B A cria uma instância de B A deve manter conhecimento de B

Exemplo:

Page 4 of 6Diagramas de Classe para a Fase de Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj8.htm

Page 93: Apoo Jacques Ufcg

Diagrama de classes até agora:

Adição de relações de dependência

Quando uma classe conhece outra (tem visibilidade), mas a visibilidade não é de atributo, usa-se uma linha tracejada

Exemplo: TPDV recebe um objeto da classe EspecificaçãoDeProduto como retorno do método especificação da classe TPDV

Diagrama de classes com dependências:

Incluindo detalhes de membros de classes

UML possui sintaxe para especificar: Visibilidade Valores iniciais

Page 5 of 6Diagramas de Classe para a Fase de Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj8.htm

Page 94: Apoo Jacques Ufcg

etc. Exemplo:

proj1-8 programa anterior próxima

Page 6 of 6Diagramas de Classe para a Fase de Projeto

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj8.htm

Page 95: Apoo Jacques Ufcg

Esquema de banco de dados e mapeamento OO-Relacional

Referências

Há uma discussão detalhada de como tratar persistência de objetos de várias formas nos livros: Object-Oriented Modeling and Design for Database Applications, Blaha e Premerlani, Prentice Hall, 1998. Database Design for Smarties, Muller, Morgan Kaufmann Publishers, 1999.

Este livro também cobre o mapeamento para SGBDs Objeto-Relacionais Nossa discussão é um breve resumo do material desses dois livros

Um tratamento completo não pode ser dado nesta disciplina devido a restrições de tempo Também tem uma breve discussão de como montar um framework de persistência no livro:

Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design, Larman, Prentice-Hall, 1998.

Frameworks profissionais de persistência podem ser vistos nos produtos TopLink e CocoBase Falaremos especialmente do mapeamento de um modelo OO para um esquema relacional

Não há tempo para tratar do mapeamento para SGBDs Objeto-Relacionais Supõe-se uma certa familiaridade com o modelo relacional

Resumo da seção

Implementação da identidade de objetos Implementação de domains Implementação de classes Implementação de operações Implementação de associações simples Implementação de associações avançadas Implementação de herança simples Implementação de herança múltipla Resumo dos passos para o mapeamento OO-Relacional

Implementação da identidade de objetos

Em SGBDOOs, objetos possuem identidade baseada na existência, mas isso não é automático num SGBDR Com um SGBDR (ou quando usam-se arquivos para a persistência), pode-se usar uma de duas alternativas:

Identidade baseada na existência O SGBDR gera um identificador único (OID) para cada registro

O OID é armazenado numa coluna adicional e é a chave primária da tabela Identidade baseada em valor

Uma combinação de atributos identifica cada registro As duas alternativas podem ser misturadas num mesmo esquema Vantagens da identidade baseada na existência

A chave primária é um atributo único, pequeno e uniforme em tamanho Algumas tabelas não possuem uma combinação de atributos que possa ser chave primária

Page 1 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 96: Apoo Jacques Ufcg

Desvantagens da identidade baseada na existência Alguns SGBDs poderão não oferecer a geração de identificadores únicos A geração de identificadores únicos pode necessitar de acesso a dados globais, interferindo assim com o

controle de concorrência e deixando a aplicação potencialmente mais lenta Pode complicar a depuração das aplicações

Já que os OIDs não possuem semântica em nível de aplicação Vantagens da identidade baseada em valor

As chaves primárias possuem semântica clara em nível de aplicação, facilitando a depuração e manutenção do BD

A distribuição do BD pode ser mais fácil Porque não há geração centralizada de identidade Mas manter a unicidade das chaves pode não ser simples

Desvantagens da identidade baseada em valor Chaves primárias podem ser mais difíceis de alterar

Devido à propagação causada por chaves estrangeiras usadas em associações e herança A propagação poderá não ser suportada automaticamente pelo SGBD

Recomendações Usar identidade baseada na existência para esquemas maiores (com mais de 30 classes)

Não precisa incluir o OID como atributo no modelo UML Caso contrário, para aplicações pequenas, considere utilizar a identidade baseada em valor, ou uma

combinação das duas técnicas No modelo UML, acrescente o tag {OID} para os atributos que participam da chave primária

Há quem recomende usar identidade baseada na existência sempre

Implementação de domains

Precisamos agora pensar sobre o tipo de dados que armazenaremos no BD Que tipos serão usados nas declarações de colunas? Domains são usados para lidar com a questão

Um domain é um subconjunto nomeado dos valores possíveis para um atributo Domains:

Promovem um projeto mais consistente do que com o uso direto dos vários tipos de dados Facilitam as mudanças Ajudam a validar consultas

O padrão ANSI SQL-92 suporta o conceito de domain. Exemplo:

CREATE DOMAIN Boolean AS CHAR(1) NOT NULL DEFAULT 'T' CONSTRAINT Bool_Constraint CHECK (Boolean IN ('T', 'F'));

Pode-se assim criar domains para os tipos de dados que serão armazenados no BD Infelizmente, a maioria dos SGBDs não dá suporte a domains!

Portanto, domains são geralmente implementados: Usando cláusulas CHECK do SQL na definição dos atributos Ou usando código de aplicação

Infelizmente, esse código de verificação de domains deve ser inserido sempre que se define um atributo, já que não há suporte a domains ANSI

Para domains simples tais como nomes, Strings e valores financeiros: Use o tipo de dado apropriado e especifique um tamanho

Use tipos ANSI (CHARACTER, CHARACTER VARYING, ...) Ou use tipos do SGBD (Oracle: VARCHAR2, NUMBER, ...)

Para domains de enumeração, há 4 soluções String de enumeração: armazene o atributo de enumeração como string

Use CHECK ou código de aplicação para verificar valores Solução simples mas não pode ser estendida a muitos valores Exemplo:

CREATE TABLE Pessoa ( EstadoCivil CHARACTER(1) NULL CHECK (EstadoCivil IN ('S', 'C', 'D', 'V')) ...

Page 2 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 97: Apoo Jacques Ufcg

)

Codificação da enumeração: como acima, mas usando inteiros em vez de strings Uma tabela pode fornecer o mapeamento entre inteiros e strings correspondentes Vantagens:

Mais fácil lidar com múltiplas línguas Usam menos espaço em disco

Desvantagem (séria) Complica a depuração e manutenção (devido ao uso de "números mágicos" sem semântica

própria) Um flag por valor de enumeração: use um atributo booleano para cada valor de enumeração

Funciona bem apenas quando múltiplos valores podem ser aplicáveis (atributos não mutuamente exclusivos)

Exemplo:

CREATE TABLE xxx ( Vermelho CHARACTER(1) NULL Azul CHARACTER(1) NULL Amarelo CHARACTER(1) NULL ... )

Uma tabela de enumeração: os valores possíveis para a enumeração são armazenados numa tabela à parte

Pode haver uma tabela por enumeração ou uma tabela para todas as enumerações O código de aplicação verifica que o valor do atributo pertence à tabela Boa solução quando há muitos valores Vantagem de ter os valores possíveis no próprio BD em vez de tê-los no código Novos valores podem ser inseridos facilmente, sem modificar o código Mas tabelas adicionais complicam o esquema e o código genérico de manipulação

Para pequenas enumerações, é mais fácil usar strings e um constraint em SQL Use quando há muitos valores ou valores desconhecidos durante o desenvolvimento Exemplo:

CREATE TABLE TipoEstadoCivil ( Valor CHAR(1) PRIMARY KEY, DisplayString VARCHAR2(50) NOT NULL, Descricao VARCHAR2(2000)); INSERT INTO TipoEstadoCivil (Valor, DisplayString) VALUES ('S', 'Solteiro'); INSERT INTO TipoEstadoCivil (Valor, DisplayString) VALUES ('C', 'Casado'); INSERT INTO TipoEstadoCivil (Valor, DisplayString) VALUES ('D', 'Divorciado'); INSERT INTO TipoEstadoCivil (Valor, DisplayString) VALUES ('V', 'Viuvo'); ) CREATE TABLE Pessoa ( EstadoCivil CHARACTER(1) NOT NULL DEFAULT 'U' REFERENCES TipoEstadoCivil(Valor), ... )

Para domains estruturados, há três alternativas, todas válidas em certas situações Concatenação: jogue fora a estrutura e armazene o atributo como string

Exemplo Uma Pessoa tem um Endereço O Endereço é um domain estruturado (possui vários atributos)

Page 3 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 98: Apoo Jacques Ufcg

Armazene o endereço inteiro como string Múltiplas colunas

O Endereço seria armazenado na tabela Pessoa em colunas diferentes Tabela separada

Pessoa referencia um registro da tabela Endereço Para domains multivalorados, use as técnicas de domains estruturados

Não há suporte especial do modelo relacional, porque domains multivalorados não obedecem a primeira forma normal

Implementação de classes

No modelo de projeto, algumas classes são persistentes e outras não As classes persistentes têm o estereótipo UML «persistent»

Tratamos aqui apenas das classes persistentes As demais definem um comportamento transiente que deve ser tratado no código da aplicação

Uma classe contém atributos e operações Discutiremos o que fazer com as operações na próxima subseção

De forma geral, cada classe persistente se transforma numa tabela e cada atributo se transforma numa coluna da tabela

Para cada tabela, trata-se a questão de identidade vista acima Para cada atributo, trata-se a questão de domains vista acima O modelo relacional não trata a visibilidade dos atributos

Todos os atributos são públicos Para atributos que têm tag UML {OID}, use um constraint PRIMARY KEY Para atributos que têm tag UML {alternate OID} (alternate key), use um constraint UNIQUE Para atributos que têm tag UML {nullable}, não use o constraint NOT NULL, caso contrário, use NOT NULL

Alguns SGBDs permitem que você use o constraint NULL que não faz parte do padrão ANSI na definição de colunas

Implementação de operações

Um SGBD Relacional não permite encapsular operações (métodos) com classes Por outro lado, stored procedures são possíveis, o que permite colocar alguma funcionalidade dos métodos

dos objetos da aplicação no SGBD Alguns SGBDs oferecem também stored functions que retornam valor

A questão básica é: "Que tipo de funcionalidade pode ser adequadamente colocada em stored procedures?" No final das contas, podemos particionar o código entre o servidor de BD e as outras camadas (middle

tier, cliente) O que é melhor colocar no SGBD e o que é melhor deixar fora?

Algumas regras sobre o que evitar seguem: Não se pode colocar operações que lidam com aspectos transientes no SGBD

O código de stored procedures não pode acessar os objetos que estão em memória nas outras camadas

Não se deve usar stored procedures para acessar dados atributo por atributo Um SGBDR acessa dados naturalmente por registro, não por atributo individual O acesso ao BD atributo por atributo resultaria numa aplicação muito lenta

Evite stored procedures que tenham que deixar "estado transiente" armazenado no BD para fazer outras operações subsequentes (não armazenar estado comportamental usado entre chamadas)

Embora alguns SGBDs (Oracle, por exemplo) permitam que isso seja feito, é melhor que cada chamada a um stored procedure seja reentrante e não dependa de estado

O sistema resultante é muito mais simples e fácil de manter e depurar Tal tipo de estado deve ser mantido na camada do meio (aplicação)

Evite fazer grandes quantidades de verificação de erro, com condições de aborto, etc. no SGBD. Mantenha isso em outra camada (aplicação ou cliente)

Algumas operações de alto desempenho poderão ser mais rápidas quando executadas numa linguagem compilada (em outra camada), em vez de uma linguagem interpretada para executar stored procedures (como PL/SQL do Oracle, Transact/SQL do SQLServer)

Evite fazer ações transacionais (COMMIT, ROLLBACK) em stored procedures Faça isso em outra camada A semântica de transação é expressa melhor na aplicação em si

Seria ruim um programador chamar um stored procedure e, depois, ao verificar um erro e tentar

Page 4 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 99: Apoo Jacques Ufcg

fazer um ROLLBACK, descobrir que a transação já sofreu COMMIT O que pode ser colocado no SGBD como stored procedures?

Fazer uma consulta dando um result set (um conjunto de registros) Insert/update/delete, mas apenas de registros inteiros, não atributo por atributo Verificação de regras de consistência e outros business rules

Talvez este seja o motivo principal do uso de Stored Procedures Triggers podem ser valiosos aqui também

Operações que chamam outros stored procedures (para acessar o dicionário, por exemplo) Verificação de erros (mas apenas erros relacionados com a estrutura do BD)

Como tratar polimorfismo? Ao usar um SGBDR, não há suporte a polimorfismo

Mesmo SGBDORs têm suporte fraco ou inexistente a polimorfismo Evite-o portanto, nas classes persistentes

Pode usar em classes transientes Se o polimorfismo for usado na modelagem de classes persistentes, ele tem que ser transformado em if-

then-else e chamadas as stored procedures diferentes Todas essas restrições explicam porque se fala do impedance mismatch!

Implementação de associações simples

Associações simples são: 1-para-1 0..1-para-1 1-para-muitos muitos-para-muitos

Descrevemos mapeamentos recomendados, alternativos e desencorajados para cada tipo Sempre considere primeiro o mapeamento recomendado Mapeamentos alternativos podem ser usados por uma questão de desempenho, extensibilidade, ou

estilo

Associações 1-para-1 Recomendado

Embutir a chave estrangeira em qualquer uma das classes A chave estrangeira poderá ser nula se houver uma cardinalidade mínima de 0 no alvo

Alternativo A associação pode ser implementada numa tabela à parte A chave primária da tabela de associação pode ser qualquer uma das duas chaves estrangeiras Vantagem: o esquema é mais extensível

Se houver mudança na cardinalidade da associação, basta mudar o constraint, não a estrutura de tabelas

Desvantagens: fragmentação do esquema e maior overhead de navegação (com joins) Desencorajado

Combinação: não junte duas classes e sua associação numa única tabela O esquema é mais fácil de entender se seguir o modelo de objetos

Associações bi-direcionais: não coloque duas chaves estrangeiras, uma em cada tabela referenciando a outra

Os SGBDs não vão manter a consistência das associações redundantes

Associações 0..1-para-1 Recomendado

Embutir a chave estrangeira na classe com a cardinalidade 0..1 A chave estrangeira é NOT NULL

Associações 1-para-muitos Recomendado

Embutir a chave estrangeira na classe com cardinalidade "muitos" Se a cardinalidade 1 (do alvo) puder ser 0-1, a chave estrangeira pode se nula Exemplo:

Page 5 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 100: Apoo Jacques Ufcg

Alternativo A associação pode ser implementada numa tabela à parte A chave estrangeira para a classe "muitos" é a chave primária da tabela de associação Mesmas vantagens e desvantagens do mapeamento 1-para-1 Exemplo:

Associações muitos-para-muitos Recomendado

A associação é mapeada para uma tabela distinta A chave primária da tabela de associação é uma combinação das chaves estrangeiras Exemplo:

Implementação de associações avançadas

Associações avançadas são: Associação qualificada Classe de associação Associação ordenada Associação ternária

Associação qualificada Lembre que uma associação qualificada é uma associação "para-muitos" onde os objetos envolvidos do lado

"muitos" são total ou parcialmente especificados usando um atributo chamado o qualificador Tais associações aumentam a precisão do modelo Um qualificador seleciona um ou mais dentre vários objetos-alvo, com o efeito de reduzir a cardinalidade,

às vezes até 1 Quando a cardinalidade final é 1, a associação qualificada especifica uma forma precisa de selecionar o

objeto alvo a partir do objeto fonte Exemplo:

Uma descrição de vôo se aplica a muitos vôos A combinação de uma descrição de vôo mais uma data de partida especifica um vôo

Page 6 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 101: Apoo Jacques Ufcg

Recomendado O mapeamento é tal qual para a associação sem qualificador No exemplo acima, uma chave estrangeira seria incluída na classe Vôo

Classe de associação É uma associação com uma classe que a descreve A classe de associação pode participar de outras associações Recomendado

Implemente a associação com uma tabela distinta A chave primária da classe de associação é uma combinação das chaves primárias das classes

envolvidas na associação Exemplo:

Associação ordenada Ocorre quando as ligações entre objetos possuem uma ordem Exemplo: janelas podem estar ordenadas numa tela (indicando qual está na frente das outras) O tag UML {ordered} é usado na associação ( ou {ordered by ...}) Recomendado

Introduzir um número de sequência como atributo

Associação ternária Exemplo:

Page 7 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 102: Apoo Jacques Ufcg

Recomendado Uma tabela distinta deve ser usada para representar a associação ternária

Agregações Recomendado

Agregações são associações e são implementadas como tal

Implementação de herança simples (generalização)

Recomendado Normalmente, a herança é implementada com tabelas separadas para a superclasse e cada subclasse Idealmente, um objeto tem a mesma chave primária na hierarquia inteira A superclasse inclui um discriminador que indica qual subclasse se aplica

Isso não é mostrado no modelo de objetos A integridade referencial pode ser usada para garantir que um registro da superclasse exista para cada

registro de uma subclasse Entretanto, se a superclasse for abstrata e exigir que haja um objeto de uma subclasse, a

integridade referencial não pode solucionar o problema O código da aplicação deve implementar a restrição

Exemplo:

Pode-se usar uma View para cada subclasse, no sentido de consolidar os dados herdados e facilitar o acesso ao objeto

Exemplo:

Page 8 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 103: Apoo Jacques Ufcg

CREATE VIEW view_PagamentoCC AS SELECT pagamentoID, valor, tipoCC, numeroCC FROM Pagamento AS P JOIN PagamentoCC as CC ON P.pagamentoID = CC.pagamentoCCID

Alternativo Eliminação

Como otimização, subclasses que não contêm atributos, fora a chave estrangeira, podem ser eliminadas

Desvantagens O código de navegação tem que saber se há uma tabela ou não para implementar a subclasse Falta de extensibilidade: se houver uma adição à subclasse, a tabela vai ter que voltar

Exemplo:

Empurrar atributos da superclasse para baixo Elimine a superclasse e duplique seus atributos para cada subclasse Uma única tabela contém todos os dados de um objeto (não há necessidade de join para reconstituir

um objeto) Desvantagens

Introduz redundância no esquema Poderá ser necessário pesquisar várias tabelas para achar um objeto Se vários níveis de hierarquia estiverem envolvidos, a estrutura da generalização (herança) é

perdida Exemplo:

Page 9 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 104: Apoo Jacques Ufcg

Empurrar atributos da subclasse para cima

Neste caso, as subclasses são eliminadas e todos seus atributos migram para a tabela da superclasse

Atributo desnecessários para certos objetos são nulos Essa alternativa viola a segunda forma normal porque alguns atributos não dependem

completamente da chave primária Exemplo:

Abordagem híbrida Empurrar os atributos da superclasse para baixo mas manter a tabela da superclasse para navegar

nas subclasses Exemplo:

Page 10 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 105: Apoo Jacques Ufcg

Tabela de generalização Semelhante ao mapeamento recomendado (tabelas para superclasse e subclasses) mas adicionando

uma tabela de generalização que amarra a chave primária da superclasse à chave primária da subclasse

A chave primária das subclasses é a chave "natural" da tabela e não mais a mesma da superclasse como no mapeamento recomendo inicial

Implementação de herança múltipla

Recomendado Usar o mapeamento recomendado acima (tabelas distintas para superclasse e subclasses)

Resumo dos passos para o mapeamento OO-Relacional

1. Cada classe UML é mapeada para uma tabela

2. Cada atributo da clase é uma coluna da tabela

3. O tipo do atributo é mapeado para um tipo da coluna, de acordo com regras de transformação de tipos

4. Se o atributo tem o tag UML {nullable}, a coluna tem constraint NULL; caso contrário, tem constraint NOT NULL

5. Se o atributo UML tem um inicializador, adicionar a cláusula DEFAULT à coluna

6. Para cada classe sem generalização (é raiz de hierarquia ou não participa de hierarquia) e com identidade baseada na existência, criar uma chave primária inteira; com identidade baseada em valor, adicionar as colunas com tag UML {OID} ao constraint PRIMARY KEY

7. Para subclasses com uma única superclasse com chave primária de uma coluna, adicionar a chave da superclasse ao constraint PRIMARY KEY e adicionar uma cláusula REFERENCES para relacionar a coluna (chave estrangeira) à chave primária da superclasse

8. Para subclasses com uma única superclasse com chave primária de várias colunas, use constraints de tabela PRIMARY KEY e FOREIGN KEY em vez do constraint de coluna do item anterior

9. Para herança múltipla, adicione uma coluna na subclasse para cada chave primária de cada superclasse; adicione um constraint de tabela FOREIGN KEY com todas essas colunas (que referenciam chaves primárias das superclasses)

0. Para classes de associação, adicione uma coluna para a chave primária de cada classe participando da

Page 11 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 106: Apoo Jacques Ufcg

associação; use um constraint FOREIGN KEY

1. Para tags UML {alternate OID}, adicione as colunas envolvidas ao constraint UNIQUE

2. Adicione CHECK para cada constraint explícito

3. Crie tabelas para as associações que não usam chaves estrangeiras embutidas (muitos-para-muitos, ternárias, ...), e use constraint de tabela FOREIGN KEY

4. Para agregações, use a opção ON DELETE CASCADE, ON UPDATE CASCADE na tabela agregadora

proj1-9 programa anterior

Page 12 of 12Esquema de banco de dados e mapeamento OO-Relacional

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj1\proj9.htm

Page 107: Apoo Jacques Ufcg

5. Fase de Implementação Mapeamento do projeto para código Programa exemplo em Java Testes de unidade Adicionando uma interface com o usuário

impl programa

Page 1 of 15. Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\index.htm

Page 108: Apoo Jacques Ufcg

Mapeamento do Projeto para Código

Com os artefatos já produzidos, estamos prontos para implementar (codificar e testar) A codificação é feita a partir dos artefatos de projeto

Diagramas de colaboração e diagrama de classes Deve-se codificar depois de um esforço suficiente de análise e projeto

Porque explorar alternativas é mais barato em fases anteriores No entanto, alguma atividade de prototipagem pode ser feita em fases anteriores Em termos de maturidade de processo de desenvolvimento, codificar cedo demais não

leva a um processo que possa ser repetido Os riscos são muito maiores

A atividade de codificação em si é uma tradução bastante mecânica dos modelos produzidos

A criatividade não ocorre durante a codificação mas antes dela Porém, a codificação frequentemente leva a modificações em decisões anteriores

Portanto, depois da codificação, os artefatos já produzidos devem ser sincronizados com o código

Uma ferramenta CASE que faz Engenharia Reversa pode ajudar aqui Ela lê o código e produz diagramas de modelos

Mapeamento do projeto para código

Deve-se escrever: Código para interfaces e classes Código para os métodos

Criação de definições de interfaces e classes Feita a partir de diagramas de classes Os passos são simples, lembrando que tipos suportados pela linguagem devem ser

escolhidos A navegabilidade indica que atributos referenciando outros objetos devem ser incluídos

na classe É desejável chamar o atributo pelo papel assumido pelo destino da associação

Page 1 of 2Mapeamento do Projeto para Código

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl1.htm

Page 109: Apoo Jacques Ufcg

Criação de métodos Feita a partir dos diagramas de colaboração, examinando as mensagens enviadas entre

os objetos

Atualização das definições de classes Após a codificação (e testes), as definições de classes são alteradas para incluir novos

métodos introduzidos, etc.

Tratamento de erros Embora tenhamos nos concentrado na atribuição de responsabilidades, a atividade de

projeto deve também considerar como será feito o tratamento de erros Normalmente usa o mecanismo de exceções Uma parte significativa do código diz respeito ao tratamento de erros

Ordem de implementação Classes individuais devem ser codificadas e sujeitas a testes de unidade na ordem da

menos acoplada à mais acoplada Para minimizar scaffolding

Uma ordem sugerida no estudo de caso seria como mostrado abaixo

impl-1 programa próxima

Page 2 of 2Mapeamento do Projeto para Código

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl1.htm

Page 110: Apoo Jacques Ufcg

Programa Exemplo em Java

O código abaixo não inclui sincronização devido a acessos concorrentes, nem tratamento de persistência O código abaixo é diferente do código do livro

Usa interfaces para desacoplar classes Apenas as interfaces externas foram definidas de forma a produzir a documentação externa de quem usa as classes (ver

documentação externa) Outras interfaces (internas) poderiam ser definidas para ter mais polimorfismo dentro do pacote

Inclui comentários javadoc para produzir documentação automaticamente Alguns modificadores de acesso (public, ...) foram alterados Usa Factory Methods (ver Design Patterns, em outro capítulo) Alguns métodos faltam no livro

Exemplo: Loja tem que ter um getCatálogoDeProdutos(), senão a camada de interface com o usuário não consegue obter a descrição de um produto com dado UPC para exibir ao cliente

Está em português Acentuação é usada em atributos e métodos mas não em nomes de classes e interfaces porque, neste último caso, o nome do

arquivo é igual à classe/interface e quero evitar acentuação em nomes de arquivos (portabilidade) Tem tratamento de erro completo com 3 tipos de exceções

Falta tratar mais um ou dois erros possíveis que estou deixando para o aluno descobrir (e tratar!) O resultado é um código mais profissional

Porém, as coisas sempre podem ser melhoradas Por exemplo: o uso de float para representar valores monetários não foi uma boa decisão do autor Larman

Por quê? Como você faria?

Documentação

A documentação externa está aqui Observe que nesta documentação, há apenas a informação que pode ser usada "de fora", isto é, pelas classes da interface do usuário O único objeto que pode ser criado é uma Loja A partir da Loja, pode-se obter um TPDV, ou um catálogo de produtos para fazer as outras operações associada à interface com o

usuário A documentação interna está aqui

Útil para os desenvolvedores do pacote

Interface IPagamento

package tpdv; /** * Interface para qualquer tipo de pagamento. * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ interface IPagamento { /** * Retorna o valor entregue pelo cliente para pagar a venda. * @return O valor entregue pelo cliente para pagar a venda. */ float getValor(); }

Classe Pagamento

package tpdv; /** * Classe que representa um pagamento feito para uma venda.

Page 1 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 111: Apoo Jacques Ufcg

* * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ class Pagamento implements IPagamento { /** * O valor do pagamento de uma venda. */ private float valor; /** * Cria um pagamento. * @param valorEntregue O valor entregue para pagar a venda. */ public Pagamento(float valorEntregue) { this.valor = valorEntregue; } /** * Cria um pagamento. * @param valorEntregue O valor entregue para pagar a venda. */ public Pagamento(double valorEntregue) { this.valor = (float)valorEntregue; } /** * Retorna o valor entregue para pagar a venda. * @return O valor entregue para pagar a venda. */ public float getValor() { return valor; } }

Interface IEspecProduto

package tpdv; /** * Interface para qualquer tipo de especificação de produto. * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public interface IEspecProduto { /** * Obtem o Universal Product Code (UPC) do produto. * @return O Universal Product Code (UPC) do produto. */ int getUPC(); /** * Obtem o preço do produto. * @return O preço do produto. */ float getPreço(); /** * Obtem a descrição do produto. * @return A descrição do produto. */ String getDescrição(); }

Classe EspecificacaoDeProduto

package tpdv; /** * Classe que representa uma especificação de um produto do catálogo de produtos. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ class EspecificacaoDeProduto implements IEspecProduto { /** * O Universal Product Code (UPC) do produto.

Page 2 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 112: Apoo Jacques Ufcg

*/ private int upc; /** * O preço do produto. */ private float preço; /** * A descrição do produto. */ private String descrição; /** * Cria uma especificação de produto. * @param upc O Universal Product Code do produto. * @param preço O preço do produto. * @param descrição A descrição do produto. */ public EspecificacaoDeProduto(int upc, float preço, String descrição) { this.upc = upc; this.preço = preço; this.descrição = descrição; } /** * Cria uma especificação de produto. * @param upc O Universal Product Code do produto. * @param preço O preço do produto. * @param descrição A descrição do produto. */ public EspecificacaoDeProduto(int upc, double preço, String descrição) { this(upc, (float)preço, descrição); } /** * Obtem o Universal Product Code do produto. * @return O Universal Product Code do produto. */ public int getUPC() { return upc; } /** * Obtem o preço do produto. * @return O preço do produto. */ public float getPreço() { return preço; } /** * Obtem a descrição do produto. * @return A descrição do produto. */ public String getDescrição() { return descrição; } }

Interface ICatalogoDeProdutos

package tpdv; /** * Interface para qualquer tipo de Catálogo de Produtos * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public interface ICatalogoDeProdutos { /** * Obtem a especificação de produto, dado o Universal Product Code (UPC) * @param upc O Universal Product Code (UPC) do produto desejado * @return A especificação de produto, dado o Universal Product Code (UPC) */ public IEspecProduto getEspecificação(int upc) throws ProdutoInexistenteException; }

Classe CatalogoDeProdutos

package tpdv; import java.util.*;

Page 3 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 113: Apoo Jacques Ufcg

/** * Classe que representa um catálogo de produtos. * Um catálogo contém várias especificações de produtos. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ class CatalogoDeProdutos implements ICatalogoDeProdutos { /** * O catálogo de produtos é guardado aqui. */ private Map especsProdutos = new HashMap(); /** * Cria um catálogo de produtos. Esta versão não trata de persistência. * O catálogo é fixo e criado no construtor. */ public CatalogoDeProdutos() { int upc1 = 100; especsProdutos.put(new Integer(upc1), makeEspecProduto(upc1, (float)1.99, "produto 1")); int upc2 = 200; especsProdutos.put(new Integer(upc2), makeEspecProduto(upc2, (float)3.49, "produto 2")); } /** * Obtém a especificação de um produto. * @param upc o Universal Product Code do produto cuja especificação se deseja. * @return A especificação do produto desejado. */ public IEspecProduto getEspecificação(int upc) throws ProdutoInexistenteException { IEspecProduto espec = (IEspecProduto)especsProdutos.get(new Integer(upc)); if(espec == null) { throw new ProdutoInexistenteException("Produto inexistente, UPC: " + upc); } return espec; } // factory method protected IEspecProduto makeEspecProduto(int upc, float preço, String descrição) { return new EspecificacaoDeProduto(upc, preço, descrição); } }

Classe ProdutoInexistenteException

package tpdv; /** * Exceção indicando produto inexistente no catálogo de produtos. * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public class ProdutoInexistenteException extends TPDVException { /** * Cria uma exceção de produto inexistente * @param mensagem Mensagem de erro imprimível */ public ProdutoInexistenteException(String mensagem) { super(mensagem); } }

Interface ILinhaDetalhe

package tpdv; /** * Interface para qualquer tipo de linha de detalhe de uma venda. * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */

Page 4 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 114: Apoo Jacques Ufcg

interface ILinhaDetalhe { /** * Retorna o subtotal da venda para os itens correspondendo a esta linha de detalhe. * @return O subtotal da venda para os itens correspondendo a esta linha de detalhe. */ float subTotal(); }

Classe LinhaDetalheVenda

package tpdv; /** * Classe que representa uma linha de detalhe de uma venda. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ class LinhaDetalheVenda implements ILinhaDetalhe { /** * A quantidade de itens (do mesmo produto) neste detalhe de venda. */ private int quantidade; /** * A especificação do produto sendo comprado. */ private IEspecProduto espec; /** * Cria uma linha de detalhe de uma venda. * @param espec A especificação do produto sendo comprado. * @param quantidade A quantidade de itens (do mesmo produto) sendo comprados */ public LinhaDetalheVenda(IEspecProduto espec, int quantidade) { this.espec = espec; this.quantidade = quantidade; } /** * Informa o subtotal da venda correspondendo a esta linha de detalhe. * @return O subtotal da venda correspondendo a esta linha de detalhe. */ public float subTotal() { return quantidade * espec.getPreço(); } }

Interface IVenda

package tpdv; /** * Interface externa para qualquer tipo de venda. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public interface IVenda { /** * Retorna o troco da venda, após fazer um pagamento de uma venda. * @return o troco da venda, após fazer um pagamento de uma venda. */ float getTroco(); /** * Retorna o valor total da venda, até agora. * @return o valor total da venda, até agora. */ float total(); }

Classe Venda

package tpdv;

Page 5 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 115: Apoo Jacques Ufcg

import java.util.*; /** * Classe que representa uma venda de produtos feita através de um TPDV. * Uma venda é composta de várias linhas de detalhe. * Enquanto a venda não terminou, tais linhas de detalhe podem ser criadas. * Um pagamento pode ser feita para pagar a venda. * Pode-se calcular o troco a ser entregue ao cliente. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ class Venda implements IVenda { /** * As linhas de detalhe da venda. */ private List linhasDetalhe = new Vector(); /** * A data da venda. */ private Date data = new Date(); // hoje /** * Indica se a venda terminou. */ private boolean isTerminada = false; /** * O pagamento efetuado para a venda. */ private IPagamento pagamento; /** * Calcula o valor total da venda. * @return O valor total da venda. */ public float total() { float total = (float)0.0; Iterator it = linhasDetalhe.iterator(); while(it.hasNext()) { total += ((ILinhaDetalhe)it.next()).subTotal(); } return total; } /** * Calcule o troco para a venda, após um pagamento. * @return O troco para a venda. */ public float getTroco() { return pagamento.getValor() - total(); } /** * Chamado para indicar que a venda terminou. */ void terminou() { isTerminada = true; } /** * Obtém o status da venda. * @return true se a venda terminou; false caso contrário. */ boolean isTerminada() { return isTerminada; } /** * Cria uma linha de detalhe para a venda. * @param espec A especificação do produto sendo comprado. * @param quantidade A quantidade de itens (do mesmo produto) sendo comprados. */ void criaLinhaDetalhe(IEspecProduto espec, int quantidade) { linhasDetalhe.add(makeLinhaDetalhe(espec, quantidade)); } /**

Page 6 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 116: Apoo Jacques Ufcg

* Faz um pagamento para a venda. * @param valorEntregue O valor entregue pelo cliente para pagar a venda. */ void façaPagamento(float valorEntregue) throws PagamentoInsuficienteException { if(valorEntregue < total()) { throw new PagamentoInsuficienteException("Pagamento insuficiente"); } pagamento = makePagamento(valorEntregue); } // factory methods protected ILinhaDetalhe makeLinhaDetalhe(IEspecProduto espec, int quantidade) { return new LinhaDetalheVenda(espec, quantidade); } protected IPagamento makePagamento(float valorEntregue) { return new Pagamento(valorEntregue); } }

Classe NaoHaVendaException

package tpdv; /** * Exceção indicando operação necessitando de venda sem venda ativa * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public class NaoHaVendaException extends TPDVException { /** * Cria uma exceção de operação necessitando de venda sem venda ativa * @param mensagem Mensagem de erro imprimível */ public NaoHaVendaException(String mensagem) { super(mensagem); } }

Classe PagamentoInsuficienteException

package tpdv; /** * Exceção indicando pagamento insuficiente para uma venda. * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public class PagamentoInsuficienteException extends TPDVException { /** * Cria uma exceção de pagamento insuficiente * @param mensagem Mensagem de erro imprimível */ public PagamentoInsuficienteException(String mensagem) { super(mensagem); } }

Interface ITPDV

package tpdv; /** * Interface para qualquer tipo de Terminal Ponto De Venda (TPDV). * Um TPDV é usado para fazer uma venda (uma única venda de cada vez). * Itens podem ser comprados até o final da venda. * Um pagamento pode ser feito para a venda corrente. * * @author Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public interface ITPDV { /**

Page 7 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 117: Apoo Jacques Ufcg

* Obtém a venda corrente sendo realizada pelo TPDV. * @return A venda corrente sendo realizada pelo TPDV. */ IVenda getVenda(); /** * Chamado para indicar que a venda terminou. */ void fimDeVenda() throws NaoHaVendaException; /** * Chamado para adicionar à venda corrente um número de itens sendo comprados. * @param upc O Universal Product Code do item sendo comprado. * @param quantidade O número de itens sendo comprados. */ void entraItem(int upc, int quantidade) throws ProdutoInexistenteException; /** * Realiza um pagamento para uma venda. * @param valorEntregue O valor entregue pelo cliente para pagar a venda. */ void façaPagamento(float valorEntregue) throws PagamentoInsuficienteException; }

Classe TPDV

package tpdv; /** * Classe que implementa um Terminal Ponto De Venda (TPDV). * Um TPDV é usado para fazer uma venda (uma única venda de cada vez). * Itens podem ser comprados até o final da venda. * Um pagamento pode ser feito para a venda corrente. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ class TPDV implements ITPDV { /** * O catálogo de produtos que podem ser vendidos neste TPDV. */ private ICatalogoDeProdutos catálogo; /** * A venda corrente sendo realizada no TPDV. */ private IVenda venda; /** * Cria um TPDV. * @param catálogo Um catálogo de produtos que podem ser adquiridos neste TPDV. */ public TPDV(ICatalogoDeProdutos catálogo) { this.catálogo = catálogo; venda = null; } /** * Obtém a venda corrente sendo realizada no TPDV. * @return A venda corrente sendo realizada no TPDV. */ public IVenda getVenda() { return venda; } /** * Quando chamado, indica que a venda corrente sendo realizada no TPDV terminou. */ public void fimDeVenda() throws NaoHaVendaException { if(venda == null) { throw new NaoHaVendaException("Nao ha venda iniciada"); } venda.terminou(); } /** * Informa um produto e a quantidade de itens deste produto sendo comprados na venda corrente.

Page 8 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 118: Apoo Jacques Ufcg

* Caso a venda anterior já tenha terminado, uma nova Venda é criada. * @param upc O Universal Product Code (UPC) do produto sendo comprado. * @param quantidade A quantidade de itens sendo comprados. */ public void entraItem(int upc, int quantidade) throws ProdutoInexistenteException { if(isNovaVenda()) { venda = makeVenda(); } venda.criaLinhaDetalhe(catálogo.getEspecificação(upc), quantidade); } /** * Realiza um pagamento para a venda corrente do TPDV. * @param valorEntregue O valor entregue pelo cliente para pagar a venda. */ public void façaPagamento(float valorEntregue) throws PagamentoInsuficienteException { venda.façaPagamento(valorEntregue); } // visibilidade de package para poder testar boolean isNovaVenda() { return venda == null || venda.isTerminada(); } // factory method protected IVenda makeVenda() { return new Venda(); } }

Classe Loja

package tpdv; /** * Classe que implementa uma Loja. Cada loja tem um catálogo de produtos e um único TPDV. * * @author Craig Larman, Jacques Philippe Sauvé, [email protected] * @version 1.0 */ public class Loja { /** * O catálogo de produtos da loja. */ private ICatalogoDeProdutos catálogo; /** * O terminal ponto de venda (TPDV) da loja. * Uma loja só tem um único TPDV. */ private ITPDV tpdv; /** * Cria uma loja. O catálogo de produtos e o TPDV são automaticamente criados. * @param valorEntregue O valor entregue para pagar a venda. */ public Loja() { catálogo = makeCatálogo(); tpdv = makeTPDV(catálogo); } /** * Obtem o TPDV da loja. * @return O TPDV da loja. */ public ITPDV getTPDV() { return tpdv; } /** * Obtem o TPDV da loja. * @return O TPDV da loja. */ public ICatalogoDeProdutos getCatálogoDeProdutos() { return catálogo; } // factory methods protected ICatalogoDeProdutos makeCatálogo() { return new CatalogoDeProdutos(); } protected ITPDV makeTPDV(ICatalogoDeProdutos catálogo) {

Page 9 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 119: Apoo Jacques Ufcg

return new TPDV(catálogo); } }

impl-2 programa anterior próxima

Page 10 of 10Fase de Implementação

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl2.htm

Page 120: Apoo Jacques Ufcg

Testes de Unidade

Justificativa

Reduzir defeitos (bugs) apresentados pelo produto Cobrir uma gama maior de equipamentos e ambientes operacionais do que aqueles disponíveis na empresa

através de testes em clientes Assegurar a qualidade final do produto para o cliente, incluindo avaliação de embalagem, manuais,

usabilidade, etc.

Estágios de testes

Testes são feitos em vários estágios Fazer testes monolíticos do produto inteiro aumentaria o tempo necessário à depuração total do software É melhor (mais rápido) testar partes menores para depois testar a integração dessas partes Determinados testes devem ser feitos por pessoas fora da equipe de desenvolvimento no sentido de manter a

maior objetividade possível nessas fases de testes e no sentido de envolver também os usuários finais fora da empresa

Automatização de testes

Os testes devem ser automatizados Pelo menos nas fases em que isso é possível

Scripts de testes desenvolvidos ao longo do tempo aumentam o patrimônio da empresa e garantirão uma qualidade cada vez maior

Tipos de testes

Testes de unidade Para testar classes individuais Feito pelo próprio programador da classe Testa toda a interface da classe

Testes funcionais Para testar os Use Cases Feito pelo time de desenvolvimento

Testes de sistema Uso de Total System Environment

Incluindo outros produtos de software, todas as plataformas, todas as configurações, etc. Feito por uma equipe independente de testes

Testes de regressão Antes de por o sistema na rua, mesmo que tenha havido apenas uma recompilação Normalmente um subconjunto dos testes de sistema

Teste alfa Teste de produto (com embalagem manual, etc.) num "cliente" dentro da empresa

Teste beta Como teste alfa mas incluindo clientes fora da empresa

Page 1 of 3Testes de Unidade

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl3.htm

Page 121: Apoo Jacques Ufcg

Testes de Unidade

Necessidade de automação Clica um botão a qualquer momento para testar tudo! Pelo menos um teste por dia (frequentemente vários testes por hora)

Uso de um framework de testes Desenvolvimento e testes em paralelo Absolutamente necessário ter testes de unidade, principalmente se fizer refactoring de código Testar as classes da menos acoplada para a mais acoplada

Na realidade, segue a ordem de desenvolvimento Desenvolvimento e testes de unidade feitos em paralelo!

Exemplo com o framework JUnit (teste da classe Venda) Neste pacote, leia o artigo "Test Infected: Programmers Love Writing Tests" Escrito por Beck (CRC, Extreme Programming) e Gamma (GoF) Todos os testes estão aqui para o código do capítulo anterior

package tpdv; import junit.framework.*; import tpdv.*; /** * Testes da classe Venda. * */ public class TestaVenda extends TestCase { protected IVenda venda1; protected IEspecProduto ep1; protected IEspecProduto ep2; protected IEspecProduto ep3; public TestaVenda(String name) { super(name); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } protected void setUp() { venda1 = new Venda(); ep1 = new EspecificacaoDeProduto(100, 1.99, "prod1"); ep2 = new EspecificacaoDeProduto(200, 2.99, "prod2"); ep3 = new EspecificacaoDeProduto(300, 3.99, "prod3"); } public static Test suite() { return new TestSuite(TestaVenda.class); } public void testConstrutor() { assert("1", !venda1.equals(null)); assertEquals("2", 0.0, venda1.total(), 0.0); assert("3", !venda1.isTerminada()); } public void testManipulacao() { venda1.criaLinhaDetalhe(ep1, 1); assertEquals("1", 1.99, venda1.total(), 0.001); venda1.criaLinhaDetalhe(ep2, 2); assertEquals("2", 1.99+(2*2.99), venda1.total(), 0.001); venda1.criaLinhaDetalhe(ep3, 2); assertEquals("3", 1.99+(2*2.99)+(2*3.99), venda1.total(), 0.001); try { venda1.façaPagamento((float)5.0); fail("facaPagamento(5.0) deveria gerar exception"); } catch(PagamentoInsuficienteException e) {

Page 2 of 3Testes de Unidade

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl3.htm

Page 122: Apoo Jacques Ufcg

} try { venda1.façaPagamento((float)20.0); } catch(PagamentoInsuficienteException e) { fail("facaPagamento(20.0) nao deveria gerar exception"); } assertEquals("4", 20-1.99-(2*2.99)-(2*3.99), venda1.getTroco(), 0.001); assert("3", !venda1.isTerminada()); venda1.terminou(); assert("3", venda1.isTerminada()); } }

Algumas palavras de Beck e Gamma

Sometimes you just won't feel like writing tests, especially at first. Don't. However, pay attention to how much more trouble you get into, how much more time you spend debugging, and how much more stress you feel when you don't have tests. We have been amazed at how much more fun programming is and how much more aggressive we are willing to be and how much less stress we feel when we are supported by tests. The difference is dramatic enough to keep us writing tests even when we don't feel like it.

impl-3 programa anterior próxima

Page 3 of 3Testes de Unidade

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl3.htm

Page 123: Apoo Jacques Ufcg

Adicionando uma Interface com o Usuário

Interface com o usuário

O business logic estando pronto e testado, podemos fazer uma interface com o usuário Pode-se fazer uma interface em 1 camada, 2 camadas, com applets, 3 camadas com servlets ou JSP, 4 camadas com RMI,

etc. Observe que o business logic não muda para qualquer tipo de interface Ao ver o código da interface com o usuário, observe que a lógica é só de apresentação e de verificação de dados de entrada Uma interface Swing em 1 camada pode ser vista aqui

Está no package tpdvui Foi feita com JBuilder 3.0

A interface parece é a seguinte:

A interface não é muito funcional e merece ser repensada

Alguns trechos de código

A classe principal

public class Tpdv { public Tpdv() { TpdvFrame frame = new TpdvFrame(); // ... um monte de coisinhas frame.setVisible(true); } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch(Exception e) { } new Tpdv(); } }

A classe TpdvFrame

Page 1 of 3Adicionando uma Interface com o Usuário

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl4.htm

Page 124: Apoo Jacques Ufcg

public class TpdvFrame extends JFrame { Loja loja = new Loja(); ITPDV tpdv = loja.getTPDV(); // ... }

Atendimento ao clique do botão Entra Item Tem umas 8 linhas de interesse e mais de 20 linhas de verificação e captura de erros Isso é perfeitamente normal!

public class TpdvFrame extends JFrame { // ... void entraItem_actionPerformed(ActionEvent e) { if(upc.getText().equals("")) { JOptionPane.showMessageDialog(this, "UPC deve ser informado"); return; } if(quantidade.getText().equals("")) { JOptionPane.showMessageDialog(this, "Quantidade deve ser informada"); return; } int upcInt = 0; int quant = 0; try { upcInt = Integer.parseInt(upc.getText()); } catch(NumberFormatException ex) { JOptionPane.showMessageDialog(this, "Produto " + upc.getText() + " inexistente"); } try { quant = Integer.parseInt(quantidade.getText()); } catch(NumberFormatException ex) { JOptionPane.showMessageDialog(this, "Quantidade deve ser numérica"); } try { tpdv.entraItem(upcInt, quant); } catch(ProdutoInexistenteException ex) { JOptionPane.showMessageDialog(this, ex.getMessage()); return; } upc.setText(""); quantidade.setText(""); total.setText(""); valorEntregue.setText(""); troco.setText(""); } // ... }

Atendimento ao clique do botão Fim Venda 2 linhas de interesse e 5 linhas de verificação e captura de erros

public class TpdvFrame extends JFrame { // ... void fimVenda_actionPerformed(ActionEvent e) { try { tpdv.fimDeVenda(); } catch(NaoHaVendaException ex) { JOptionPane.showMessageDialog(this, ex.getMessage()); return; } total.setText(String.valueOf(tpdv.getVenda().total())); } }

Atendimento ao clique do botão Faça Pagamento 2 linhas de interesse e 9 linhas de verificação e captura de erros

Page 2 of 3Adicionando uma Interface com o Usuário

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl4.htm

Page 125: Apoo Jacques Ufcg

public class TpdvFrame extends JFrame { // ... void façaPagamento_actionPerformed(ActionEvent e) { if(valorEntregue.getText().equals("")) { JOptionPane.showMessageDialog(this, "Qual é o valor entregue?"); return; } try { tpdv.façaPagamento((float)Double.parseDouble(valorEntregue.getText())); } catch(PagamentoInsuficienteException ex) { JOptionPane.showMessageDialog(this, ex.getMessage()); return; } troco.setText(String.valueOf(tpdv.getVenda().getTroco())); } }

impl-4 programa anterior

Page 3 of 3Adicionando uma Interface com o Usuário

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\impl\impl4.htm

Page 126: Apoo Jacques Ufcg

6. Fase de Análise 2 Escolha de requisitos da segunda iteração Relacionando múltiplos use cases Extensão do modelo conceitual Generalização Organizando o modelo conceitual com packages Refinamento do modelo conceitual Modelo conceitual no estudo de caso Comportamento do sistema: Diagramas de sequência e contratos na Segunda

Iteração Comportamento do sistema: Diagramas de estado

anal2 programa

Page 1 of 16. Fase de Análise 2

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\index.htm

Page 127: Apoo Jacques Ufcg

Escolha de Requisitos da Segunda Iteração

Escolheremos o que fazer na segunda iteração visando apresentar novos conceitos na disciplina

No mundo real, os requisitos da segunda iteração poderiam ser diferentes Manteremos os mesmos Use Cases da primeira iteração, mas o Use Case de Compra de

Itens incluirá pagamentos em dinheiro, com cheque e com cartão de crédito Temos a seguinte funcionalidade adicional

Pagamento pode ser em dinheiro, com cheque e com cartão de crédito Apenas um pagamento é feito e de um tipo único Pagamentos em cheque e com CC devem ser autorizados Um serviço diferente de autorização de crédito é usado para cada cartão de crédito

(Visa, Mastercard, ...) Um único serviço de autorização de cheques é usado para todos os cheques O terminal PDV é responsável pela comunicação com o serviço de autorização de

crédito O leitor de CC apenas lê o número do CC e o disponibiliza para o terminal PDV

A comunicação com um serviço externo é feito com um modem Deve-se discar um número de telefone a cada venda

anal2-1 programa próxima

Page 1 of 1Escolha de Requisitos da Segunda Iteração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal1.htm

Page 128: Apoo Jacques Ufcg

Organizando o Modelo Conceitual com Packages

Introdução

Quando o modelo conceitual fica grande demais, pode ser quebrado em modelos menores

Já falamos de camadas e partições em outro contexto (Projeto arquitetural), mas a situação se aplica também no modelo conceitual

Packages em UML

Para referencia um conceito de um outro package, usa-se a notação NomeDoPackage::NomeDoConceito

Pode-se incluir dependências entre packages

Organizando um modelo conceitual em packages

Regras para juntar elementos num mesmo package: Os elementos partencem à mesma área conceitual

Page 1 of 3Organizando o Modelo Conceitual com Packages

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal5.htm

Page 129: Apoo Jacques Ufcg

Os elementos participam de uma mesma hierarquia de tipos Os elementos participam dos mesmos Use Cases Os elementos Estão fortemente associados

Packages no estudo de caso

Os packages mostrados abaixo são: Conceitos De Domínio Elementos Básicos Vendas Produtos Pagamentos Transações De Autorização

Page 2 of 3Organizando o Modelo Conceitual com Packages

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal5.htm

Page 130: Apoo Jacques Ufcg

anal2-5 programa anterior próxima

Page 3 of 3Organizando o Modelo Conceitual com Packages

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal5.htm

Page 131: Apoo Jacques Ufcg

Relacionando Múltiplos Use Cases

Introdução

UML tem uma notação especial para Use Cases em dois casos: Use Cases grandes podem ser quebrados em vários Use Cases menores mas relacionados A duplicação de certos passos de Use Cases diferentes pode se fatorada em um Use Case separado

Veremos como fazer isso para os Use Cases seguintes do estudo de caso: Pagar com dinheiro Pagar com cartão de crédito (CC) Pagar com cheque

Relacionamentos "Uses" em UML

Se um Use Case inicia outro Use Case (isto é, inclui o comportamento de outro Use Case), o relacionamento entre os dois é do tipo "Uses"

Exemplo: O Use Case Comprar Itens pode iniciar um dos Use Cases seguintes: Pagar com dinheiro Pagar com cartão de crédito (CC) Pagar com cheque

Ver o diagrama UML abaixo

Na descrição do Use Case, a palavra "initiate" (iniciar) é usada para identificar que um Use Case usa outro

O Use Case Comprar Itens

Use case: Comprar itens Atores: Cliente (iniciador), Caixa Descrição: Um cliente chega ao caixa com itens a comprar. O caixa registra os itens comprados e recebe pagamento. No fim, o cliente sai com os itens comprados.

Sequência típica de eventos

Ação do ator Resposta do sistema

1. O Use Case inicia quando um cliente chega a um caixa munido de TPDV com itens a comprar

2. O caixa registra a identificação de cada item

3. Determina o preço do item e adiciona a informação ao total da transação de venda

Page 1 of 3Relacionando Múltiplos Use Cases

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal2.htm

Page 132: Apoo Jacques Ufcg

Sequências Alternativas: Seção 2: Identificador inválido de item informado: Exibit erro. Seção 7: Cliente não pode pagar: Cancelar transação de venda

Use Cases Relacionados: Usa Pagar com dinheiro Usa Pagar com CC Usa Pagar com Cheque

O Use Case Pagar com Dinheiro

Use case: Pagar com Dinheiro Atores: Cliente (iniciador), Caixa Descrição: Um cliente paga uma venda com dinheiro num terminal ponto-de-venda

Sequência típica de eventos

Sequências Alternativas: Seção 2: O Cliente não tem dinheiro suficiente. Pode cancelar a venda ou iniciar um novo método de pagamento Seção 3: A gaveta não tem dinheiro para pagar o troco. Caixa pede dinheiro ao supervisor ou pede ao Cliente para escolher outro método de pagamento

O Use Case Pagar com Cartão de Crédito

Use case: Pagar com Cartão de Crédito Atores: Cliente (iniciador), Caixa, Serviço de Autorização de Crédito, Contas A Receber Descrição: Um cliente paga uma venda com cartão de crédito num terminal ponto-de-venda. O pagamento é validado num serviço externo de autorização de crédito e é lançado num sistema de contas a receber.

Se houver mais itens, o caixa pode informar a quantidade também A descrição e preço do item corrente são exibidos

4. Ao completar a entrada dos itens, o caixa indica este fato ao TPDV 5. Calcula e apresenta o total da venda

6. O caixa informa o total da venda ao cliente

7. O cliente escolhe o método de pagamento: a. Se for dinheiro, iniciar Pagar Com Dinheiro b. Se for CC, iniciar Pagar Com CC a. Se for cheque, iniciar Pagar Com Cheque

8. Faz log da venda completada

9. Gera um recibo impresso

10. O caixa entrega o recibo impresso ao cliente

11. O cliente sai da loja com os itens comprados

Ação do ator Resposta do sistema

1. O Use Case inicia quando um cliente decide pagar uma venda com dinheiro, após descobrir o valor total da venda

2. O cliente entrega o pagamento em dinheiro (o "valor entregue", possivelmente maior que o total da venda

3. O Caixa registra o valor entregue 4. Exibe o troco devido ao Cliente

5. O Caixa deposita o dinheiro recebido e devolve o troco devido

Page 2 of 3Relacionando Múltiplos Use Cases

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal2.htm

Page 133: Apoo Jacques Ufcg

Sequência típica de eventos

Sequências Alternativas: Seção 4: A autorização é negada pelo Serviço de Autorização de Crédito. O Caixa sugere um outro método de pagamento.

O Use Case Pagar com Cheque

Use case: Pagar com Cheque Atores: Cliente (iniciador), Caixa, Serviço de Autorização de Cheque Descrição: Um cliente paga uma venda com cheque num terminal ponto-de-venda. O pagamento é validado num serviço externo de autorização de cheque.

Sequência típica de eventos

Sequências Alternativas: Seção 5: A autorização é negada pelo Serviço de Autorização de Cheque. O Caixa sugere um outro método de pagamento.

anal2-2 programa anterior próxima

Ação do ator Resposta do sistema

1. O Use Case inicia quando um cliente decide pagar uma venda com CC, após descobrir o valor total da venda

2. O cliente entrega a informação de crédito para o pagamento 3. Gera um pedido de pagamento com CC e o envia a um Serviço de Autorização de Crédito

4. O Serviço de Autorização de Crédito autoriza o pagamento 5. Recebe uma aprovação de crédito do Serviço de Autorização de Crédito

6. Lança o pagamento com crédito e informação de autorização no sistema de Contas a Receber

7. Exibe uma messagem de sucesso de autorização

Ação do ator Resposta do sistema

1. O Use Case inicia quando um cliente decide pagar uma venda com cheque, após descobrir o valor total da venda

2. O cliente escreve o cheque e se identifica

3. O Caixa registra a informação de identificação e pede a autorização de pagamento com cheque

4. Gera um pedido de pagamento com cheque e o envia a um Serviço de Autorização de Cheque

5. O Serviço de Autorização de Cheque autoriza o pagamento 6. Recebe uma aprovação de crédito do Serviço de Autorização de Cheque

7. Exibe uma messagem de sucesso de autorização

Page 3 of 3Relacionando Múltiplos Use Cases

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal2.htm

Page 134: Apoo Jacques Ufcg

Extensão do Modelo Conceitual

Novos conceitos no estudo de caso

Examinando a lista de categorias de conceitos, preenchemos a tabela abaixo Categoria de Conceito Exemplos

Objetos físicos ou tangíveis Cartão de crédito, Cheque

Especificações, projetos ou descrições de coisas

Lugares

Transações (um momento notável) PagamentoComDinheiro, PagamentoComCC, PagamentoComCheque,

Detalhes de transação (Line item)

Papeis de pessoas

Coleções de outras coisas (containers)

Coisas dentro das coleções

Outros sistemas externos a nosso sistema SistemaAutorizaçãoCC, SistemaAutorizaçãoCheque

Conceitos abstratos

Organizações SistemaAutorizaçãoCC, SistemaAutorizaçãoCheque

Eventos

Processos (frequentemente não é representado como conceito, mas pode ocorrer)

Regras e políticas

Catálogos

Page 1 of 2Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal3.htm

Page 135: Apoo Jacques Ufcg

Pode-se também identificar conceitos novos através dos substantivos nos Use Cases Identificamos assim:

PedidoAutorizaçãoCC RespostaAutorizaçãoCC PedidoAutorizaçãoCheque RespostaAutorizaçãoCheque

Modelo conceitual inicial resultante

anal2-3 programa anterior próxima

Registros de assuntos financeiros, de trabalho, de contratos, legais ContasAReceber

Instrumentos e serviços financeiros

Manuais, livros

Page 2 of 2Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal3.htm

Page 136: Apoo Jacques Ufcg

Refinando o Modelo Conceitual

Introdução

Apresentam-se idéias adicionais associadas à modelagem conceitual

Tipos Associativos

Quando uma Loja usa um Serviço de Autorização, a comunicação envolve uma Identificação de Lojista

Onde seria armazenado o atributo? Não pode ficar na Loja, pois a identificação é diferente para cada Serviço Não pode ficar no Serviço, pois a identificação é diferente para cada Loja (Lojista)

Podemos modelar isso com um tipo associativo (ou Tipo de Associação)

Regras: quando usar um tipo associativo? Um atributo está relacionado com uma associação Instâncias do tipo associativo têm tempo de vida dependentes da associação Há uma associação muitos-para-muitos entre dois conceitos e há informação

associada à associação em si Há uma única instância do tipo associativo para uma associação envolvendo dois

conceitos Exemplo fácil para os alunos: Modele o domínio de problema envolvendo Aluno,

Page 1 of 3Refinando o Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal6.htm

Page 137: Apoo Jacques Ufcg

DescriçãoDeDisciplina, DisciplinaCursada, etc. Onde vai o conceito recebido numa disciplina cursada?

Agregação e composição

A agregação é uma associação que modela um relacionamento todo-parte O "todo" é chamado composite As partes não têm nome padronizado (parte, componente, elemento, ...)

Exemplo: todo = mão, partes = dedos Agregação na UML

Agregação composta A cardinalidade do lado composite é 1 O losango é cheio (preto) Significa que o composite possui as partes sozinho, sem compartilhamento

Agregação compartilhada A cardinalidade do lado composite pode ser maior que 1 Significa que uma parte pode estar em mais de um composite Exemplo no domínio de desenho gráfico

Regras para identificar agregação O tempo de vida das partes está incluso no tempo de vida do composite Tem uma relação óbvia de todo-parte ou montagem lógica Algumas propriedades do composite se propagam para as partes

Exemplo: localização Operações aplicadas ao composite propagam paraa as partes

Exemplos: movimento, destruição, ... Usa ou não usar agregação nos diagramas

Não é muito importante e pode ser excluído ao construir um modelo conceitual As vantagens são mais importantes durante a fase de projeto Durante o projeto, a agregação

Identifica mais claramente dependências de tempo de vida Ajuda a identificar o criador das partes (padrão Creator) Alerta para a possível propagação de operações

Exemplo: clone, ou Deep Copy Agregação no estudo de caso

Page 2 of 3Refinando o Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal6.htm

Page 138: Apoo Jacques Ufcg

Nomes de papeis na associações

O uso de nomes de papeis, de cada lado de uma associação é possível mas não obrigatório

Associações qualificadas

Numa associação, um qualificador ajuda a determinar um ou mais objetos do lado destino de uma associação

Exemplo: UPC é usado (conceitualmente) para identificar Especificações de Produtos dentro de um Catálogo de Produtos

Observe que a cardinalidade foi afetada

Cuidado! Já que estamos na análise, uma associação qualificada apenas pode ajudar a entender o modelo melhor

Nada significa sobre a escolha de chaves de recuperação no projeto

anal2-6 programa anterior próxima

Page 3 of 3Refinando o Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal6.htm

Page 139: Apoo Jacques Ufcg

Generalização

Generalização

Os conceitos PagamentoDinheiro, PagamentoCC e PagamentoCheque são semelhantes de podem ser organizados num hierarquia de tipos chamada Generalização-Especialização

Temos um supertipo (Pagamento) que representa um conceito mais genérico e subtipos mais especializados

A generalização é útil pois: Permite identificar conceitos em termos mais gerais e abstratos Permite evitar a repetição de informação No momento de implementar, a herança será usada e ela permite polimorfismo, o

que leva a código mais extensível Duas formas de representar generalização em UML

Definição de Supertipos e Subtipos

Uma definição de supertipo é mais geral do que uma definição de subtipo Exemplo:

Page 1 of 5Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal4.htm

Page 140: Apoo Jacques Ufcg

Um Pagamento (genérico) envolve um valor transferido entre partes Um PagamentoCC é um Pagamento que deve ser autorizado Portanto, Pagamento é mais geral e PagamentoCC é mais específico

Em termos de teoria dos conjuntos: Todos os membros de um conjunto de subtipo pertence ao conjunto do supertipo

Duas regras úteis para verificar se subtipos são de fato subtipos de um supertipo Regra 100%: 100% da definição do supertipo deve ser aplicáveis ao subtipo,

incluindo atributos e associações Exemplo: Os subtipos de Pagamento devem:

Ter um atributo "valor" Ter uma associação com Venda (Pagamento Paga-uma Venda)

Isso é verdade para os subtipos acima Regra É-um: Todos os membros de um conjunto de subtipo pertence ao conjunto do

supertipo Em linguagem natural, pode-se dizer Subtipo É-um Supertipo

Quando definir um subtipo

O particionamento nem sempre é útil Exemplo: Supertipo Cliente e subtipos ClienteMasculino e ClienteFeminino pode não

ser útil Para criar um subtipo, uma das 4 regras abaixo deve se aplicar:

O subtipo tem atributos adicionais O subtipo tem associações adicionais O conceito subtipo é manipulado, recebe operações, reage, ou leva a reações

diferentemente do supertipo ou outros subtipos O conceito subtipo representa uma coisa animada (animal, robô, ...) que se comporta

de forma diferente comparado ao subtipo ou outros subtipos Pelas regras, os subtipos ClienteMasculino e ClienteFeminino não parecem úteis (mas

podem ser em algumas aplicações estranhas) Exemplos concretos seguem:

Motivação para ter um subtipo Exemplos

O subtipo tem atributos adicionaisPagamentos - não aplicável

Biblioteca - Livro, subtipo de RecursoEmprestável tem um ISBN

O subtipo tem associações adicionais

Pagamentos - PagamentoCC, subtipo de Pagamento, está associado a um CC

Biblioteca - Vídeo, subtipo de RecursoEmprestável, está associado a um Diretor

O conceito subtipo é manipulado, recebe operações, reage, ou leva a reações diferentemente do supertipo ou outros subtipos

Pagamentos - PagamentoCC, subtipo de Pagamento, é manipulado de forma diferente no que diz respeito a autorização

Biblioteca - Software, subtipo de RecursoEmprestável, requer um depósito antes de ser emprestado

O conceito subtipo representa uma coisa animada (animal, robô, ...)

Pagamentos - não aplicável

Biblioteca - não aplicável

Page 2 of 5Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal4.htm

Page 141: Apoo Jacques Ufcg

Quando definir um supertipo

A generalização de tipos existentes é motivada pela identificação de fatores comuns entre subtipos potenciais

Algumas regras: Os subtipos potenciais representam variações de um conceito similar Os subtipos obedecerão as regras 100% e É-um Todos os subtipos possuem um determinado atributo que pode ser fatorado e

colocado no supertipo Todos os subtipos possuem uma determinada associação que pode ser fatorada e

colocada no supertipo

Estudo de caso: Terminal ponto-de-venda

Tipos de Pagamentos Ver a motivação da criação da hierarquia na figura abaixo

Tipos de Serviços de Autorização Ver a motivação da criação da hierarquia na figura abaixo

que se comporta de forma diferente comparado ao subtipo ou outros subtipos

Pesquisa de mercado - PessoaMasculina, subtipo de Pessoa, tem um comportamento diferente de PessoaFeminina com respeito a hábitos de compras

Page 3 of 5Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal4.htm

Page 142: Apoo Jacques Ufcg

Tipos de Transações de Autorização Transações com o mundo externo devem ser mostradas no modelo conceitual porque os

processos utilizam esses conceitos Vários tipos de hierarquias podem ser montadas usando esses conceitos Usar uma hierarquia muito profunda pode ser complexo demais Optamos pela estrutura abaixo que exibe as relações enquanto mantém uma certa

simplicidade

Tipos abstratos

Se um conceito não pode existir como instância concreta, estamos definindo um tipo abstrato

Exemplo: um Pagamento não pode existir, sem que seja um dos subtipos Em UML, um tipo abstrato recebe um nome em itálico

Na implementação, um tipo abstrato pode ser implementado como classe abstrata ou como interface (em Java, por exemplo)

Mutação de tipos

Não modele mudanças de estado de objetos como mudanças de tipos (mutações) Exemplo: um Pagamento pode ser não autorizado (no início) e passar a ser autorizado

Não modele isso como mudança de um tipo PagamentoNãoAutorizado para outro tipo PagamentoAutorizado

Falaremos mais sobre mutações quando elaborarmos sobre herança num capítulo futuro

Generalização e herança

Não falamos de herança aqui porque estamos no mundo conceitual e não estamos falando de classes de software

Em linguagens OO, uma subclasse de uma superclasse herda atributos e métodos A herança é portanto uma forma de implementar a regra 100%

Page 4 of 5Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal4.htm

Page 143: Apoo Jacques Ufcg

Ao passar para a fase de projeto, poderemos ou não usar herança para as hierarquias de tipo

Exemplo, em C++, poderíamos usar uma única classe com templates em vez de uma hierarquia de classes

anal2-4 programa anterior próxima

Page 5 of 5Extensão do Modelo Conceitual

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal4.htm

Page 144: Apoo Jacques Ufcg

Modelo Conceitual no Estudo de Caso

O Package Conceitos De Domínio

O Package Elementos Básicos

O Package Pagamentos

Page 1 of 3Modelo Conceitual no Estudo de Caso

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal7.htm

Page 145: Apoo Jacques Ufcg

O Package Produtos

O Package Vendas

Page 2 of 3Modelo Conceitual no Estudo de Caso

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal7.htm

Page 146: Apoo Jacques Ufcg

O Package Transações De Autorização

anal2-7 programa anterior próxima

Page 3 of 3Modelo Conceitual no Estudo de Caso

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal7.htm

Page 147: Apoo Jacques Ufcg

Comportamento do Sistema: Diagramas de Sequência e Contratos na Segunda Iteração

Diagramas de Sequência do Sistema

Para esta iteração, os diagramas de sequência do sistema devem representar o processo de escolher e tratar o método de pagamento

O início comum para o Use Case Comprar Itens O início não depende do método de pagamento

Pagamento com cartão de crédito Após o início comum, a seguinte sequência é usada:

Page 1 of 2Comportamento do Sistema: Diagramas de Sequência e Contratos na Segunda Iteração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal8.htm

Page 148: Apoo Jacques Ufcg

Pagamento com cheque Após o início comum, a seguinte sequência é usada:

Contratos

Os contratos podem ser elaborados para cada evento do sistema

Os detalhes podem ser vistos no livro texto (Larman)

anal2-8 programa anterior próxima

Page 2 of 2Comportamento do Sistema: Diagramas de Sequência e Contratos na Segunda Iteração

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal8.htm

Page 149: Apoo Jacques Ufcg

Comportamento do Sistema: Diagramas de Estado

Eventos, estados e transições

Um evento é uma "ocorrência interessante" Exemplo: os eventos do sistema discutidos anteriormente (entraItem, ...)

Um estado é a condição de um objeto entre dois eventos Exemplo: no estudo de caso, o sistema está no estado "Entrando itens" enquanto

itens estão sendo informados

Diagramas de estado

Diagramas de estado podem ser usados para Use Cases complexos Quando a ordem legal de eventos do sistema não é óbvia

Não Use Case complexo no estudo de caso, mas podemos mostrar um diagrama de estado nesse contexto (Use Case Comprar Itens)

anal2-9 programa anterior

Page 1 of 1Comportamento do Sistema: Diagramas de Estado

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\anal2\anal9.htm

Page 150: Apoo Jacques Ufcg

7. Fase de Projeto 2 Padrões adicionais para atribuir responsabilidades Interfaces Composição versus herança Padrões de Projeto (Design Patterns)

O que são Design Patterns? Elementos essenciais de um Design Pattern Design Pattern: Factory Method Design Pattern: Iterator Design Pattern: Composite Design Pattern: Strategy Design Pattern: Decorator Design Pattern: Template Method Design Pattern: Observer

proj2 programa

Page 1 of 17. Fase de Projeto 2

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\index.htm

Page 151: Apoo Jacques Ufcg

Polimorfismo

O padrão de projeto Polimorfismo

Problema Como tratar alternativas baseadas no tipo de objeto?

Se usar if-then-else ou switch-case, temos que mudar o código sempre que uma nova alternativa surge

A modificação tem que ser feita em todo lugar onde a alternativa deve ser tratada

O resultado é um código pouco extensível Como criar componentes plugáveis?

Como trocar um componente por outro sem afetar os clientes do componente? Há uma discussão mais detalhada de componentes em outro capítulo

Solução Usar operações polimórficas ao comportamento que varia entre os tipos Resultado: não se testa o tipo do objeto, chama-se a operação polimórfica,

simplesmente

Exemplo No estudo de caso, quem deveria ser responsável pela autorização de diferentes tipos

de pagamentos? Como a forma de obter autorização depende do tipo de pagamento (dinheiro, CC ou

cheque), podemos usar uma operação polimórfica autorize() A implementação da operação será diferente em cada subtipo

Discussão A idéia é semelhante ao padrão Expert ("eu mesmo faço") Polimorfismo é um dos padrões mais importantes no projeto de software Extensões são simples

Exemplo: como adicionar um método de pagamento com débito direto em conta corrente?

Consequências Adições futuras e não antecipadas têm pouco efeito no código existente

proj2-1 programa próxima

Page 1 of 1Padrões Adicionais para Atribuir Responsablidades

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj1.htm

Page 152: Apoo Jacques Ufcg

Interfaces

Herança de classe versus herança de interface

Há uma diferença grande entre uma classe e seu tipo A classe define uma implementação O tipo define apenas a interface oferecida para acessar objetos da classe Um objeto pode ter muitos tipos Classes diferentes podem ter o mesmo tipo

Herança de classe significa herança de implementação A sub-classe herda a implementação da super-classe É um mecanismo para compartilhar código e representação

Herança de interface (ou sub-tipos) descreve quando um objeto pode ser usado em vez de outro Ao fazer herança de classe, automaticamente faz também herança de interface Algumas linguagens não permitem definir tipos separadamente de classes

Mas, neste caso, a classe puramente abstrata serve

"Program to an interface, not an implementation"

O fato de que a herança de implementação permite facilmente reusar a funcionalidade de uma classe é interessante mas não é o aspecto mais importante a ser considerado

Herança oferece a habilidade de definir famílias de objetos com interfaces idênticas Isso é extremamente importante pois permite desacoplar um objeto de seus clientes através do polimorfismo A herança de interface corretamente usada (sem eliminar partes da interface nas sub-classes) acaba criando sub-tipos,

permitindo o polimorfismo Programar em função de uma interface e não em função de uma implementação (uma classe particular) permite o

polimorfismo e fornece as seguintes vantagens: Clientes permanecem sem conhecimento do tipo de objetos que eles usam, desde que os objetos obedeçam a

interface Clientes permanecem sem conhecimento das classes que implementam tais objetos

A interface é o que há de comum A flexibilidade vem da possibilidade de mudar a implementação da interface, até em tempo de execução, já que o

polimorfismo é implementado com "late binding" feito em tempo de execução Em java, uma classe pode implementar várias interfaces

Isso permite ter mais polimorfismo mesmo sem que as classes pertençam a uma mesma hierarquia

Exemplo no uso de interfaces

Temos vários tipos de composites (coleções) que não pertencem a uma mesma hierarquia ColeçãoDeAlunos ColeçãoDeProfessores ColeçãoDeDisciplinas

Temos um cliente comum dessas coleções Digamos um selecionador de objetos usado numa interface gráfica para abrir uma list box para selecionar objetos

com um determinado nome Exemplo:

Quero listar todos os alunos com nome "João" e exibí-los numa list box para escolha pelo usuário Idem para listar professores com nome "Alfredo" Idem para listar disciplinas com nome "Programação"

Queremos fazer um único cliente para qualquer uma das coleções O exemplo abaixo tem polimorfismo em dois lugares

interface SelecionávelPorNome { Iterator getIteradorPorNome(String nome); } interface Nomeável { String getNome(); } classe ColeçãoDeAlunos implements SelecionávelPorNome { // ... Iterator getIteradorPorNome(String nome) { // ... } } classe Aluno implements Nomeável { // ...

Page 1 of 3Interfaces

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj2.htm

Page 153: Apoo Jacques Ufcg

String getNome() { ... } } classe ColeçãoDeProfessores implements SelecionávelPorNome { // ... Iterator getIteradorPorNome(String nome) { // ... } } classe Professor implements Nomeável { // ... String getNome() { ... } } classe ColeçãoDeDisciplinas implements SelecionávelPorNome { // ... Iterator getIteradorPorNome(String nome) { // ... } } classe Disciplina implements Nomeável { // ... String getNome() { ... } } classe ComponenteDeSeleção { Iterator it; // observe o tipo do parâmetro (uma interface) public ComponenteDeSeleção(SelecionávelPorNome coleção, String nome) { it = coleção.getIteradorPorNome(nome); // chamada polimórfica } // ... void geraListBox() { response.out.println("<select name=\"nome\" size=\"1\">"); while(it.hasNext()) { int i = 1; // observe o tipo do objeto Nomeável obj = (Nomeável)it.next(); response.out.println("<option value=\"escolha" + i + "\">" + obj.getNome() + // chamada polimórfica "</option>"); } response.out.println("</select>"); } } // Como usar o código acima num servlet: // supõe que as coleções usam o padrão Singleton ComponenteDeSeleção cds = new ComponenteDeSeleção(ColeçãoDeAlunos.getInstance(), "João"); cds.geraListBox(); cds = new ComponenteDeSeleção(ColeçãoDeDisciplinas.getInstance(), "Programação"); cds.geraListBox();

Como achar interfaces

Procure assinaturas repetidas Exemplo: várias classes que representam coisas que podem ser vendidas indicam o uso de uma interface

VendávelIF Onde há delegação, um objeto se esconde atrás de outro: deve haver uma interface comum Procure métodos que poderiam ser usadas em aplicações semelhantes e use interfaces para que a reusabilidade das

classes clientes seja maior Exemplo: muitas coisas poderiam ser reserváveis, não só passagens de avião

Page 2 of 3Interfaces

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj2.htm

Page 154: Apoo Jacques Ufcg

Exemplo: muitas coisas pode ser alugadas, não só fitas de vídeo Exemplo: muitos objetos são clonáveis

Procure mudanças futuras (novos objetos que poderiam aparecer) e coloque as semelhanças sob controle de interfaces Há, entretanto, pessoas que não concordam em "pensar muito na frente"

Vide "Extreme Programming" adiante ...

proj2-2 programa próxima

Page 3 of 3Interfaces

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj2.htm

Page 155: Apoo Jacques Ufcg

Composição versus Herança

Composição e Herança

Composição e herança são dois mecanismos para reutilizar funcionalidade Alguns anos atrás (e na cabeça de alguns programadores ainda!), a herança era

considerada a ferramenta básica de extensão e reutilização de funcionalidade A composição estende uma classe pela delegação de trabalho para outro objeto

a herança estende atributos e métodos de uma classe Hoje, considera-se que a composição é muito superior à herança na maioria dos

casos A herança deve ser utilizada em alguns (relativamente poucos) contextos

Um exemplo de composição

Use composição para estender as responsabilidades pela delegação de trabalho a outros objetos

Um exemplo no domínio de endereços Uma empresa tem um endereço (digamos só um) Uma empresa "tem" um endereço Podemos deixar o objeto empresa responsável pelo objeto endereço e temos

agregação composta (composição)

Um exemplo de herança

Atributos, conexões a objetos e métodos comuns vão na superclasse (classe de generalização)

Adicionamos mais dessas coisas nas subclasses (classes de especialização) Três situações comuns para a herança (figura abaixo)

Uma transação é um momento notável ou intervalo de tempo

Exemplo no domínio de reserva e compra de passagens de avião

Page 1 of 5Composição versus Herança

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj3.htm

Page 156: Apoo Jacques Ufcg

Benefícios da herança

Captura o que é comum e o isola daquilo que é diferente A herança é vista diretamente no código

Problemas da herança

O encapsulamento entre classes e subclasses é fraco (acoplamento é forte) Mudar uma superclasse pode afetar todas as subclasses Isso viola um dos princípios básicos de projeto O-O (fraco acoplamento)

Às vezes um objeto precisa ser de uma classe diferente em momentos diferentes Com herança, a estrutura está parafusada no código e não pode sofrer

alterações facilmente em tempo de execução A herança é um relacionamento estático que não muda com tempo Cenário: pessoas envolvidas na aviação (fugira abaixo)

Page 2 of 5Composição versus Herança

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj3.htm

Page 157: Apoo Jacques Ufcg

Problema: uma pessoa pode mudar de papel a assumir combinações de papeis Fazer papeis múltiplos requer 7 combinações (subclasses)

Solucionando o problema com composição: uma pessoa e vários papeis possíveis

Observe que também podemos inverter a composição (uma pessoa tem um ou mais papeis)

Pense na implicação par a interface de "pessoa" Aqui, estamos usando delegação: dois objetos estão envolvidos em atender um

pedido (digamos setNome) O objeto tripulação (digamos) delega setNome para o objeto pessoa que ele

tem por composição Técnica também chamada de forwarding É semelhante a uma subclasse delegar uma operação para a superclasse

(herdando a operação) Delegação sempre pode ser usada para substituir a herança

Se usássemos herança, o objeto tripulação poderia referenciar a pessoa com this

Com o uso de delegação, tripulação pode passar this para pessoa e o objeto pessoa pode referenciar o objeto original se quiser

Em vez de tripulação ser uma pessoa, ele tem uma pessoa A grande vantagem da delegação é que o comportamento pode ser escolhido

em tempo de execução e vez de estar amarrado em tempo de compilação A grande desvantagem é que um software muito dinâmico e parametrizado é

mais difícil de entender do que software mais estático

O resultado de usar composição

Em vez de codificar um comportamento estaticamente, definimos pequenos comportamentos padrão e usamos composição para definir comportamentos mais complexos

5 regras para o uso de herança (Coad)

Page 3 of 5Composição versus Herança

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj3.htm

Page 158: Apoo Jacques Ufcg

O objeto "é um tipo especial de" e não "um papel assumido por" O objeto nunca tem que mudar para outra classe A subclasse estende a superclasse mas não faz override ou anulação de variáveis

e/ou métodos Não é uma subclasse de uma classe "utilitária"

Não é uma boa idéia fazer isso porque herdar de, digamos, HashMap deixa a classe vulnerável a mudanças futuras à classe HashMap

O objeto original não "é" uma HashMap (mas pode usá-la) Não é uma boa idéia porque enfraquece a encapsulação

Clientes poderão supor que a classe é uma subclasse da classe utilitária e não funcionarão se a classe eventualmente mudar sua superclasse

Exemplo: x usa y que é subclasse de vector x usa y sabendo que é um Vector Amanhã, y acaba sendo mudada para ser subclasse de HashMap x se lasca!

Para classes do domínio do problema, a subclasse expressa tipos especiais de papeis, transações ou dispositivos

Exemplo da aplicação das regras Considere Agente, Tripulação e Passageiro como subclasses de Pessoa

Regra 1 (tipo especial): não passa. Um Passageiro não é um tipo especial de Pessoa: é um papel assumido por uma Pessoa

Regra 2 (mutação): não passa. Um Agente pode se transformar em Passageiro com tempo

Regra 3 (só estende): ok. Regra 4: ok. Regra 5: não passa. Passageiro está sendo modelado como tipo especial de

Pessoa e não como tipo especial de papel

Outro exemplo: transações

Reserva e Compra podem herdar de Transação?

Regra 1 (tipo especial): ok. Uma Reserva é um tipo especial de Transação e não um papel assumido por uma Transação

Page 4 of 5Composição versus Herança

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj3.htm

Page 159: Apoo Jacques Ufcg

Regra 2 (mutação): ok. Uma reserva sempre será uma Reserva, e nunca se transforma em Compra (se houver uma compra da passagem, será outra transação). Idem para Compra: sempre será uma Compra

Regra 3 (só estende): ok. Ambas as subclasses estendem Transação com novas variáveis e métodos e não fazem override ou anulam coisas de Transação

Regra 4 (não estende classe utilitária): ok. Regra 5 (tipo especial de papel/transação/dispositivo): ok. São tipos especiais de

Transação

proj2-3 programa

Page 5 of 5Composição versus Herança

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\proj2\proj3.htm

Page 160: Apoo Jacques Ufcg

Design Patterns

O que são Design Patterns? Uma definição informal:

"Cada padrão descreve um problema que ocorre frequentemente e então descreve o cerne da solução ao problema de forma a poder reusar a solução milhões de vezes em situações diferentes"

Observe que o que é reutilizado são as classes e suas colaborações Reuso de idéias, não código Consistem de micro-arquiteturas de classes, objetos, seus papeis e suas

colaborações Contêm o somatório da experiência dos melhores projetistas O-O! Estão revolucionando o projeto de software desde 1995 quando o famoso livro da

"Gang of Four" (GoF) apareceu com o primeiro catálogo de 23 padrões Ver bibliografia Tem muito mais padrões aparecendo sempre OOPSLA é uma grande fonte de padrões

Ficará mais claro com alguns exemplos Design Patterns iniciaram a febre de padrões

Analysis Patterns Testing Patterns Business Patterns Pedagogical Patterns e mais ...

Há um meta-padrão envolvido: Entre várias situações, isolar o que muda do que é igual.

Uma sinopse dos Design Patterns da GoF está aqui.

pat-1 programa próxima

Page 1 of 1O que são Design Patterns?

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\oque.htm

Page 161: Apoo Jacques Ufcg

Elementos essenciais de um Design Pattern

Um Nome

Descreve o problema de projeto, suas soluções e consequências em poucas palavras

Permite projetar num nível mais alto de abstração Permite falar com outros sobre soluções e documentar código, já que os nomes de

padrões estão ficando padronizados "Todo mundo" conhece os 23 padrões da GoF É equivalente a padronizar "lista encadeada", "pilha", etc. no mundo das

estruturas de dados

O Problema

Descreve quando aplicar o padrão Descreve o problema e o contexto Pode descrever problemas específicos de projeto

Exemplo: como representar algoritmos como objetos? Pode descrever estruturas de objetos ou de classes que são sintomas de um

projeto inflexível Às vezes, o padrão lista condições que devem se aplicar para usar o padrão

A Solução

Descreve os elementos constituintes do projeto, seus relacionamentos, responsabilidades e colaborações

A solução não descreve um projeto ou implementação concretos porque um padrão é um gabarito de solução para várias situações

As Consequências

Os resultados e trade-offs da aplicação do padrão Diz respeito a trade-offs de espaço, tempo, flexibilidade, extensibilidade,

portabilidade

pat-2 programa anterior próxima

Page 1 of 1Elementos essenciais de um Design Pattern

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\elem.htm

Page 162: Apoo Jacques Ufcg

Factory Method

Introdução aos Padrões de Criação: Construindo Labirintos

GoF classifica os padrões em Padrões de Criação, Estruturais e de Comportamento Padrões de criação abstraem o processo de instanciação de objetos Usaremos a construção de labirintos para um jogo via computador para mostrar

alguns padrões de criação Ignoraremos muitos detalhes do labirinto (o que pode estar no labirinto, os

jogadores, etc.) Foco na criação dos labirintos

Um labirinto é um conjunto de salas Uma sala conhece seus quatro vizinhos Vizinhos podem ser outra sala, uma parede ou uma porta para outra sala

As classes importantes são Sala, Porta e Parede Só trataremos as partes das classes que interessam para a criação do labirinto

O diagrama de classes segue abaixo (em UML) Se precisar de um resumo de UML, ver aqui

Um diagrama de objetos segue para um pequeno labirinto

Page 1 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 163: Apoo Jacques Ufcg

Cada sala tem quatro vizinhos Usamos norte, sul, leste, oeste para referenciá-los

A interface ElementoDeLabirinto é implementada por todos os componentes de um labirinto

Tem um método entra() cujo significado depende onde se está entrando Se for uma sala, a localização do jogador muda Se for uma porta aberta, você vai para outra sala, caso contrário se

machuca Se for uma parede, você se machuca

public interface ElementoDeLabirinto { public void entra(); }

Exemplo: se você estiver numa sala e quiser implementar a operação "vá para o leste", o jogo determina qual ElementoDeLabirinto está do lado leste e chama entra() deste objeto

O método entra() da subclasse específica determina o que ocorre Num jogo real, entra() poderia aceitar o objeto jogador como parâmetro

Sala é a classe que implementa ElementoDeLabirinto e define as relações-chave entre objetos

Mantém referências para 4 outros ElementoDeLabirinto Armazena um número de sala para indentificar as salas do labirinto

class Sala implements ElementoDeLabirinto { private ElementoDeLabirinto[] vizinhos =

Page 2 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 164: Apoo Jacques Ufcg

new ElementoDeLabirinto[4]; private int númeroDaSala; public Sala(int númeroDaSala) { ... } public void entra() { ... } public ElementoDeLabirinto getVizinho(int direção) { ... } public void setVizinho(int direção, ElementoDeLabirinto vizinho) { ... } } class Parede implements ElementoDeLabirinto { public Parede() { ... } public void entra() { ... } } class Porta implements ElementoDeLabirinto { private Sala sala1, sala2; private boolean estáAberta; public Porta(ElementoDeLabirinto sala1, ElementoDeLabirinto sala2) { ... } public void entra() { ... } public Sala salaDoOutroLado(Sala sala) { ... } }

Também precisamos de uma classe Labirinto para representar uma coleção de salas

A classe Labirinto pode localizar uma sala dado seu número com o método getSala()

class Labirinto { private Vector salas = new Vector(); public Labirinto() { ... } public void adicionaSala(Sala sala) { ... } public sala getSala(int númeroDaSala) { ... } }

Também definimos uma classe Jogo que cria o labirinto Uma forma simples de criar um labirinto é de criar os componentes, adicioná-

los ao labirinto e interconectá-los Exemplo da criação de um labirinto com 2 salas e uma porta entre elas

Page 3 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 165: Apoo Jacques Ufcg

class Jogo { ... public Labirinto criaLabirinto() { Labirinto umLabirinto = new Labirinto(); Sala sala1 = new Sala(1); Sala sala2 = new Sala(2); Porta aporta = new Porta(sala1,sala2); umLabirinto.adicionaSala(sala1); umLabirinto.adicionaSala(sala2); sala1.setVizinho(norte, new Parede()); sala1.setVizinho(leste, aporta); sala1.setVizinho(sul, new Parede()); sala1.setVizinho(oeste, new Parede()); sala2.setVizinho(norte, new Parede()); sala2.setVizinho(leste, new Parede()); sala2.setVizinho(sul, new Parede()); sala2.setVizinho(oeste, aporta); return umLabirinto; } ... }

O problema desta solução é sua inflexibilidade O método criaLabirinto() não é reutilizável em outras situações Motivo: criaLabirinto() mistura a questão da estrutura do labirinto com a

questão dos tipos exatos de elementos que compõem o labirinto New cria um forte acoplamento entre a classe Jogo e as classes dos objetos

criados porque implica num compromisso (amarração) com uma determinada implementação

Veremos agora como mudar o projeto para criar diferentes tipos de labirintos Labirintos encantados

Com portas travadas que precisam de um encantamento para abrir Salas contendo encantamentos que podem ser apanhados

Page 4 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 166: Apoo Jacques Ufcg

Labirintos perigosos Salas com bombas que podem ser explodidas para danificar as paredes (e

talvez o jogador!) Como mudar criaLabirinto() para facilmente criar estes novos tipos de labirintos?

O maior problema é que a solução atual nos força a colocar em código as classes concretas que serão instanciadas

Usaremos padrões de criação para tornar o projeto mais flexível (mais reusável)

O padrão Factory Method

Objetivo

Definir uma interface para criar objetos de forma a deixar subclasses decidirem qual classe instanciar

Factory Method deixa que subclasses façam a instanciação

Também conhecido como

Construtor Virtual

Resumo

A idéia é simples: em vez de um cliente que precisa de um objeto chamar new e assim especificar a classe concreta que ele instancia, o cliente chama um método abstrato (Factory Method) especificado em alguma classe abstrata (ou interface) e a subclasse concreta vai decidir que tipo exato de objeto criar e retornar

Mudar a subclasse concreta que cria o objeto permite mudar a classe do objeto criado sem que cliente saiba

Permite estender a funcionalidade através da construção de subclasses sem afetar os clientes

Resumindo: "Crie objetos numa operação separada de forma que subclasses possam fazer

override da forma de criação"

Quando usar o padrão Factory Method?

Quando uma classe (o criador) não pode antecipar a classe dos objetos que deve criar

Quando uma classe quer que suas subclasses especifiquem os objetos criados Quando classes delegam responsabilidade para uma entre várias subclasses de

apoio e queremos localizar num ponto único a conhecimento de qual subclasse está sendo usada

Estrutura genérica

Page 5 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 167: Apoo Jacques Ufcg

Participantes

Produto: define a interface dos objetos criados pelo Factory Method ProdutoConcreto: implementa a interface Produto Criador: declara o Factory Method que retorna um objeto do tipo Produto

Às vezes, o Criador não é apenas uma interface mas pode envolver uma classe concretaque tenha tem uma implementação default para o Factory Method para retornar um objeto com algum tipo ProdutoConcreto default

Pode chamar o Factory Method para criar um produto do tipo Produto CriadorConcreto: faz override do Factory Method para retornar uma instância de

ProdutoConcreto

Colaborações

Criador depende de suas subclasses para definir o Factory Method para que ele retorne uma instância do ProdutoConcreto apropriado

Consequências do uso do padrão Factory Method

Factory Methods eliminam a necessidade de colocar classes específicas da aplicaçãono código

O código só lida com a interface Produto O código pode portanto funcionar com qualquer classe ProdutoConcreto

Provê ganchos para subclasses Criar objetos dentro de uma classe com um Factory Method é sempre mais

flexível do que criar objetos diretamente O Factory Method provê um gancho para que subclasses forneçam uma versão

estendida de um objeto Exemplo num editor de documentos

Uma classe Documento poderia ter um Factory Method criaFileDialog para criar um objeto file dialog default para abrir um documento existente

Uma subclasse de Documento poderia criar um file dialog especial através do override do Factory Method default

Neste caso, o Factory Method não é abstrato mas fornece um default razoável

Exercício: como estruturar o código de uma aplicação bancária para que você não fique maluco quando seu gerente pedir que todas as novas contas de poupança criadas a partir de segunda-feira tenham algo novo implementado nelas mas sem afetar código antigo que trata das contas antigas?

Considerações de implementação

É boa prática usar uma convenção de nomes para alertar para o fato de que está

Page 6 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 168: Apoo Jacques Ufcg

usando Factory Methods Exemplo: makeAbc(), makeXyz() Exemplo: criaAbc(), criaXyz()

Exemplo de código: criação de labirintos

A criação de labirintos já vista não ficou flexível pois criamos (com new) os objetos especificando as classes concretas na função criaLabirinto()

Usaremos Factory Methods para deixar que subclasses escolham que objetos criar Usaremos o seguinte projeto

Produto: Sala, Parede, Porta ProdutoConcreto: Sala, SalaEncantada, SalaPerigosa, Parede,

ParedeComBomba, Porta, PortaComChave Ccriador: Jogo

Seu método criaLabirinto cria o labirinto chamando Factory Methods Ele também é um CriadorConcreto pois oferece uma implementação default

para os Factory Methods (para criar um labirinto simples) CriadorConcreto: Jogo, JogoEncantado, JogoPerigoso que serão subclasses de

jogo Iniciamos com o criador Jogo que contém os Factory Methods

class Jogo { // Factory Methods com default public Labirinto criaLabirinto() { return new Labirinto(); } public Sala criaSala(int númeroDaSala) { return new Sala(númeroDaSala); } public Parede criaParede() { return new Parede(); } public Porta criaPorta(Sala sala1, Sala sala2) { return new Porta(sala1, sala2); } // Observe que essa função não tem new: // ela usa Factory Methods // Esta é a *única* diferença com relação // à versão original // Observe como o método só trata da estrutura do labirinto // e não do tipo de elemento que o compõe public Labirinto criaLabirinto() { Labirinto umLabirinto = criaLabirinto(); Sala sala1 = criaSala(1); Sala sala2 = criaSala(2); Porta aPorta = criaPorta(sala1, sala2); umLabirinto.adicionaSala(sala1); umLabirinto.adicionaSala(sala2); sala1.setVizinho(norte, criaParede()); sala1.setVizinho(leste, aporta); sala1.setVizinho(sul, criaParede()); sala1.setVizinho(oeste, criaParede()); sala2.setVizinho(norte, criaParede()); sala2.setVizinho(leste, criaParede()); sala2.setVizinho(sul, criaParede()); sala2.setVizinho(oeste, aporta); return umLabirinto; }

Page 7 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 169: Apoo Jacques Ufcg

}

Para criar um jogo perigoso, criamos uma subclasse de Jogo e redefinimos alguns Factory Methods

// um novo CriadorConcreto class JogoPerigoso extends Jogo { public Parede criaParede() { return new ParedeDestrutível(); } public Sala criaSala(int númeroDaSala) { return new SalaComBomba(númeroDaSala); } }

Comparando o diagrama de objetos com a versão inicial, não há objeto adicional Só há uma mudança do objeto umJogo para um umJogoPerigoso

Para criar um jogo encantado, procedemos de forma análoga

// um novo CriadorConcreto class JogoEncantado extends Jogo { public sala criaSala(int númeroDaSala) { return new salaEncantada(númeroDaSala, jogaEncantamento()); } public Porta criaPorta(Sala sala1, Sala sala2) { return new portaPrecisandoDeEncantamento(sala1, sala2); } protected Encantamento jogaEncantamento() { ... }

Page 8 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 170: Apoo Jacques Ufcg

}

O acoplamento depois do Factory Method

Discussão geral de padrões de criação

Ajudam a deixar o sistema independente de como seus objetos são criados, compostos e representados

São dois tipos: Padrões de criação via classes

Usam herança para variar a classe que é instanciada Exemplo: Factory Method

Padrões de criação via objetos Delegam a instanciação para outro objeto Exemplo: Abstract Factory

Composição é usada mais que herança para estender funcionalidade e padrões de criação ajudam a lidar com a complexidade de criar comportamentos

Em vez de codificar um comportamento estaticamente, definimos pequenos comportamentos padrão e usamos composição para definir comportamentos mais complexos

Isso significa que instanciar um objeto com um comportamento particular requer mais do que simplesmente instanciar uma classe.

Eles escondem como instâncias das classes concretas são criadas e juntadas para gerar "comportamentos" (que podem envolver vários objetos compostos)

Os padrões mostrados aqui mostram como encapsular as coisas de forma a simplificar o problema de instanciação.

Os padrões de criação discutem temas recorrentes: Eles encapsulam o conhecimento das classes concretas que são instanciadas

Lembre que preferimos nos "amarrar" a interfaces (via interface ou classes abstratas) do que a classes concretas

Isso promove a flexibilidade de mudança (das classes concretas que são instanciadas)

Page 9 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 171: Apoo Jacques Ufcg

Pergunta final para discussão

De que forma a Factory Method ajuda a produzir código fracamente acoplado?

pat-3 programa anterior próxima

Page 10 of 10Factory Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\factory.htm

Page 172: Apoo Jacques Ufcg

Iterator

Objetivo

Prover uma forma de sequencialmente acessar os elementos de um objeto agragado sem expor sua representação interna

Também conhecido como

Cursor

Motivação

Queremos isolar o uso de uma estrutura de dados de sua representação interna de forma a poder mudar a estrutura sem afetar quem a usa

Para determinadas estruturas, pode haver formas diferentes de caminhamento ("traversal") e queremos encapsular a forma exata de caminhamento

Exemplo: árvore pode ser varrida "em ordem", "em pós-ordem", em "pré-ordem"

Exemplo: podemos ter um "iterador com filtro" que só retorna certos elementos da coleção

Exemplo: num editor de documentos, poderíamos ter os elementos do documento organizados em árvores (documento consiste de páginas qe consistem de parágrafos, ...) e ter um iterador especial para elementos não gráficos (que podem ter sua grafia verificada, por exemplo)

A idéia do iterador é de retirar da coleção a responsabilidade de acessar e caminhar na estrutura e colocar a responsabilidade num novo objeto separado chamado um iterador

A interface Iterador: Define uma interface para acessar os elementos da coleção

A classe Iterador Implementa a interface Iterador Mantém qualquer informação de estado necessária para saber até onde a

iteração (caminhamento) já foi Como criar um iterador?

Não podemos usar new de uma classe concreta diretamente pois o iterador a ser criado depende da coleção a ser varrids

Solução: a coleção tem um factory method para criar um iterador Exemplo em java: Vector.iterator()

Aplicabilidade: use o padrão iterador

Para acessar o conteúdo de uma coleção sem expor suas representação interna Para suportar múltiplas formas de caminhamento Para prover uma interface única para varrer estruturas agregadas diferentes

Isto é, para suportar iteração polimórfica

Estrutura

Page 1 of 4Iterator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\iterator.htm

Page 173: Apoo Jacques Ufcg

Exemplo de uso: um impressor genérico em Java

class Printer { static void printAll(Iterator it) { while(it.hasNext()) { System.out.println(it.next().toString()); } } } class LabirintoDeRatos { public static void main(String[] args) { Vector ratos = new Vector(); for(int i = 0; i < 3; i++ ) { ratos.add(new Rato(i)); } // iterador criado aqui Printer.printAll(ratos.iterator()); } }

Participantes

Iterador (Enumeration no Java original) Define a interface para acessar e caminhar nos elementos

IteradorConcreto (elements() no Java original, iterator() no Java recente) Implemementa a interface Iterator Mantém estado para saber o elemento corrente na coleção

Coleção (não tem isso no Java antigo; no Java recente, chama-se Collection) Define uma interface para criar um objeto iterador

ColeçãoConcreta (Vector, ArrayList, LinkedList, ... em Java) Implementa a interface de criação do iterador e retorna uma instância do

IteradorConcreto

Consequências

Page 2 of 4Iterator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\iterator.htm

Page 174: Apoo Jacques Ufcg

A mera substituição de um iterador permite caminhar numa coleção de várias formas

Juntar a interface de caminhamento num iterador permite retirar esta interface da coleção, simplificando assim a interface desta coleção

Várias iterações podem estar ocorrendo ao mesmo tempo, já que o estado de uma iteração é mantido no iterador e não na coleção

Detalhes de implementação

Iteradores internos versus iteradores externos Com iterador interno, o cliente passa uma operação a ser desempenhada pelo

iterador e este o aplica a cada elemento Com iterador externo (mais flexíveis), o cliente usa a interface do iterador para

caminhar mas ele mesmo (o cliente) processa os elementos da coleção Um iterador interno só é usado quando um iterador externo seria difícil de

implementar Exemplo: para coleções complexas, manter o estado da iteração pode ser

difícil (teria que armazenar o caminho inteiro dentro de uma coleção recursiva multi-nível). Neste caso, usar um iterador interno recursivo e armazenar o estado na propria pilha de execução pode ser mais simples.

Tratamento de concorrência O que ocorre se houver mudanças à coleção (novos objetos ou objetos

removidos) durante uma iteração (devido a um thread)? Um "iterador fail-fast" indica imediatamente que está havendo acesso

concorrente (via exceção) Alguns iteradores podem clonar a coleção para caminhar, mas isto é caro em

geral Um "iterador robusto" permite fazer iterações e mudar a coleção sem se perder

Operadores do iterador Pode permitir ou não andar para trás, pular posições, etc.

Iteradores nulos são interessantes para prover condições limites Um iterador nulo sempre diz que a iteração acabou Eexemplo: se todo objeto de um Composite (ver à frente) tiver um iterador,

uma folha poderia ter um iterador nulo

Exemplo de código

O iterador do Vector em Java seria semelhante ao que segue abaixo

public Iterator iterator() { return new Iterator() { // classe interna anônima int cursor = 0; public boolean hasNext() { return cursor < size(); } public Object next() { try { Object next = get(cursor); cursor++; return next; } catch(IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } };

Page 3 of 4Iterator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\iterator.htm

Page 175: Apoo Jacques Ufcg

}

Pergunta final para discussão

Considere uma coleção (objeto composto) que contenha objetos representando empréstimos. A interface do objeto Empréstimo contém um método chamado ValorDoEmpréstimo() que retorna o valor corrente do empréstimo. Dado um requisito para extrair todos os empréstimos da coleção com valor menor que um limite (ou maior que um limite ou entre dois limites), você usaria ou escreveria um iterador para resolver o problema?

pat-4 programa anterior próxima

Page 4 of 4Iterator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\iterator.htm

Page 176: Apoo Jacques Ufcg

Composite

Um problema a resolver: editor de documentos

Para introduzir este padrão (e alguns outros), usaremos o exemplo do projeto de um editor de documentos WYSIWYG (What You See Is What You Get)

Semelhante a Word, por exemplo Outros exemplos do padrão Composite no Swing de Java

O editor pode misturar texto e gráficos usando várias opções de formatação A redor da área de edição estão os menus, scroll bars, barras de ferramentas, etc. O primeiro problema de design que queremos atacar é como representar a

estrutura do documento Essa estrutura afeta o resto da aplicação já que a edição, formatação, análise

textual, etc. deverão acessar a representação do documento Um documento é um arranjo de elementos gráficos básicos

Caracteres, linhas, polígonos e outras figuras O usuário normalmente não pensa em termos desses elementos gráficos mas em

termos de estruturas físicas Linhas, colunas, figuras, tabelas e outras sub-estruturas As sub-estruturas podem ser compostas de outras sub-estruturas, etc.

O usuário também pode pensar na estrutura lógica (frase, parágrafos, seções, etc.) Não vamos considerar isso aqui mas a solução que usaremos se aplica a esta

situação também A interface do usuário (UI) do editor deve permitir que o usuário manipule tais sub-

estruturas diretamente Por exemplo, o usuário pode tratar um diagrama como uma unidade em vez de

uma coleção de elementos gráficos primitivos O usuário deve manipular uma tabela como uma unidade e não como um

amontoado de texto e gráficos Para permitir tal manipulação, usaremos uma representação interna que case com

a estrutura física do documento Portanto, a representação interna deve suportar:

A manutenção da estrutura física do documento (o arranjo de texto e gráficos em linhas, colunas, tabelas, ...)

A geração e apresentação visual do documento Mapear posições da tela para elementos da representação interna. O editor vai

saber para o que o usuário está apontando Tem algumas outras restrições no projeto

Texto e gráficos devem ser tratados uniformemente A interface deve permitir embutir texto em gráficos e vice versa Um gráfico não deve ser tratado como caso especial de texto, nem texto

como caso especial de gráfico, senão teremos mecanismos redundantes de manipulação, formatação, etc.

A implementação não deve ter que diferenciar entre elementos únicos e grupos de elementos na representação interna

O editor deve tratar elementos simples e complexos de forma uniforme permitindo assim documentos arbitrariamente complexos

O décimo elemento da linha 5, coluna 2 pode ser um caractere único ou um diagrama complexo com muitos elementos

Page 1 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 177: Apoo Jacques Ufcg

Basta que o elemento saiba se desenhar, possa dar suas dimensões: ele pode ter qualquer complexidade

Por outro lado, queremos analisar o texto para verificar a grafia, hifenizar, etc. e não podemos verificar a grafia de gráficos ou hifenizá-las

Composição recursiva

Uma forma comum de representar informação estruturada hierarquicamente é através da Composição Recursiva

Permite construir elementos complexos a partir de elementos simples Aqui, a composição recursiva vai permitir compor um documento a partir de

elementos gráficos simples Começamos formando linhas a partir de elementos gráficos simples (caracteres

e gráficos) Múltiplas linhas formam colunas Múltiplas colunas formam páginas Múltiplas páginas formam documentos etc.

Podemos representar essa estrutura física usando um objeto para cada elemento Isso inclui elementos visíveis e elementos estruturais (linhas, colunas) A estrutura de objetos seria como abaixo

Page 2 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 178: Apoo Jacques Ufcg

Na prática, talvez um objeto não fosse usado para cada caractere por razões de eficiência

Podemos agora tratar texto e gráficos de forma uniforme Podemos ainda tratar elementos simples e compostos de forma uniforme Teremos que ter uma classe para cada tipo de objeto e essas classes terão que ter

a mesma interface (para ter uniformidade de tratamento) Uma forma de ter interfaces compatíveis é de usar herança

Definimos uma interface "ElementoDeDocumentoIF" e uma classe abstrata "ElementoDeDocumento" para todos os elementos que aparecem na estrutura de objetos

Suas subclasses definem elementos gráficos primitivos (caracteres e gráficos) e elementos estruturais (linhas, colunas, frames, páginas, documentos, ...)

Parte da hierarquia de classes segue abaixo

Page 3 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 179: Apoo Jacques Ufcg

Elementos de documentos têm três responsabilidades Sabem se desenhar (draw) Sabem o espaço que ocupam (limites) Conhecem seus filhos e pai

Subclasses de ElementoDeDocumento devem redefinir certas operações tais como draw()

Um ElementoDeDocumentoIF pai deve freqüentemente saber quanto espaço seus filhos ocupam para posicioná-los de forma a não haver sobreposição

Isso é feito com o método limites() que retorna o retângulo que contém o elemento

A operação intersecta() serve para saber se um ponto intersecta o elemento Usado quando o usuário clica com o mouse

A classe abstrata ElementoCompostoDeDocumento implementa certos métodos comuns através da aplicação sucessiva do método aos filhos

É o caso de intersecta()

Page 4 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 180: Apoo Jacques Ufcg

Todos os elementos têm uma mesma interface para gerenciar os filhos (inserir, remover, etc.)

Este padrão de projeto chama-se Composite e será discutido mais detalhadamente agora

O Padrão Composite

Objetivo

Compor objetos em estruturas em árvore para representar hierárquias Parte-Todo Composite permite que clientes tratem objetos individuais e composições

uniformemente

Participantes

Os nomes genéricos dados às classes abstratas são Component e Composite Os nomes genéricos dados às classes concretas são Leaf e ConcreteComposite

Page 5 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 181: Apoo Jacques Ufcg

Consequências do uso de Composite

Objetos complexos podem ser compostos de objetos mais simples recursivamente O cliente pode tratar objetos simples ou compostos da mesma forma: simplifica

o cliente Facilita a adição de novos componentes: o cliente não tem que mudar com a

adição de novos objetos (simples ou compostos) Do lado negativo, o projeto fica geral demais

É mais difícil restringir os componentes de um objeto composto Por exemplo, acima, podemos compor linhas com linhas ou com documentos,

etc. o que não faz sentido O sistema de tipagem da linguagem não ajuda a detectar composições erradas

Page 6 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 182: Apoo Jacques Ufcg

A solução é verificar em tempo de execução

Considerações de implementação

Adicionar referência ao pai de um objeto pode simplificar o caminhamento na estrutura

Onde adicionar a referência ao pai? Normalmente é colocada na classe abstrata Component

Exercício: colocar esta referência na figura acima As subclasses herdam a referência e os métodos que a gerenciam

Compartilhamento de componentes Útil para reduzir as necessidades de espaço Por exemplo, caracteres iguais poderiam compartilhar objetos Fazer isso complica se os componentes só puderem ter um único pai O padrão "flyweight" mostra como resolver a questão

Maximização da interface de Component Exercício para casa: certos livros colocam os métodos de gerenciamento de

filhos apenas na classe Composite porque uma folha não tem filhos! Você concorda ou discorda com a maximização da interface de Component? Por

quê? Em outras palavras, é melhor ter uma interface idêntica para folhas e Composite (transparência para o cliente) ou interfaces diferentes (segurança de não fazer besteiras como adicionar um filho a uma folha, o que seria capturado pelo compilador)?

Se mantivermos as interfaces de Component e Composite diferentes, como o cliente pode testar se um objeto é folha ou composto?

Onde são armazenados os filhos? Nós os colocamos em Composite mas eles poderiam ser colocados em

Component A desvantagem é a perda de espaço para essa referência para folhas

Quando os filhos devem ter um ordem especial, deve-se cuidar deste aspecto Usar um iterator é uma boa idéia

Cache de informação As classes Composite podem manter em cache informação sobre seus filhos de

forma a eliminar (curto-circuitar) o caminhamento ou pesquisa nos filhos Um exemplo: um Composite poderia manter em cache os limites do conjunto

de filhos de forma a não ter que recalcular isso sempre Quando um filho muda, a cache deve ser invalidada Neste caso, os filhos devem conhecer o pai para avisar da mudança

Como armazenar os filhos? Vector, LinkedList, HashMap (qualquer coleção razoável)

Uso do padrão na API Java: O pacote java.awt.swing

Usa o padrão Composite com a classe abstrata "Component" e o Composite sendo a classe "Container"

Folhas podem ser Label, TextField, Button Composites concretos são Panel, Frame, Dialog

Exemplo de código: um editor de documentos

Page 7 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 183: Apoo Jacques Ufcg

O diagrama de classes segue

interface ElementoDeDocumentoIF { ElementoDeDocumentoIF getPai(); /** * Retorna o font associado a este objeto. * Se não houver font, retorna o font do pai. * Se não houver pai, retorna null. */ Font getFont(); /** * Associa um font a este objeto. */ void setFont(Font font); /** * Retorna o número de glyphs que este objeto contém. */

Page 8 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 184: Apoo Jacques Ufcg

int getNumGlyph(); /** * Retorna o filho deste objeto na posição dada. */ ElementoDeDocumentoIF getFilho(int índice) throws ÉFolhaException; /** * Faça o ElementoDeDocumentoIF dado um filho deste objeto. */ void insereFilho(ElementoDeDocumentoIF filho) throws ÉFolhaException; /** * remove o ElementoDeDocumentoIF dado * da lista de filhos deste objeto. */ void removeFilho(ElementoDeDocumentoIF filho) throws ÉFolhaException; } // interface ElementoDeDocumentoIF abstract Class ElementoDeDocumento implements ElementoDeDocumentoIF { // Este é o font associado ao objeto // Se for nulo, o font é herdado do pai private Font font; // o container deste objeto ElementoDeDocumentoIF pai; ... public ElementoDeDocumentoIF getPai() { return pai; } public Font getFont() { if(font != null) { return font; } else if(pai != null) { return pai.getFont(); } else { return null; } } // getFont() public void setFont(Font font) { this.font = font; } // setFont() public abstract int getNumGlyph(); public ElementoDeDocumentoIF getFilho(int índice) throws ÉFolhaException { throw new ÉFolhaException("Folha não tem filhos"); } /** * Faça o ElementoDeDocumentoIF dado * um filho deste objeto. */ public void insereFilho(ElementoDeDocumentoIF filho) throws ÉFolhaException { throw new ÉFolhaException("Folha não tem filhos"); } /** * Remove o ElementoDeDocumentoIF dado * da lista de filhos deste objeto. */ public void removeFilho(ElementoDeDocumentoIF filho) {

Page 9 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 185: Apoo Jacques Ufcg

throws ÉFolhaException { throw new ÉFolhaException("Folha não tem filhos"); } } // class ElementoDeDocumento abstract class ElementoCompostoDeDocumento extends ElementoDeDocumento implements ElementoDeDocumentoIF { // Os filhos deste objeto private Collection filhos = new Vector(); // Valor em cache de getNumGlyph private int cacheNumGlyph; // Validade de cacheNumGlyph private boolean cacheValida = false; /** * Retorna o filho deste objeto na posição dada. */ public ElementoDeDocumentoIF getFilho(int índice) { return (ElementoDeDocumentoIF)filhos.get(índice); } // getFilho() /** * Faça o ElementoDeDocumentoIF dado * um filho deste objeto. */ public synchronized void insereFilho(ElementoDeDocumentoIF filho) { synchronized(filho) { filhos.add(filho); filho.pai = this; avisoDeMudança(); } // synchronized } // insereFilho() /** * Remove o ElementoDeDocumentoIF dado * da lista de filhos deste objeto. */ public synchronized void removefilho(ElementoDeDocumentoIF filho) { synchronized(filho) { if(this == filho.pai) { filho.pai = null; } filhos.remove(filho); avisoDeMudança(); } // synchronized } // removeFilho() ... /** * Uma chamada a esta função significa que um filho mudou, * o que invalida a cache de informação que o objeto mantém * sobre seus filhos. */ public void avisoDeMudança() { cacheValida = false; if(pai != null) { pai.avisoDeMudança(); } } // avisoDeMudança() /** * Retorna o número de glyphs que este objeto contém. */ public int getNumGlyph() { if(cacheValida) { return cacheNumGlyph; } cacheNumGlyph = 0; for(int i = 0; i < filhos.size(); i++) {

Page 10 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 186: Apoo Jacques Ufcg

ElementoDeDocumentoIF filho; filho = (ElementoDeDocumentoIF)filhos.get(i); cacheNumGlyph += filho.getNumGlyph(); } // for cacheValida = true; return cacheNumGlyph; } // getNumGlyph() } // class ElementoCompostoDeDocumento class Caractere extends ElementoDeDocumento implements ElementoDeDocumentoIF { ... /** * Retorna o número de glyphs que este objeto contém. */ public int getNumGlyph() { return 1; } // getNumGlyph() } // class Caractere class Imagem extends ElementoDeDocumento implements ElementoDeDocumentoIF { ... /** * Retorna o número de glyphs que este objeto contém. */ public int getNumGlyph() { return 1; } // getNumGlyph() } // class Imagem class Página extends ElementoCompostoDeDocumento { implements ElementoDeDocumentoIF { ... } // Página

Alguns comentários getFont() usa a informação de seu pai Um objeto composto usa uma cache para saber quantos glyphs compõem o

objeto synchronized é usado ao mexer com dados que podem ser compartilhados para

possibilitar uma implementação multi-threaded

Perguntas finais para discussão

De que forma o padrão Composite ajuda a consolidar lógica condicional espalhada no sistema (system-wide conditional logic)?

Você usaria o padrão Composite se não tivesse uma hierarquia parte-todo? Em outras palavras, se apenas alguns objetos têm filhos e quase todos os outros objetos de uma coleção são folhas (uma folha não tem filho), você ainda usaria o padrão Composite para modelar tais objetos?

pat-5 programa anterior próxima

Page 11 of 11Composite

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\composite.htm

Page 187: Apoo Jacques Ufcg

Strategy

Introdução

Vamos considerar o problema de formatação no editor de documentos WYSIWYG Já sabemos como é a representação da informação Mas ainda não sabemos como gerar um estrutura particular de linhas, colunas e

objetos simples para um documento particular Isso é resultado da formatação do documento

Para simplificar, formatação significa apenas quebra em linhas O resto da formatação pode ser tratado de forma análoga

Automatizar a formatação não é simples Há um trade-off entre velocidade de formatação e a qualidade resultante Muitas coisas devem ser consideradas tais como a "cor" de um documento (o

espalhamento uniforme de espaços em branco) Muitos algoritmos têm sido propostos e podem ser usados no editor

O algoritmo pode até mudar em tempo de execução Considere a formatação em word com "layout normal" (simples) e

"layout da página" (mais demorado mas mais WYSIWYG) Ponto importante: queremos manter o algoritmo de formatação isolado da

estrutura do documento Podemos adicionar elementos gráficos sem afetar o algoritmo de formatação Podemos mudar o algoritmo de formatação sem afetar o tratamento de

elementos de documento Isolaremos o algoritmo de formatação através de sua encapsulação num objeto Usaremos uma hierarquia de classes para objetos que encapsulam algoritmos de

formatação A raiz da hierarquia será uma classe com interface suficientemente genérica

para suportar uma larga gama de algoritmos Cada subclasse implementa a interface para um algoritmo particular

As classes Formatador e ElementosAFormatar

A classe Formatador é usada para objetos que encapsulam um algoritmo de formatação

As subclasses de Formatador implementam algoritmos de formatação específicos Os elementos a formatar são filhos de uma subclasse especial de

ElementoDeDocumento (ElementosAFormatar) Tem um único objeto da classe ElementosAFormatar ElementosAFormatar existe por dois motivos:

Para ser pai dos elementos básicos quando não tem formatação feita ainda Para manter referência ao formatador

Quando um objeto ElementosAFormatar é criado, ele cria uma instância de uma subclasse de Formatador, especializada em formatar de alguma forma

O objeto ElementosAFormatar pede ao formatador para formatar seus elementos quando necessário

Por exemplo, quando há uma mudança ao documento Ver a estrutura de classes abaixo

Page 1 of 6Strategy

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\strategy.htm

Page 188: Apoo Jacques Ufcg

Um objeto ElementosAFormatar não formatado contém apenas os elementos básicos visíveis (sem Composites linha, coluna, etc.)

Quando os ElementosAFormatar precisam de formatação, o objeto chama o formatador

O formatador varre os filhos de ElementosAFormatar e insere os elementos linha, coluna, etc. de acordo com o algoritmo de formatação

Ver resultado dos objetos abaixo

Page 2 of 6Strategy

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\strategy.htm

Page 189: Apoo Jacques Ufcg

Formatadores diferentes implementam algoritmos diferentes FormatadorSimples é o mais simples e rápido (não trata de "cor") e trata

apenas uma linha de cada vez FormatadorTeX é mais complexo pois considera o parágrafo inteiro para

distribuir os espaços em branco FormatadorArray coloca um número igual de elementos em cada linha (para

alinhar imagens, por exemplo) Resultado: a separação Formatador-ElementosAFormatar assegura uma separação

forte entre o código que suporta a estrutura do documento e o código de formatação

Podemos adicionar novos formatadores sem tocar nas classes de elementos e vice-versa

Podemos até mudar de formatador em tempo de execução com uma função setFormatador na classe ElementosAFormatar

O padrão que usamos chama-se Strategy

O padrão Strategy

Objetivo

Definir uma família de algoritmos, encapsular cada um, e torná-los intercambiáveis Strategy permite mudar os algoritmos independentemente dos clientes que os

usam

Também conhecido como

Policy

Quando usar o padrão Strategy?

Page 3 of 6Strategy

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\strategy.htm

Page 190: Apoo Jacques Ufcg

Várias classes relacionadas têm apenas comportamento diferente Você precisa de variantes de um algoritmo

Exemplo: com trade-offs diferentes de espaço-tempo Para esconder dos clientes os dados complexos que um algoritmo usa Uma classe tem vários comportamentos escolhidos com muitas decisões

Em vez de usar decisões, mova os trechos apropriados para sua própria classe Strategy

Estrutura genérica

Participantes

EstratégiaIF (exemplo: FormatadorIF) Declara a interface comum a todos os algoritmos O contexto usa essa interface para chamar o algoritmo definido em

EstratégiaConcreta Estratégia (exemplo: Formatador)

Possível classe abstrata para fatorar código comum entre os algoritmos EstratégiaConcreta (exemplo: FormatadorSimples)

Implementa o algoritmo usando a interface EstratégiaIF Contexto (exemplo: ElementosAFormatar)

É configurado com um objeto EstratégiaConcreta Mantém uma referência para um objeto EstratégiaIF Pode definir uma interface para que a estratégia acesse seus dados

Colaborações entre objetos

Page 4 of 6Strategy

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\strategy.htm

Page 191: Apoo Jacques Ufcg

O Contexto pode chamar a Estratégia passando a si mesmo para que a estratégia acesse os dados

O Contexto encaminha pedidos dos seus clientes para a Estratégia Clientes normalmente criam uma EstratégiaConcreta e a passam para o contexto

A partir daí, os clientes interagem apenas com o Contexto

Consequências do uso do padrão Strategy

Uma alternativa à herança Poder-se-ia usar herança (subclasses de Contexto) para fazer a mesma coisa

Teríamos uma hierarquia de ElementosAFormatar, cada um com um método formatar() diferente

Em tempo de execução, faríamos um new de alguma subclasse de ElementoAFormatar

Qual subclasse dependeria do algoritmo específico de formatação que se quer

O problema: como mudar o algoritmo formatar() em tempo de execução?? Teria que fazer "mutação" do objeto ElementoAFormatar1 para um novo

tipo ElementoAFormatar2 Mas a "mutação de tipo" é sinal de que o código fede!

As linguagens não dão suporte para isso Solução melhor: retirar o método formatar e criar um objeto a parte só para

ele Portanto, isso seria um mau exemplo do uso de herança

Acopla o Contexto com os algoritmos (parafusa o comportamento no Contexto)

Deixa o Contexto mais difícil de entender, manter e estender O algoritmo não poderia variar dinamicamente

Exemplo clássico de herança versus composição Estratégias eliminam statements condicionais

Quando vários comportamentos estão agrupados na mesma classe Código que tem muitas condições assim é candidato para o padrão Strategy

Ponto negativo: transparência incompleta dos 2 objetos Depois que o contexto é criado, os clientes enxergam apenas um objeto (o

contexto) e não dois (contexto e estratégia) Porém, no momento da criação do contexto, alguma estratégia deve ser

escolhida Os clientes devem portanto conhecer as estratégias antes de escolher uma Isso expõe os clientes a considerações de implementação Só usa Strategy quando a diferença de comportamento for relevante aos

clientes Ponto negativo: mais objetos no projeto

O padrão flyweight mostra como lidar com isso

Exemplo na API Java

Os Layout Managers de AWT são exemplos de classes que representam uma estratégia de layout para containers

A EstratégiaIF é LayoutManager

Page 5 of 6Strategy

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\strategy.htm

Page 192: Apoo Jacques Ufcg

também tem LayoutManager2 que é uma extensão de LayoutManager Não tem classe abstrata Estratégia Tem muitas classes concretas (GridLayout, FlowLayout, BorderLayout, ...) O Contexto pode ser qualquer Container (Panel, ScrollPane, Window, ...)

Perguntas finais para discussão

O que ocorre quando um sistema tem uma explosão de objetos de estratégia? Tem uma forma melhor de gerenciar essas estratégias?

Em Gamma, os autores descrevem duas formas pelas quais um objeto de estratégia pode obter a informação de que precisa para fazer seu trabalho. Uma forma descreve como um objeto de estratégia poderia receber uma referência a um objeto de contexto, permitindo assim o acesso aos dados de contexto. Mas não poderia ocorrer que os dados necessários à estratégia não estivessem disponíveis através da interface do objeto de contexto? Como remediar este possível problema?

pat-6 programa anterior próxima

Page 6 of 6Strategy

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\strategy.htm

Page 193: Apoo Jacques Ufcg

Decorator

Introdução

No editor de documentos WYSIWYG, vamos embelezar a interface do usuário (UI) Vamos adicionar uma borda à área de edição Vamos adicionar barras de rolagem (scroll bars)

Não vamos usar herança para adicionar este embelezamento Não poderíamos mudar o embelezamento em tempo de execução Para n tipos de embelezamento, precisaríamos de 2n-1 subclasses para ter todas as combinações

Teremos mais flexibilidade se outros objetos da UI não souberem que está havendo embelezamento!

Inclusão transparente

Usaremos composição em vez de herança evita os problemas mencionados, mas quais objetos devem participar da composição?

O embelezamento em si será um objeto (digamos uma instância da classe Borda) Isso nos dá dois objetos para fazer a composição: ElementoDeDocumento e Borda Devemos decidir agora quem vai compor quem A Borda pode conter o ElementoDeDocumento

Faz sentido já que a Borda engloba o ElementoDeDocumento na tela O ElementoDeDocumento pode conter a Borda

Isso implica em mudar a classe ElementoDeDocumento para que ela conheça a Borda

Usaremos a primeira escolha de forma a manter o código que trata bordas inteiramente na classe Borda sem mexer nas outras classes

Como construir a classe Borda? O fato da borda ter uma aparência na tela sugere que ela deveria ser uma

subclasse de ElementoDeDocumento Tem um outro motivo mais forte ainda de fazer isso: clientes tratam objetos

ElementoDeDocumento e não deveriam saber se um ElementoDeDocumento tem uma Borda ou não!

Clientes devem tratar ElementoDeDocumento uniformemente Se um cliente manda um ElementoDeDocumento sem Borda se desenhar

não vai aparecer borda, caso contrário, vai aparecer borda, mas o cliente não sabe

Isso implica que a Borda tem a mesma interface que ElementoDeDocumento Fazemos Borda uma subclasse de ElementoDeDocumento para garantir este

relacionamento Este conceito chama-se "Inclusão Transparente"

Composição com um único filho; e Interfaces compatíveis

Clientes não sabem se estão tratando do objeto original (ElementoDeDocumento) ou do seu incluidor (Borda)

O incluidor delega as operações para o objeto incluído, mas aumenta o comportamento fazendo seu trabalho antes ou depois da delegação da operação

A classe MonoElementoDeDocumento

Page 1 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 194: Apoo Jacques Ufcg

Definimos uma subclasse de ElementoDeDocumento chamada MonoElementoDeDocumento

MonoElementoDeDocumento é uma classe abstrata para todos os ElementoDeDocumento de embelezamento

MonoElementoDeDocumento armazena uma referência a um único ElementoDeDocumento (daí "mono") e encaminha todos os pedidos para ele

Isso é chamado Forwarding ou Delegação Isso faz com que MonoElementoDeDocumento seja completamente transparente

aos clientes A classe MonoElementoDeDocumento vai reimplementar pelo menos um dos

métodos de ElementoDeDocumento para fazer seu trabalho Exemplo: Borda redefine o método draw():

public class Borda extends MonoElementoDeDocumento { ... public void draw(Component c) { super.draw(c); drawBorda(c); } ...

Page 2 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 195: Apoo Jacques Ufcg

}

Observe que Borda estende o método do pai para desenhar a borda Já que chama o método do pai antes de fazer seu trabalho

A classe Rolador também é um embelezamento Ela desenha seu Componente em posições diferentes dependendo de duas

barras de rolagem Ela adiciona as barras de rolagem como embelezamento Ao desenhar seu Componente, Rolador pede ao sistema gráfico para fazer

"clipping" do Componente nos limites apropriados As partes fora dos limites não aparecerão

Agora, como adicionar uma Borda e um Rolador? Compomos os ElementosAFormatar dentro de um Rolador e este dentro de uma

Borda Se compuséssemos a Borda dentro do Rolador, a borda seria rolada

também Se isso for o comportamento desejado, essa ordem deve ser usada

A estrutura de objetos aparece abaixo

Page 3 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 196: Apoo Jacques Ufcg

Observe que os embelezadores compõem um único Componente Se tentássemos embelezar mais de uma coisa de cada vez, teríamos que misturar

vários tipos de ElementoDeDocumento com embelezadores Teríamos embelezamento de linha, embelezamento de coluna, etc. O jeito que fizemos parece melhor

Este padrão chama-se Decorator Embelezamento usando inclusão transparente Observe que o embelezamento pode, na realidade, ser qualquer adição de

responsabilidades e não um "embelezamento visual" Ex. embeleza uma árvore de sintaxe com ações semânticas Ex. embeleza uma máquina de estados finitos com novas transições

O padrão Decorator

Objetivo

Adicionar responsabilidades dinamicamente a um objeto Decoradores provêem uma alternativa flexível à herança para estender

funcionalidade

Page 4 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 197: Apoo Jacques Ufcg

Permitem adicionar responsabilidades a um objeto e não a uma classe inteira

Também chamado de

Wrapper

Quando usar o padrão Decorator?

Para adicionar responsabilidades dinamicamente a objetos individuais e transparentemente (sem afetar outros objetos)

Quando há responsabilidades que podem ser retiradas Quando herança geraria uma explosão de subclasses Quando a herança seria uma boa alternativa mas a definição da classe está

escondida ou não disponível para herança

Estrutura genérica

Participantes

ComponenteIF (ex. ElementoDeDocumentoIF)

Page 5 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 198: Apoo Jacques Ufcg

Define a interface de objetos que podem ter responsabilidades adicionadas dinamicamente

Componente (ex. ElementoDeDocumento) Possível classe abstrata para fatorar o código comum dos ComponenteConcreto

ComponenteConcreto (ex. ElementosAFormatar) Define um objeto ao qual se pode adicionar responsabilidades adicionais

Decorador (ex. MonoElementoDeDocumento) Mantém uma referência a um objeto ComponenteIF e define uma interface igual

à do Componente DecoradorConcreto (ex. Borda, Rolador)

Adiciona responsabilidades ao Componente

Colaborações entre objetos

O Decorador encaminha pedidos ao Componente Pode opcionalmente adicionar operações antes ou depois deste encaminhamento

Consequências do uso do padrão Decorator

Mais flexível do que herança estática Pode adicionar responsabilidades dinamicamente Pode até adicionar responsabilidades duas vezes! (ex. borda dupla)

Evita classes com features demais no topo da hierarquia Em vez de tentar prever todos os features numa classe complexa e

customizável, permite definir classes simples e adicionar funcionalidade de forma incremental com objetos decoradores

Desta forma, as aplicações não têm que pagar pelos features que não usam Ponto negativo: o Decorador e o objeto incluso não têm a mesma identidade

Portanto, cuidado com a identidade de objetos: um Decorador adiconado a um objeto vai mudar o objeto com o qual o cliente lida (em termos de identidade)

Ponto negativo: muitos pequenos objetos Fácil de customizar por programadores que entendem o projeto mas pode ser

difícil entender e depurar

Considerações de implementação

A interface do decorador deve ser igual à interface do objeto sendo decorado Se tiver que adicionar uma única responsabilidade, pode remover o decorador

abstrato Neste caso, o decorador concreto pode tratar do forwarding para o Componente

incluso Mantendo Componentes enxutos

A classe Componente deve ser mantida enxuta e os dados ser definidos nos Componentes concretos

Caso contrário, os decoradores (que herdam de Componente) ficam "pesados"

Decorator versus Strategy

Page 6 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 199: Apoo Jacques Ufcg

Decorator muda a "pele" de um objeto enquanto Strategy muda as "entranhas" Strategy é melhor quando a classe Componente é pesada

Neste caso, o decorador seria pesado demais Com Strategy, parte do comportamento de Componente é repassado para outro

objeto (que implementa um algoritmo) O Componente "sabe" da existência do(s) objeto(s) de estratégia mas não sabe

da existência de decoradores Exemplo: bordas com Strategy

O Componente pode mandar um objeto Borda (que ele conhece) desenhar a borda

O Componente pode manter uma lista de objetos de estratégia para fazer várias coisas, o que é equivalente a ter decoradores recursivos

Neste caso, o objeto Borda encapsula a estratégia de desenhar uma borda Ver a figura abaixo

Exemplo de código na API Java

Uso de scroll bars ScrollPane() é um decorador que contém um Component e adiciona barras de

rolagem Não usei Swing para poder mostrar o resultado num applet e vários browsers

ainda não suportam Swing Para Swing, a classe é um JScrollPane.

Exemplo de código segue:

import java.awt.*; import java.applet.*; public class Scroll extends Applet { public void init() { ScrollPane spane = new ScrollPane(); Button botaoGrande1 = new Button("Eu adoro Metodos Avançados de Programação!"); botaoGrande1.setFont(new Font("Serif", Font.ITALIC, 80)); Button botaoGrande2 = new Button("Eu adoro Metodos Avançados de Programação!"); botaoGrande2.setFont(new Font("Serif", Font.ITALIC, 80)); spane.add(botaoGrande1); add(botaoGrande2); // sem scroll bars add(spane); // com scroll bars }

Page 7 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 200: Apoo Jacques Ufcg

}

Applet roda aqui

Pergunta final para discussão

Na seção de implementação do Decorator Pattern, os autores (Gamma et al.) escrevem: A interface de um objeto decorador deve estar de acordo com a interface do Componente que ele decora. Agora, considere um objeto A decorado pelo objeto B. Haja vista que o objeto B decora o objeto A, o objeto B compartilha uma interface com o objeto A. Se algum cliente recebe uma instância do objeto decorado (B) e tenta chamar um método em B que não faça parte da interface de A, isto significa que o objeto B não é mais um decorador, no sentido estrito do padrão? Além do mais, porque é importante que a interface de um objeto decorador esteja de acordo com a interface do objeto que ele decora?

pat-7 programa anterior próxima

Page 8 of 8Decorator

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\decorator.htm

Page 201: Apoo Jacques Ufcg

Template Method

Um problema a resolver: login

Sua tarefa é de escrever uma classe para controlar o login de usuários numa aplicação

Tem dois caminhos básicos para resolver o problema: Escrever uma classe estanque para a aplicação sob consideração Escrever uma solução genérica para qualquer aplicação

Para promover o reuso A solução genérica seria um framework de login

Um esqueleto de login que seja comum a qualquer tarefa de login Ganchos para permitir que cada aplicação customize o processo de login

Quais são os passos genéricos de login? Prompt para o usuário fornecer sua identificação (ID) e senha Autenticação da ID e senha

O resultado da autenticação deve ser um objeto Este objeto pode encapsular qualquer informação que possa ser usada

adiante pela aplicação para comprovar a autenticação Aviso visual de progresso indicando que a autenticação está sendo realizada Um aviso de sucesso ao resto da aplicação que o login foi realizado e para

disponibilizar o objeto produzido pela autenticação A lógica das etapas 1 e 3 não muda A lógica das etapas 2 e 4 pode variar muito entre aplicações

Cada aplicação deverá prover seu próprio código Solução

Criar uma classe abstrata Login contendo: Um método principal (chamado Template Method) que capture a lógica

comum de login Métodos abstratos para representar as etapas do algoritmo que devem ser

fornecidas pela aplicação particular Estender a classe Login para prover implementações dos métodos abstratos

para uma aplicação particular (digamos para uma aplicação de DecisionSupportSystem)

Page 1 of 4Template Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\template.htm

Page 202: Apoo Jacques Ufcg

Chama-se o método login() de Template Method

O padrão Template Method

Objetivo

Define o esqueleto de um algoritmo numa operação, deixando que subclasses completem algumas das etapas.

O padrão Template Method permite que subclasses redefinem determinadas etapas de um algoritmo sem alterar a estrutura do algoritmo.

Resumo

Um Template Method define um algoritmo usando operações abstratas Subclasses fazem override das operações para prover um comportamento concreto Este padrão é a base para a construção de frameworks

Quando usar o padrão Template Method?

Para implementar partes invariantes de um algoritmo uma única vez e deixar subclasses implementarem o comportamento variável

Quando comportamento comum entre subclasses deveria ser fatorado e localizado numa classe comum para evitar duplicação

É um passo frequente de "refactoring" de código Primeiro identifique as diferenças Coloque as diferenças em novos métodos Substitua o código das diferenças por uma chamada a um dos novos

métodos Para controlar extensões de subclasses

Você pode definir um Template Method que chame operações-gancho (hook) e pontos específicos, permitindo extensões apenas nestes pontos

Faça com que apenas os métodos-gancho possam sofrer override, usando adjetivos de visibilidade

Page 2 of 4Template Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\template.htm

Page 203: Apoo Jacques Ufcg

"public final" para o Template Method "protected" para métodos que devem/podem sofrer override

Estrutura genérica

Participantes

ClasseAbstrata (Login) Define operações abstratas que subclasses concretas definem para implementar

certas etapas do algoritmo Implementa um Template Method definindo o esqueleto de um algoritmo

O Template Method chama várias operações, entre as quais as operações abstratas da classe

ClasseConcreta (LoginDecisionSupportSystem) Implementa as operações abstratas para desempenhar as etapas do algoritmo

que tenham comportamento específico a esta subclasse

Colaborações

ClasseConcreta depende de ClasseAbstrata para implementar as partes invariantes do algoritmo

Consequências do padrão Template Method

Template Methods constituem uma das técnicas básicas de reuso de código São particularmente importantes em frameworks e bibliotecas de classes para o

fatoramento de comportamento comum Template Methods levam a uma inversão de controle

O código particular de uma aplicação é chamado pelo resto do código Normalmente, escrevemos o código "de cima" e chamamos partes comuns "em

baixo" Aqui, é o contrário

Page 3 of 4Template Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\template.htm

Page 204: Apoo Jacques Ufcg

Também chamado de "Hollywood Principle" "Don't call us, we'll call you"

O Template Method pode chamar vários tipos de operações Operações concretas (da ClasseConcreta ou de outras classes) Operações concretas de ClasseAbstrata (operações comuns úteis às subclasses) Operações abstratas (onde o comportamento varia)

Devem sofrer override Factory Methods Operações-gancho

Podem sofrer override Uma operação-gancho tem implementação nula (fazendo nada) na

ClasseAbstrata A subclasse pode fazer override para inserir algo neste ponto (daí,

"gancho") É uma forma limpa de estender o comportamento de uma classe de forma

controlada Isto é, apenas nos pontos onde há ganchos

Considerações de implementação

É importante minimizar o número de operações abstratas que devem sofrer override para completar o algoritmo

Motivo: simplificação para não chatear o programador Convenções de nome

Métodos abstratos que devem sofrer override deveriam ter algo de comum no nome

Exemplo: doXpto() // começa com "do" Métodos-gancho que podem sofrer override deveriam ter algo de comum no

nome Exemplo: logHook() // termina com "Hook"

Pergunta final para discussão

O Template Method funciona com herança. Seria possível obter a mesma funcionalidade da Template Method usando composição de objetos? Quais seriam alguns dos tradeoffs?

Suponha que um framework tenha uma classe X contendo um ou mais template methods. Os criadores de objetos da classe X são objetos da classe C. O framework é completado com subclasses de X, digamos X'. De que forma seria possível que objetos da classe X' fossem criados pelo framework, sem que o programador tenha o código fonte do framework (isto é, sem o código fonte da classe C)?

pat-8 programa anterior próxima

Page 4 of 4Template Method

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\template.htm

Page 205: Apoo Jacques Ufcg

Observer Não vamos seguir a apresentação do livro GoF aqui, pois há críticas sobre a

solução dada Falaremos das críticas à frente

Seguiremos a apresentação dada por Bill Venners em http://www.javaworld.com/topicalindex/jw-ti-techniques.html (The 'event generator' idiom)

Em particular, apresentaremos como este padrão é implementado em Java Portanto, além de um Design Pattern (que não depende de linguagem),

apresentaremos um "Idioma Java" que mostra como implementar um Design Pattern numa linguagem particular

Objetivo

O padrão Observer permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto

O objeto sendo observado é chamado de: "Subject" (GoF) "Observable" (java.util) "Source" ou "Event Source" (java.swing e java.beans) Provedor de informação (Bill Venners) Gerador de eventos (Bill Venners)

O objeto que observa é chamado de Observer (GoF e java.util) Listener (java.swing)

Java usa este padrão em 2 lugares mas de formas diferentes! A forma java.util não é boa (ver críticas adiante)

Usaremos as palavras Source e Listener

Também chamado de

Event Generator, Dependents, Publisher-Subscriber

Exemplo

Como projetar um sistema que modele um telefone e todos os objetos que poderiam estar interessados quando ele toca?

Os objetos interessados poderiam ser: Pessoas que estejam perto (na mesma sala) Uma secretária eletrônica Um FAX Até um dispositivo de escuta clandestina :-)

Os objetos interessados podem mudar dinamicamente Pessoas entram e saem da sala onde o telefone está Secretárias eletrônicas, FAX, etc. podem ser adicionados ou removidos durante

a execução do programa Novos dispositivos poderão ser inventados e adicionados em versões futuras do

programa Qual é a solução básica de projeto?

Faça do telefone um Event Source

Page 1 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 206: Apoo Jacques Ufcg

O problema

Em Java, um objeto (o Source) envia informação para outro objeto (o Listener) pela chamada de um método do Listener

Mas, para que isso seja possível: O Source deve ter uma referência ao Listener O tipo desta referência deve ser uma classe ou interface que declare ou herde o

método a chamar Fazer com que o tipo da referência seja a classe (concreta) do Listener não

funciona bem, porque: O número e tipos dos Listeners não é conhecido em tempo de compilação Os vários listeners poderão não fazer parte de uma mesma hierarquia de

objetos Não queremos criar um acoplamento forte entre Source e Listeners

A solução vai se basear primordialmente em interfaces para resolver o problema Aliás, este é um excelente exemplo do poder de interfaces para prover

polimorfismo envolvendo classes não relacionadas por herança (de implementação)

A solução idiomática em Java

Etapa 1: Definir classes de categorias de eventos Defina uma classe separada de evento para cada categoria principal de eventos

que poderão ser gerados pelo Source Faça com que cada classe de eventos estenda java.util.EventObject Faça com que cada classe encapsule a informação a ser propagada para os

Listeners Use nomes de classe que terminem em Event (exemplo: TelefoneEvent)

Etapa 2: Define interfaces de Listener Para cada categoria de eventos, defina uma interface que estenda

java.util.EventListener e que contenha um método para cada evento (da categoria) que vai gatilhar a propagação de informação do Source para os Listeners

Chame a interface como chamou a classe de eventos, substituindo Event por Listener

Exemplo: Para a classe TelefoneEvent, a interface de Listener seria TelefoneListener

Dê nomes aos métodos da interface para descrever a situação que causou o evento. Use um verbo no pretérito

Exemplo: método TelefoneTocou Cada método deve retornar void e aceitar um parâmetro, uma referência a uma

instância da classe de eventos apropriada Exemplo de uma assinatura completa:

void telefoneTocou(TelefoneEvent e);

Etapa 3: Define classes de adaptação (opcional) Observação:

É muito comum querer uma classe que implemente uma interface fazendo nada para a maioria dos métodos e fazendo algo útil apenas para alguns poucos métodos

Page 2 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 207: Apoo Jacques Ufcg

Para ajudar o programador, é comum, em Java, criar uma classe "adapter" que implemente todos os métodos de uma interface com métodos que nada fazem

As classes que devem implementar a interface podem herdar do adapter e fazer override de alguns poucos métodos

Para cada interface de Listener que contenha mais do que um método, defina uma classe adapter que implemente a interface por inteiro com métodos que nada fazem

Dê um nome à classe substituindo Listener com Adapter Exemplo, para a interface TelefoneListener, a classe seria TelefoneAdapter

Etapa 4: Defina a classe observável Source Para cada categoria de eventos que serão propagados a partir de instâncias desta

classe, define um par de métodos para adicionar/remover Listeners Chame os métodos add<nome-da-interface-listener> e remove<nome-da-

interface-listener> Exemplo: addTelefoneListener() e removeTelefoneListener()

Para cada método em cada interface de Listener, define um método privado de propagação de eventos. O método não aceita parâmetros e retorna void. Este método propaga o evento para os Listeners

Chame o método dispara<nome-do-método-listener> Exemplo: disparaTelefoneTocou()

Chamadas ao método de disparo de eventos devem ser adicionas em lugares apropriados da classe Source

Nos lugares onde há mudança de estado ou ocorrência de outros eventos interessantes

Etapa 5: Defina objetos Listener Para ser um Listener de uma certa categoria de eventos, basta implementar a

interface de Listener da categoria de eventos Isso é normalmente feito estendendo a classe Adapter

Estrutura

Page 3 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 208: Apoo Jacques Ufcg

Exemplo de código

No arquivo TelefoneEvent.java:

public class TelefoneEvent extends java.util.EventObject { public TelefoneEvent(Telefone source) { super(source); } }

Observe que source é passado como parâmetro e armazenado no objeto (super(source) faz isso)

Isso permite que quem recebe o evento faça java.util.EventObject.getSource() para saber qual objeto gerou o evento

Permite que um mesmo objeto seja Listener de vários objetos Source Também permite que, com esta referência ao Source, o Listener acione outros

métodos do objeto para obter informação Chama-se este modelo de "Pull model" No "Push model", toda a informação necessária está presente dentro do

evento Por simplicidade, não se está encapsulando dados no evento aqui mas seria

possível incluir: O número de telefone que está chamando A data e as horas

No arquivo TelefoneListener.java (interface de Listener):

Page 4 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 209: Apoo Jacques Ufcg

public interface TelefoneListener extends java.util.EventListener { void telefoneTocou(TelefoneEvent e); void telefoneAtendido(TelefoneEvent e); }

No arquivo TelefoneAdapter.java (classe Adapter):

public class TelefoneAdapter implements TelefoneListener { void telefoneTocou(TelefoneEvent e) { } void telefoneAtendido(TelefoneEvent e) { } }

A definição do source fica no arquivo Telefone.java:

import java.util.*; public class Telefone { private Collection telefoneListeners = new Vector(); public void tocaFone() { disparaTelefoneTocou(); } public void atendeFone() { disparaTelefoneAtendido(); } public synchronized void addTelefoneListener( TelefoneListener l) { if (telefoneListeners.contains(l)) { return; } telefoneListeners.add(l); } public synchronized void removeTelefoneListener(TelefoneListener l) { telefoneListeners.remove(l); } private void disparaTelefoneTocou() { Collection tl; synchronized (this) { // A interface Collection não tem clone() // mas a classe AbstractCollection tem. // Clonar para evitar problemas de sincronização // durante a propagação tl = ((AbstractCollection)telefoneListeners).clone(); } Iterator it = tl.iterator(); if(!it.hasNext()) { return; } TelefoneEvent evento = new TelefoneEvent(this); while(it.hasNext()) { ((TelefoneListener)(it.next())).telefoneTocou(evento); } }

Page 5 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 210: Apoo Jacques Ufcg

// disparaTelefoneAtendido() é semelhante a disparaTelefoneTocou() // Exercício: Que design pattern poderia ser usado para fatorar // o código comum? private void disparaTelefoneAtendido() { Collection tl; synchronized (this) { tl = ((AbstractCollection)telefoneListeners).clone(); } Iterator it = tl.iterator(); if(!it.hasNext()) { return; } TelefoneEvent evento = new TelefoneEvent(this); while(it.hasNext()) { ((TelefoneListener)(it.next())).telefoneAtendido(evento); } } }

Também seria possível usar o Infobus de Java para propagar os eventos Agora, precisamos de classes para usar o esquema acima Primeiro, os Listeners No arquivo SecretariaEletronica.java, temos:

public class SecretariaEletronica implements TelefoneListener { public void telefoneTocou(TelefoneEvent e) { System.out.println("Secretaria escuta o telefone tocando."); } public void telefoneAtendido(TelefoneEvent e) { System.out.println("Secretaria sabe que o telefone foi atendido."); } }

No arquivo Pessoa.java

public class Pessoa { public void escutaTelefone(Telefone t) { t.addTelefoneListener( new TelefoneAdapter() { public void telefoneTocou(TelefoneEvent e) { System.out.println("Eu pego!"); ((Telefone)(e.getSource())).atendeFone(); } } ); } }

Observe que a SecretariaEletronica implementa a interface TelefoneListener diretamente, sem usar TelefoneAdapter

Por outro lado, o objeto Pessoa instancia uma "inner class" anônima que estende TelefoneAdapter e faz override apenas do método que interessa (TelefoneTocou())

Quisemos apenas mostrar formas diferentes de implementar a interface TelefoneListener

Finalmente, precisamos de uma aplicação (arquivo ExemploFone.java)

public class ExemploFone { public static void main(String[] args) { Telefone fone = new Telefone(); Pessoa fulano = new Pessoa(); SecretariaEletronica se = new SecretariaEletronica();

Page 6 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 211: Apoo Jacques Ufcg

fone.addTelefoneListener(se); fulano.escutaTelefone(fone); fone.tocaFone(); // começa a brincadeira } }

A execução de ExemploFone imprime:

Secretaria escuta o telefone tocando. Eu pego! Secretaria sabe que o telefone foi atendido.

Quando usar o padrão Observer?

Quando uma abstração tem dois aspectos, um dependente do outro. Encapsular tais aspectos em objetos separados permite que variem e sejam reusados separadamente

Quando uma mudança a um objeto requer mudanças a outros e você não sabe quantos outros objetos devem mudar

Quando um objeto deve ser capaz de avisar outros sem fazer suposições sobre quem são os objetos. Em outras palavras, sem criar um acoplamento forte entre os objetos

Consequências do uso do padrão

Permite que se varie objetos Source e Listeners independentemente Pode-se reusar objetos Source sem reusar seus Listeners e vice-versa Pode-se adicionar Listeners sem modificar o Source ou os outros Listeners

O acoplamento entre Source e Listeners é mínimo Basta que os Listeners implementem uma interface simples Os objetos involvidos poderiam até pertencer a camadas diferentes de software

Suporte para comunicação em broadcast O Source faz broadcast do aviso. Os Listeners podem fazer o que quiserem com

o aviso, incluindo ignorá-lo Do lado negativo: o custo de uma mudança ao estado de um Source pode ser

grande se houver muitos Listeners

Considerações de implementação

Um Listener pode estar cadastrado junto a vários objetos Source Ele pode descobrir quem o esta notificando se o objeto evento contiver uma

referência ao source (como temos no idioma Java) Quem dispara o evento original?

Se cada método que muda o estado do Source disparar um evento, pode haver eventos demais se houver mudanças de estado demais

Neste caso, pode-se deixar um método público do Source que clientes ativam para disparar um evento depois que todas as mudanças ao estado forem feitas

O problema é que o cliente pode "esquecer" de chamar este método Assegurar a consistência do estado do objeto antes de disparar o evento

Particularmente perigoso se um método do Source fizer:

super(novoValor); // Pai dispara o evento

Page 7 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 212: Apoo Jacques Ufcg

var = novoValor; // atualiza estado do objeto (é tarde!)

Diferenças entre modelos Push e Pull O modelo Pull acopla os objetos menos pois o modelo Push supõe que o Source

sabe das necessidades de informação dos Listeners O modelo Push pode ser mais eficiente pois o Source pode indicar o que mudou

dentro do evento, facilitando a vida para que os listeners saibam o que mudou Usar eventos diferentes para cada situação pode resolver o problema

Cadastro de interesses Pode-se mudar o protocolo de cadastro (Subscribe) para que o Listener indique

as coisas que o interessam

Críticas sobre outras soluções do mesmo padrão

Gamma apresenta este padrão de uma forma um pouco diferente e menos interessante

Esta forma (fraca) do padrão Observer também é usada nas classes Observer/Observable de java.util

Esses dois exemplos são mais fracos do que o apresentado aqui (baseado no Java Swing) pelos seguintes motivos:

Observable é uma classe da qual você deve herdar para fazer seu objeto um Source

Java não tem herança múltipla e isso queima o (único) cartucho de herança Usar interfaces (herança de tipo) em vez de herança de implementação é

melhor Para implementar um Observer (equivalente a Listener), você tem que

implementar a interface Observer que tem um único método update(Observable, Object)

A solução acima é muito melhor pois podemos ter vários eventos, e vários métodos associados, o que torna o código mais claro

Você prefere entrar no código do método para descobrir que ele tratar de um telefone que está tocando ou é melhor chamar o método telefoneTocou() como fizemos??

A solução acima permite descobrir mais facilmente o que mudou no estado do Source pois podemos usar vários eventos.

De forma geral, o Observer/Observable do Java não é bem visto hoje

Perguntas finais para discussão

O design clássico Model-View-Controller é explicado na nota de implementação #8: Encapsulamento de semântica complexa de de atualização. Poderia fazer sentido às vezes um Observer (ou View) falar diretamente com o Subject (ou Model)?

Quais são as propriedades de um sistema que usa o padrão Observer muito? Como fazer para depurar código em tal sistema?

Como tratar o problema de concorrência com este padrão? Considere, por exemplo, uma mensagem Unregister() sendo enviada para um objeto antes que este envie uma mensagem Notify() para o Gerente de Mudança (ou Controlador).

Examine a tecnologia Infobus do Java e relacione-a com o padrão Observer.

pat-10 programa anterior próxima

Page 8 of 8Observer

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\observer.htm

Page 213: Apoo Jacques Ufcg

Comentários finais sobre Design Patterns

Como selecionar um Design Pattern?

Considerando como Design Patterns resolvem Problemas de Design

Vimos aqui uma lista de situações que forçam um redesign Listamos novamente os problemas juntamente com os Design Patterns que ajudam

a resolvê-los Criar um objeto especificando sua classe explicitamente

Abstract Factory, Factory Method, Prototype Dependência de operações específicas

Chain of Responsibility, Command Dependência de plataformas de hardware ou software específicas

Abstract Factory, Bridge Dependência da representação ou implementação de objetos

Abstract Factory, Bridge, Memento, Proxy Dependências algorítmicas

Builder, Iterator, Strategy, Template Method, Visitor Acoplamento forte

Abstract Factory, Bridge, Chain of Responsibility, Command, Façade, Mediator, Observer

Extensão de funcionalidade através da herança Bridge, Chain of Responsibility, Composite, Decorator, Observer, Strategy

Dificuldade de alterar classes convenientemente Adapter, Decorator, Visitor

Examinando os Objetivos de cada Pattern

Veja a lista de todos os objetivos aqui

Estudando o relacionamento entre Design Patterns

Ver figura abaixo

Page 1 of 3Comentários finais sobre Design Patterns

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\comentarios.htm

Page 214: Apoo Jacques Ufcg

Examinando no livro da GoF as semelhanças e diferenças entre padrões

Ver o final da apresentação de cada padrão Ver a introdução aos 3 capítulos do catálogo

Há uma discussão das semelhanças

Considerando o que deve ser variável do Design

Em vez de verificar as causas de redesign, podemos fazer o contrário e verificar o que gostaríamos que fosse modificável sem redesign

O importante aqui é Encapsular o conceito que varia

Page 2 of 3Comentários finais sobre Design Patterns

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\comentarios.htm

Page 215: Apoo Jacques Ufcg

Ver tabela abaixo

Finalmente ... O que esperar de Design Patterns Um vocabulário comum de Design

"Vamos usar um Observer aqui ..." Ajuda no entendimento de software existente

Desde que se especifique os Design Patterns usados Patterns farão de você um projetista melhor Um alvo para Refactoring

Mais sobre isso aqui Consiste na reorganização de software existente para melhorar sua qualidade

pat-11 programa anterior

Propósito Design PatternAspecto(s) que varia(m)

(O que pode mudar sem redesign)

Criação

Abstract Factory Famílias de objetos-produto

Builder Como um objeto composto é criado

Factory Method Subclasse do objeto que é instanciado

Prototype A classe do objeto que é instanciado

Singleton A única instância de uma classe

Estrutura

Adapter A interface para acessar um objeto

Bridge A implementação de um objeto

Composite A estrutura e composição de um objeto

Decorator As responsabilidades de um objeto (sem uso de herança)

Façade A interface de um subsistema

Flyweight O custo de armazenamento de objetos

Proxy Como um objeto é acessado; sua localização

Comportamento

Chain of Responsibility O objeto que pode atender a um pedido

Command Quando e como um pedido é atendido

Interpreter Gramática e interpretação de uma linguagem

Iterator Como os elementos de uma coleção são acessados, varridos

Mediator Como e quais objetos interagem uns com os outros

Memento Qual informação privada é armazenada fora de um objeto, e quando

Observer O número de objetos que dependem de um outro objeto; como os objetos dependentes ficam atualizados

State Os estados de um objeto

Strategy Um algoritmo

Template Method Certas etapas de um algoritmo

Visitor Operações que podem ser aplicadas a objetos sem mudar suas classes

Page 3 of 3Comentários finais sobre Design Patterns

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\pat\comentarios.htm

Page 216: Apoo Jacques Ufcg

8. Tópicos Avançados Refactoring Extreme Programming Frameworks Componentes

etc programa

Page 1 of 18. Tópicos Avançados

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\etc\index.htm

Page 217: Apoo Jacques Ufcg

Refactoring

Introdução

Entropia de software Programas começam num estado bonito, bem projetados mas, com tempo, as

sucessivas adições e mudanças fazem o programa perder sua estrutura Resultado final: espaguete

Motivos Programa muda em formas não previstas Programa não é perfeitamente entendido (mesmo sendo nosso!) e o enxerto é

menos perfeito do que poderia ser Pressões de tempo Seria melhor reprojetar o sistema para limpá-lo, mas preferimos empurrar com

a barriga Tem um excelente livro de Fowler sobre Refactoring

Refactoring

Refactoring é um termo usado para descrever técnicas que diminuem a dor de reprojetar

Mudanças feitas a um programa que alteram apenas sua organização, não sua funcionalidade

Transformações que preservam o comportamento

Por que refactoring é importante?

A única defesa contra a entropia de software Para consertar "bugs" de reusabilidade Permite adicionar padrões de projeto após escrever o programa Permite transformar um programa num framework Deixa você pensar na generalidade amanhã!

Hoje: basta deixar funcionando Parece algo estranho a dizer, mas veremos que a turma do extreme

programming acredita nisso piamente! Necessário para software bonito

Problemas que refactoring pode resolver

Código duplicado Elimina duplicação com novos métodos, novos objetos, movendo coisas comuns

numa superclasse Métodos longos

Métodos devem ser coesos (ser longo é dica de que não está coeso) Métodos devem caber numa tela Métodos devem ser do mesmo nível de abstração Métodos devem estar na classe correta

Acoplamento forte demais Longas listas de parâmetros

Encapsula num objeto Muda o método para acessar o objeto

Page 1 of 2Refactoring

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\etc\refactoring.htm

Page 218: Apoo Jacques Ufcg

Vê o que mais deveria estar no objeto switch e variáveis "tipo-de-objeto"

Mudar para polimorfismo Introduzir interfaces e aumentar o polimorfismo

Como fazer refactoring?

Não faça refactoring e adição de funcionalidade ao mesmo tempo Tenha testes automáticos prontos antes de fazer refactoring Faça mudanças muito pequenas de cada vez e teste, teste, teste

Quando fazer refactoring?

Quando parece difícil de enxertar nova funcionalidade Se uma nova funcionalidade adicionou código feio Quando você não aguenta olhar para seu próprio código!

etc-1 programa próxima

Page 2 of 2Refactoring

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\etc\refactoring.htm

Page 219: Apoo Jacques Ufcg

Extreme Programming (XP)

Introdução

Alguns super-programadores (e irreverentes!) de smalltalk decidiram criar um processo simples de desenvolvimento de software

Talvez achando que os outros processos eram complexos?!? Ward Cunningham, Ron Jeffries, Martin Fowler, Kent Beck

Cunningham e Beck são a turma do cartão CRC Cuidado! XP foi testado para times pequenos e talvez requeira excelentes

programadores. Não se sabe a aplicabilidade geral da técnica Não é para qualquer um, mas pode ter resultado impressionantes

Muita informação aqui sobre isso. Vale a pena conferir. Também tem um excelente livro de Beck

Extreme Programming

Alegação básica: software é difícil demais para gastar tempo com coisas que não são importantes

Então, o que é importante? Codificar: se, no final do dia, o programa não funciona e não ajuda o cliente a

ganhar dinheiro, você não fez nada Testar: você tem que saber quando terminou. Os testes dizem isso. Se você for

inteligente, vai escrevê-los primeiro para saber instantaneamente quando você terminou

Escutar: tem que saber qual é o problema a resolver. Escute clientes, gerentes e pessoas do negócio

Refatorar: você tem que escutar o que o programa está dizendo para você sobre sua própria estrutura e colocar este conhecimento de volta no programa

Se alguém falar para você que fazer software é outra coisa (além de codificar, testar, escutar, refatorar), ele está tentando lhe vender algo

Não falei que eram irreverentes?! Por isso, inventaram uma disciplina de desenvolvimento de software (xp) baseada

nos seguintes valores: Simplicidade Comunicação Feedback Agressividade

As práticas de XP foram definidas para balancear as forças agindo no projeto

Resumo do processo (com links para o wiki)

Planejamento feito com o PlanningGame Autoridade é delegada para os clientes definirem os requisitos usando

UserStories (parecem Use Cases) Autoridade é delegada para os clientes estabelecerem as prioridades de

desenvolvimento das estórias Desta forma, o cliente pode maximizar o business value

(BusinessValueFirst) Autoridade é delegada para os desenvolvedores estimarem quanto tempo cada

estória levará para ser desenvolvida

Page 1 of 3Extreme Programming

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\etc\xp.htm

Page 220: Apoo Jacques Ufcg

Esta delegação de autoridade (que é rara!) provê um ambiente de desenvolvimento livre de estresse

Os clientes possuem boa informação sobre quanto tempo as coisas levam e podem portanto maximizar o custo-benefício das estórias que são desenvolvidas primeiro

Os desenvolvedores pouco se importam com as funcionalidades pedidas (o que também é raro!), porque eles estimam quanto tempo as coisas levam

Já que delegar as prioridades para o cliente pode ser perigoso em alguns casos (pedir algo fundamental mas difícil no fim do projeto é perigoso!), há uma regra que balanceia as coisas: as piores coisas são atacadas primeiro (WorstThingsFirst)

Semelhante ao processo unificado "risk-confronting" O trabalho é acompanhado através de um cronograma (CommitmentSchedule)

revisado a cada poucas iterações Para avaliar novos riscos e oportunidades

As iterações são planejadas (IterationPlanning) entre desenvolvedores e clientes Nada é feito que não seja imediatamente útil e necessário para não impactar os

prazos de desenvolvimento (YouArentGonnaNeedIt) Eles não acreditam em pensar muito no futuro para se preparar para o que vem

depois Faça funcionar o UserStory de hoje!

A simplicidade sempre reina: só se usa a solução mais simples que satisfaça os requisitos do problema (DoTheSimplestThingThatCouldPossiblyWork)

As duas regras acima (YouArentGonnaNeedIt e DoTheSimplestThingThatCouldPossiblyWork) acabam gerando código que precisa ser alterado às vezes. Para simplificar a manutenção/evolução, o código tem que estar sempre limpo e não duplicado. A regra é refatorar impiedosamente (RefactorMercilessly).

Práticas de XP

Para terminar esta introdução, eis a lista de práticas de XP (leia cada uma dessas práticas no wiki e resuma cada uma em uma frase nas suas próprias palavras)

DoTheSimplestThingThatCouldPossiblyWork encoraja não sobre-projetar (nem sub-projetar)

AskTheCode porque ele sabe (... dizer que precisa ser refatorado, ... dizer onde está o bug, ...)

UnitTests: essa turma testa, testa, testa ... para não quebrar o código um do outro. Unit testes são escritos para cada classe e testados usando o TestingFramework. Testes de unidade pertencem ao desenvolvedor.

FunctionalTests para testar as estórias e saber se as necessidades do usuário estão sendo atingidas. Os usuários forneceram os dados usados nestes testes. Testes funcionais pertencem ao cliente.

ContinuousIntegration gerando um processo iterativo para evitar IntegrationHell. A integração de uma nova versão de algo (mesmo pequeno) é quase instantânea, logo depois dos testes.

ContinuousIntegrationRelentlessTesting (como acima, mas lembrando que tem que testar, testar e testar)

RefactorMercilessly para manter o código limpo e o progresso rápido (ver também WikiPagesAboutRefactoring). Só funciona bem se tiver muitos testes para se assegurar de que não quebrou nada.

Recomenda-se chegar à ExtremeNormalForm "Your classes are small and your methods are small; you've said everything

OnceAndOnlyOnce and you've removed the last piece of unnecessary code. Somewhere far away an aikido master stands in a quiet room. he is centered.. aware.. ready for anything.

Page 2 of 3Extreme Programming

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\etc\xp.htm

Page 221: Apoo Jacques Ufcg

Outside a sprinter shakes out her legs and settles into the block, waiting for the crack of the gun while a cool wind arches across the track. Ssoftly, a bell sounds.. all of your tests have passed. Your code is in ExtremeNormalForm... tuned to today and poised to strike at tomorrow."

ProgrammingInPairs provê qualidade mais alta, treinamento mútuo e velocidade mais alta. Use uma pessoa menos experiente no teclado e uma mais experiente junto.

SpikeSolution soluções exploratórias rápidas para certos problemas ModelFirst mais SpartanUserInterface ajudam a manter o foco nas necessidades do

usuário. SpartanUserInterface significa fazer uma interface simples e deixar o usuário usar, melhorar o que atrapalha, jogar fora o que não é usado até que o resultado satisfaça.

ExtremePlanning bolar um mapa rápido da solução global com refinamentos incrementais

PlanningGame para formalizar os papeis e responsabilidades no planejamento CountDownToRelease discute como usar ExtremePlanning quando a data de

release final se aproxima. As regras: Deixa o cliente decidir o que falta até soltar o produto Reunião semanal para tratar de IterationPlan StandupMeeting diário rápido

ExtremeReuse adotando software de terceiros e adequando-o a XP pela construção de testes

TossIt para fazer e manter projetos magros, jogue o que não parece útil pela janela. Não precisa ser mantido, documentado, etc.

SystemMetaphor formas de comunicar o sistema para outros e os próprios desenvolvedores. Outras palavras para arquitetura

Pouca coisa: algumas classes, alguns padrões, ... XpDesign quem projeta em XP e quando?

Solução: o time (pequeno) inteiro usando CRC ExtremeDocuments documentação faz parte, embora ela seja diferente às vezes

Para requisitos: UserStories e FunctionalTests (Sim! testes funcionais são requisitos que devem ser satisfeitos! Pense sobre isso ...)

Para análise e design: nenhum documento, só cartões CRC Para codificação: um comentário por classe, se necessário Se o usuário quiser um documento, manual, etc. é só fazer um UserStory

pedindo! SupportCrisis o que fazer quando a m..... bate no ventilador?

Regra 1: pareça calmo (não precisa sê-lo, só parecer) Regra 2: escreva cada problema num cartão Regra 3: atribua um fator de urgência a cada cartão Regra 4: trate de um cartão de cada vez. faça o primeiro. faça o segundo, ...

até que a crise vá embora.

etc-2 programa anterior próxima

Page 3 of 3Extreme Programming

04/02/2012file://C:\_SYNC\_DISCIPLINAS\APOO\APOO Jacques UFCG\etc\xp.htm