Cs 2

Post on 23-Jun-2015

855 views 4 download

Transcript of Cs 2

Projeto de Software:Durante a Construção de Software

Em projetos pequenos, muitas atividades são consideradas parte da construção, inclusive o projeto.

Em gera, o programador desenvolve parte do projeto.

Como é o projeto?

Desenho de um diagrama na UML, contendo algumas classes e relacionamentos entre elas

Pseudocódigo de um método

Selecionar um padrão de projeto a ser empregado

DesafiosProjeto de software é um problema “perverso”(é preciso resolver o problema para entendê-lo)

O projeto é obtido de um processo desordenado (faz uso de heurísticas)

Equilíbrio de prioridades(desempenho, produtividade, manutenção?)

Envolve restrições (tempo, custo, ...)

Não é determinístico (n pessoas, n projetos)

Evoluem (não nascem prontos)

Principal objetivo técnico do software: controle da complexidade

Como lidar com a complexidade?

Minimizar a quantidade de complexidade que o cérebro tem que lidar em dado momento

Evitar complexidade acidental desnecessária

O que é desejável?

Complexidade mínima

Facilidade de manutenção

Baixo acoplamento

Extensibilidade

Reutilização

Alto fan-in, baixo fan-out, ...

Níveis de projeto

Sistema (todo o software)

Divisão em subsistemas (vários pacotes)

Divisão em classes dentro de pacotes

Divisão em dados e rotinas (nas classes)

Projeto interno de rotina (método)

Sistema

Todo o sistema

Em casos simples, nenhuma subidivisão é necessária antes da definição de classes

SubsistemasROZANSKI, N. AND WOODS, E. SOFTWARE SYSTEMS ARCHITECTURE. READING, MASSACHUSETTS: ADDISON-WESLEY, 2005, P. 16.

SubsistemasSTEVENS, R., BROOK, P., JACKSON, K., AND ARNOLD, S. SYSTEMS ENGINEERING. ENGLEWOOD CLIFFS, NEW JERSEY: PRENTICE HALL, 1998, P. 97.

Subsistemas

GARLAND, J. LARGE-SCALE SOFTWARE ARCHITECTURE. INDIANAPOLIS, INDIANA: WILEY, 2003, P. 91.

Muitos outros exemplos...

Handbook of Software Architecturehttp://handbookofsoftwarearchitecture.com

Apresenta + de 1000 padrões arquiteturais

Subsistemas típicos

Regras de negócio (cômputos, regras como o aluno não poderá matricular se estiver em débito com a biblioteca, ...)

Interface com o usuário

Acesso a banco de dados

Dependências do sistema operacional, hardware específico, bibliotecas, ...

Classes

Projeto interno de rotinas

Projeto de métodos (algoritmos, pseudocódigo, ...)

Exemplo:Fazer uso de busca binária e, quando encontrado o elemento, verificar se se trata do elemento de menor índice (o que deve ser retornado).

Ferramenta do projetista

HeurísticasNão existe caminho “bem definido” ou determinístico

Da perspectiva OO

Encontre objetos do mundo real (modelagem de domínio)

Identifique objetos (software) e seus atributos

Determine o que pode ser feito com cada objeto

Determine o que cada objeto faz com os demais

Identifique partes visíveis de um objeto

Defina as interfaces de cada objeto

Abstração

Capacidade de ignorar detalhes

Como construir uma casa sem ignorar detalhes?

Detalhes de software devem ser encapsulados!

Ocultamento de informação

Decisões de projeto ou construção são ocultados de todas as outras classes!

Por exemplo, você sabe como está implementada a classe java.util.ArrayList?

Como ocultar?

Usar constantes em vez de literais, ou seja, MAX_ALUNOS_POR_TURMA em vez de 30

Tipos de dados (por exemplo, ArrayList)

Rotinas (métodos)getNextID()

ClassesMegaSenaDownload

Barreiras para o ocultamento

Distribuição excessiva

Dependências circulares

Dados de classes (dados globais)

Perda de desempenho (String.toString() e vetor.length)

O que devo ocultar?

HABITUE-SE À PERGUNTA

Áreas de provável alteraçãoRegras de negócio

Dependências de hardware

Entrada/Saída

Recursos não padronizados (linguagem de programação)

Áreas de projeto e construção difíceis

Variáveis de status

Restrições quanto ao tamanho dos dados

Manter baixo acoplamento

PERSPECTIVAS

Tamanho (poucas conexões)

Visibilidade (pouca exposição)

Flexibilidade (facilidade de alterar conexões)

Tipos. Acoplamento de:Parâmetro e dados simples (apenas tipos primitivos)

Objeto simples (cria instância de uma classe)

Parâmetro-objeto (+ elaborado do que parâmetro de tipos primitivos)

Acoplamento semântico (conhece o funcionamento de outro módulo)(imperceptível ao compilador ou IDE)

Padrão de projeto

Soluções prontas para problemas comuns

Factory Method

Publish/Subscribe (ou Observer), ...

Abstract Factory

Práticas de Projeto

Iteração

Dividir e conquistar

Top-down/bottom-up

Prototipagem experimental

Projeto colaborativo

Quanto de projeto é suficiente?Depende: (a) da experiência da equipe; (b) do conhecimento do domínio; (c) rotatividade da equipe; (d) quão crítica é a aplicação; (e) projeto é pequeno; (f) tempo de vida do software.

Steve McConnell diz:“Eu preferiria usar 80% do trabalho de projeto na criação e exploração de alternativas e 20% na criação de documentação menos aperfeiçoada.”

Registro do projeto

No próprio código

Wiki

Resumos (enviar por email)

Use uma câmera digital

Diagramas UML

Documentos formais

Padrões

IEEE Std 1016 Recommended Practice for Software Design Descriptions

IEEE Std 1471 Recommended Practice for Architectural Description of Software Intensive Systems

Classes funcionais

Evolução

• Inicialmente desenvolvia-se software pensando em instruções

• Depois em rotinas (anos 70 e 80)

• Hoje se pensa em classes!

Tipo Abstrato de Dados

• Ou TAD

• Conjunto composto por dados e operações executadas sobre tais dados

Exemplo

• Elevador: sobe um andar, desce um andar, move-se para andar específico, ...

• Menu: inicia novo menu, cria entrada no menu, ativa/desativa item de menu, ...

Implementação de TAD

• Se a linguagem é orientada a objetos, então tem-se classes

• Caso contrário, você terá mais trabalho

Classe

• Tipo Abstrado de Dados +

• Herança +

• Polimorfismo

Passo + importante na criação de uma classe:Crie uma boa interface(oferece boa abstração)

Dicas• A interface deve oferecer um nível de

abstração consistente

• Certifique-se de compreender qual abstração a classe está implementando

• Forneça serviços em pares (e opostos)(apaga/acende, define/obtém, ...)

• Mova informações não relacionadas para outra classe

Mais dicas...

• Crie interfaces programáticas em vez de semânticas

• (semântica indica como a interface deve ser empregada)

• Considere a abstração e a coesão em conjunto

Bom encapsulamento

• Abstração ajuda a controlar a complexidade (ignora detalhes)

• Encapsulamento (impede que detalhes sejam conhecidos)

Dicas

• Minimize a acessibilidade de classes e membros

• Não exponha dados como públicos

• Elemento interno deve ser privado

• Não faça suposições sobre clientes

• Cuidado com violações semânticas de encapsulamento (não chamar db.connect() porque você sabe que db.busca(jogo) chama o método anterior se não existir conexão)

Elementos internos da classe

• Relação tem-um (referência para objeto)

• Relação é-um (herança), por exemplo, Boi é um Animal.

Dicas

• Pense em herança ou a proíba (final)

• Siga o PSL (Princípio de Substituição de Liskov)

• Evite árvores profundas de herança (7+-2)

Mais dicas...

• Verifique se um switch pode ser substituído por uso de polimorfismo

switch (bicho.getTipo()) { case BOI: System.out.println(“boi”); break; case SAPO: System.out.println(“sapo”); break;}

Funções

• Mantenha o menor número de métodos em uma classe

• Minimize o número de diferentes métodos chamados por uma classe

• Minimize as chamadas indiretas de métodos (Lei de Demétrio)

TAREFA

• Crie código que ilustre uma substituição apropriada de switch pelo uso de polimorfismo

• Crie um diagrama de sequência (UML) que ilustre a Lei de Demétrio

• Crie uma classe com construtor privado e só permita a criação de uma única instância (Singleton)

Métodos de Alta Qualidade

O que você deve saber!

O que é rotina?

Rotina é um método, função ou procedimento que pode ser chamado para desempenhar um único propósito

Razões para criar um método

Reduzir a complexidade

Introduzir uma abstração (aluno.isAprovado() em vez de aluno.naoDeveBilioteca && ...)

Evitar código duplicado

Melhorar a portabilidade, desempenho, ...

Coesão

Quão intimamente estão relacionadas as operações em uma rotina?

Por exemplo, raizDoInverso(x) é menos coesa que raiz(x) e inverso(x).

Tipos

Funcional (executa uma única operação)(MegaSena proposta não coesa)

Sequencial (não identifica função completa)

Comunicativa (usam os mesmos dados)

Temporal

Procedural (ordem de dados fornecidos pela UI)

Lógica (ocorre decisão por flag)

Bons nomes de rotinas

Descreva tudo que a rotina faz

Evite imprecisão (fazCalculo()? geraImpressao()?

Não divida por número (r1(), r2(), r3(), ...)

Use nomes tão longos quanto necessário

Descreva o valor de retorno (raizQuadrada(x))

Use verbo + nome “fortes” (gerarExtrato(fulano)

Bons nomes...

Use opostos corretamente

adicionar/remover em vez de adicionar/destruir

min/max em vez de min/maior

abrir/fechar em vez de abrir/encerrar

Convenções para operações comuns (get/set)

Quão longa deve ser uma rotina?

• Tamanho de uma rotina é inversamente proporcional ao número de erros?!

• Não ultrapasse 200 linhas (não inclui linha em branco nem comentário)

Como usar parâmetros?

• Siga a ordem entrada-uso-saída

• Considere convenções (in, out, ...)

• Se várias rotinas usam os mesmos parâmetros, use uma mesma ordem

• Use todos os parâmetros

• Não os use como variáveis locais

• Limite o número de parâmetros a 7

TAREFA

• JavaBeans possui uma convenção para dar nomes a métodos que obtém e modificam valores de propriedades. Qual é esta convenção?

• java.lang.String possui os métodos regionMatches e copyValueOf, dentre outras. O uso de parâmetros é consistente?

PROGRAMAÇÃO DEFENSIVA“Direção defensiva” em software

Postura

Se alguém fizer algo perigoso, você não será prejudicado!

Entradas inválidas

Verifique dados de todas as fontes externas

Verifique todos os parâmetros de entrada

Decida o que fazer com entradas incorretas

Assertions

Código usado durante o desenvolvimento que permite a um programa fazer uma “auto-verificação” enquanto é executado

calculaMediaFinal(Aluno aluno) { .... mediaFinal = ... assert mediaFinal >= 0 && mediaFinal <= 10; return mediaFinal;}

Dicas

Use um assert para algo que nunca pode ocorrer!

Use código de tratamento de exceção para o que pode ocorrer

Não use código executável em um assert

Use asserts para verificar pré-condições e pós-condições

Tratando errosRetornar um valor “inofensivo” (String vazia, array sem elementos, ...)

Substituir pelos próximos dados válidos(browsers fazem isto com HTML)

Retornar a mesma resposta anterior

Valor válido mais próximo (-2 Kelvin para 0 Kelvin)

Registrar alerta em arquivo de log

Tratando erros...

Retornar um código de erro

Chamar rotina de processamento de erro

Exibir mensagem quando erro for encontrado

Terminar a execução

Tratamento de exceçõesUse para notificar ocorrências que não podem ser ignoradas

Use exceção apenas para situação excepcional

Não use exceção para “empurrar” para outro um problema seu

Evite gerar exceções em construtores, exceto se você as tratar

Exceção deve ser compatível com nível de abstração

Tratando exceções...

Inclua mensagens (contexto) da exceção)

Evite blocos catch vazios

Não ignore exceções que código de biblioteca gera

Considere a criação de “relator” de exceção global

Padronize as exceções do seu projeto

TAREFA

• System.out.println(“x”) retorna void. Como é feito o tratamento em caso de erro?

• System.out.println(“x”) pode gerar uma exceção?

• O que é programar de forma ofensiva? (segundo Steve McConnell?)