O documento discute aspectos do projeto de software durante a fase de construção. Ele aborda tópicos como: 1) a diferença entre projeto em projetos pequenos e grandes, onde muitas atividades são consideradas parte da construção em projetos menores; 2) como lidar com a complexidade no projeto, minimizando a complexidade para o programador; e 3) os diferentes níveis de projeto, desde o sistema como um todo até métodos individuais.
3. Em gera, o programador
desenvolve parte do projeto.
4. 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
5. Desafios é um problema “perverso”
Projeto de software
(é 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)
7. 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
8. O que é desejável?
Complexidade mínima
Facilidade de manutenção
Baixo acoplamento
Extensibilidade
Reutilização
Alto fan-in, baixo fan-out, ...
9. 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)
10. Sistema
Todo o sistema
Em casos simples, nenhuma subidivisão é
necessária antes da definição de classes
11. Subsistemas
ROZANSKI, N. AND WOODS, E. SOFTWARE SYSTEMS ARCHITECTURE. READING, MASSACHUSETTS:
ADDISON-WESLEY, 2005, P. 16.
12. Subsistemas
STEVENS, R., BROOK, P., JACKSON, K., AND ARNOLD, S. SYSTEMS ENGINEERING. ENGLEWOOD CLIFFS,
NEW JERSEY: PRENTICE HALL, 1998, P. 97.
15. 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, ...
17. 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).
19. 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
20. Abstração
Capacidade de ignorar
detalhes
Como construir uma casa sem ignorar detalhes?
Detalhes de soft ware devem ser encapsulados!
21. 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?
22. 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()
Classes
MegaSenaDownload
25. Áreas de provável
alteração
Regras 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
27. 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)
28. Padrão de projeto
Soluções prontas para problemas comuns
Factory Method
Publish/Subscribe (ou Observer), ...
31. 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.”
32. Registro do projeto
No próprio código
Wiki
Resumos (enviar por email)
Use uma câmera digital
Diagramas UML
Documentos formais
33. Padrões
IEEE Std 1016 Recommended Practice for
Software Design Descriptions
IEEE Std 1471 Recommended Practice for
Architectural Description of Software Intensive
Systems
36. Tipo Abstrato de Dados
• Ou TAD
• Conjunto composto por dados e
operações executadas sobre tais dados
37. 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, ...
38. Implementação de TAD
• Se a linguagem é orientada a objetos,
então tem-se classes
• Caso contrário, você terá mais
trabalho
40. Passo + importante na
criação de uma classe:
Crie uma boa interface
(oferece boa abstração)
41. 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
42. 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
43. Bom encapsulamento
• Abstração ajuda a controlar a
complexidade (ignora detalhes)
• Encapsulamento (impede que detalhes
sejam conhecidos)
44. 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)
45. Elementos internos da
classe
• Relação tem-um (referência para
objeto)
• Relação é-um (herança), por exemplo,
Boi é um Animal.
46. 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)
47. 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;
}
48. 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)
49. 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)
51. O que é rotina?
Rotina é um método, função ou procedimento
que pode ser chamado para desempenhar um
único propósito
52. 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, ...
53. 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).
54. 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)
55. 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)
56. 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)
57. 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)
58. 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
59. 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?
62. Entradas inválidas
Verifique dados de todas as fontes externas
Verifique todos os parâmetros de entrada
Decida o que fazer com entradas incorretas
63. 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;
}
64. 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
65. Tratando erros
Retornar 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
66. Tratando erros...
Retornar um código de erro
Chamar rotina de processamento de erro
Exibir mensagem quando erro for encontrado
Terminar a execução
67. Tratamento de exceções
Use 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
68. 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
69. 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?)