Livros desenvolvimento de software

Get Started. It's Free
or sign up with your email address
Livros desenvolvimento de software by Mind Map: Livros desenvolvimento de software

1. Pratique ética - sua responsabilidade seu tempo

2. Microsserviços preparados para produção

2.1. Princípios para disponibilidade

2.1.1. Estabilidade

2.1.1.1. Ciclo de desenvolvimento estável

2.1.1.2. Processo de implantação estável

2.1.1.3. Procedimentos estável de introdução e descontinuação

2.1.2. Confiabilidade

2.1.2.1. Processo confiável de implantação

2.1.2.2. Planejar, atenuar e proteger-se contra falhas e dependências

2.1.2.3. Roteamento e descoberta confiáveis

2.1.3. Escalabilidade

2.1.3.1. Escalas de crescimento quantitativas e qualitativas bem definidas

2.1.3.2. Identificação de gargalos e requisitos de recursos

2.1.3.3. Planejamento de capacidade cuidadoso e preciso

2.1.3.4. Tratamento escalável do tráfego

2.1.3.5. Escalamento das dependências

2.1.3.6. Armazenamento escalável dos dadosn

2.1.4. Tolerância a falhas

2.1.4.1. Identificar e se planejar para potenciais cenários de catástrofes e falhas

2.1.4.2. Identificar e resolver pontos únicos de falha

2.1.4.3. Estratégias de detecção e correção de falhas em funcionamento

2.1.4.4. Testes de resiliência por meio de testes de código, teste de carga e teste de caos

2.1.4.5. Tráfego deve ser gerenciado cuidadosamente em preparação para falhas

2.1.4.6. Incidentes e interrupções devem ser tratados de forma adequada e produtiva

2.1.5. Prontidão para catástrofes

2.1.6. Desempenho

2.1.6.1. SLAs adequados de disponibilidade

2.1.6.1.1. 2 noves

2.1.6.1.2. 3 noves

2.1.6.1.3. 4 noves

2.1.6.1.4. 5 noves

2.1.6.2. Adequado tratamento e processamento de tarefas

2.1.6.3. Utilização eficiente de recursos

2.1.7. Monitoramento

2.1.7.1. Logging e rastreamento adequados em toda a pilha

2.1.7.2. Dashboards bem projetados que sejam fáceis de entender e reflitam com precisão a saúde do serviço

2.1.7.3. Alertas eficazes e acionáveis acompanhados de roteiros

2.1.7.4. Implementar e manter uma rotação das equipes de prontidão

2.1.8. Documentação

2.1.8.1. Documentação completa, atualizada e centralizada contendo todas informações relevantes e essenciais

2.1.8.2. Compreensão organizacional nos níveis de desenvolvedor, equipe e ecossistema

2.2. Desafios microsserviços

2.2.1. Estrutura organizacional isolada Comunicação deficiente entre equipes

2.2.1.1. Lei de Conway Reversa - Estrutura da empresa reflete arquitetura de sistema

2.2.1.2. Dificuldade de montar organização operacional

2.2.1.3. Mesma equipe precisa desenvolver, operar, corrigir e monitorar

2.2.2. Aumento dramático da dispersão técnica

2.2.3. Maior capacidade de falha do sistema

2.2.4. Competição por recursos de engenharia e infraestrutura

2.3. Desafios monolítico

2.3.1. Escalabilidade

2.3.2. Falta de eficiência

2.3.3. Dificuldade de adotar novas tecnologias

2.3.4. Velocidade no desenvolvimento

2.4. Camadas

2.4.1. Camada 1: hardware

2.4.1.1. Gerenciamento de configuração

2.4.1.1.1. Ansible

2.4.1.1.2. Chef

2.4.1.1.3. Puppet

2.4.1.2. Sistema operacional

2.4.1.3. Monitoramento

2.4.1.3.1. Nagios

2.4.2. Camada 2: comunicação

2.4.2.1. Rede

2.4.2.2. DNS

2.4.2.3. RPCs

2.4.2.4. Endpoints de APIs

2.4.2.5. Service Discovery

2.4.2.5.1. etcd

2.4.2.5.2. Consul

2.4.2.5.3. Hyperbahn

2.4.2.5.4. ZooKeeper

2.4.2.6. Service registry

2.4.2.7. Balanceamento de carga

2.4.2.7.1. Aws elastic load balancear

2.4.2.7.2. Netflix eureka

2.4.2.7.3. HAProxy

2.4.2.7.4. Nginx

2.4.2.8. Troca de mensagens

2.4.2.8.1. Apache Kafka

2.4.2.8.2. RabbitMQ

2.4.3. Camada 3: plataforma de aplicação

2.4.3.1. Ferramentas internas de desenvolvimento do tipo autosserviço

2.4.3.2. Ambiente de desenvolvimento

2.4.3.3. Ferramenta de teste, empacotamento, build e liberação

2.4.3.4. Pipeline de deployment

2.4.3.5. Logging em nível de microsserviço

2.4.3.6. Monitoramento em nível de microsserviço

2.4.4. Camada 4: microsserviços

2.4.4.1. Todas as configurações específicas dos microsserviços

2.4.4.2. Microsserviços

3. Codificador limpo

3.1. Ensino, aprendizagem e habilidade

3.1.1. Ensino

3.1.1.1. Maioria dos bons programadores não saíram de universidades

3.1.1.2. Maioria dos bons programadores são autodidatas e continuam aprendizado sempre

3.1.1.3. Bons manuais

3.1.1.4. Experiências (na marra)

3.1.2. Aprendizagem

3.1.2.1. Exemplo dos médicos: residência

3.1.2.2. Mestres

3.1.2.2.1. Já assumiram liderança em mais de um projeto

3.1.2.2.2. ~10 anos

3.1.2.2.3. Sabem lidar e coordenar equipes

3.1.2.2.4. São designers e arquitetos

3.1.2.2.5. Mantém papel técnico por meio de leitura, estudo, prática, desempenho e ensino

3.1.2.3. Operadores

3.1.2.3.1. Programadores treinados, competentes e energéticos

3.1.2.3.2. ~5 anos

3.1.2.3.3. Conhecimento de tecnologia atual, mas não de muitas

3.1.2.3.4. São supervisionados por mestres

3.1.2.3.5. São professores dos aprendizes

3.1.2.4. Aprendizes

3.1.2.4.1. Começo da carreira

3.1.2.4.2. ~1 ano

3.1.2.4.3. Supervisionados por operadores

3.1.2.4.4. Não recebem tarefas, mas dão assistência

3.1.2.4.5. São ensinados nas disciplinas: TDD, refatoração, estimativas...

3.1.2.5. Realidade

3.1.2.5.1. Maioria das supervisões não são técnicas!

3.1.2.5.2. Supervisões devem ser técnicas!

3.1.2.5.3. Deve ser um programa focado no ensino, treinamento, supervisão e revisão técnica

3.1.3. Habilidade

3.1.3.1. Arte

3.1.3.2. Habilidade, qualidade, experiência e competência

3.1.3.3. Mentalidade profissional

3.1.3.4. Valores, disciplinas, técnicas, atitudes e respostas

3.1.3.5. Não se convence ninguém a se tornar um artesão de software, você deve dar o exemplo, mostrar sua arte

3.2. Projetos e equipes

3.2.1. Não divida a equipe

3.2.2. Tenha uma equipe que possa assumir vários projetos

3.2.3. É difícil montar uma equipe

3.2.4. Priorização de projetos fica por conta da empresa

3.2.5. É de responsabilidade do gestor de projeto lutar pela prioridade de seu projeto

3.3. Colaboração

3.3.1. Programadores vs Pessoas

3.3.1.1. Não nos tornamos programadores porque gostamos de pessoas

3.3.1.2. Gostamos do relacionamento previsível das máquinas

3.3.2. Programadores vs Empregadores

3.3.2.1. Esteja alinhado com as metas e objetivos do seu empregador

3.3.2.2. Se for o melhor profissional mas não estar alinhado, está fora

3.3.3. Programadores vs Programadores

3.3.3.1. Código deve ser da equipe

3.3.3.2. Seu código deve estar preparado pra qualquer um modificar

3.3.3.3. Trabalhe mais em duplas, se é útil nas emergências, é útil em todos casos

3.3.3.3.1. Saiba se a tarefa é tão trivial que não valha a pena

3.3.3.3.2. Saiba se você realmente precisa se concentrar pra finalizar

3.3.3.3.3. Saiba também quando o problema é complexo e é melhor resolver em dupla

3.4. Pressão

3.4.1. Como você gostaria que um médico agisse em uma cirurgia?

3.4.2. Mantenha a calma e decisões firmes

3.4.3. Empresa sempre irá querer a data de entrega para "eliminar" o risco

3.4.4. Você deve mostrar as probabilidades, quantificar o risco

3.4.5. Trabalho sujo e rápido nunca é bom

3.4.6. Não ficar polindo código, mas não tolere bagunça!

3.4.7. Siga as disciplinas, em tempos de crise ou não

3.4.8. Comunique sempre! O mais rápido possível!

3.4.9. Comunique caso algo dê errado e mostre os planos para colocar o trem de volta nos trilhos

3.4.10. Peça ajuda! Peça ajuda! Peça ajuda!

3.5. Estimativa

3.5.1. Ponte entre negócio e desenvolvedores

3.5.1.1. Parte dos fracassos são causados por ela

3.5.1.2. Fonte de todas desconfianças que governam essa relação

3.5.2. O que é?

3.5.2.1. Empresa enxerga como comprometimento

3.5.2.2. Desenvolvedores enxergam como palpites

3.5.2.3. Estimativas são palpites, porque não sabemos quanto tempo levará

3.5.2.4. Uma estimativa não é um número é uma DISTRIBUIÇÃO

3.5.2.4.1. Probabilidades!

3.5.3. PERT para distribuição das estimativas

3.5.4. Lei dos números grandes

3.5.4.1. Dividir tarefas em várias pequenas

3.5.4.2. A soma das tarefas menores é mais precisa

3.5.4.3. Porque os erros das tarefas pequenas tendem a se integrar

3.5.5. Provável que leve 3 dias, mas pode levar até 7 dias

3.5.5.1. E você pode TENTAR não levar mais de 5 dias?

3.5.5.2. Se você aceitar TENTAR, fez um compromisso e deve honra-lo

3.6. Gerenciamento de tempo

3.6.1. Reuniões

3.6.1.1. São necessárias

3.6.1.2. São um enorme desperdício de tempo

3.6.1.3. Objetivo de administrar seu tempo

3.6.1.3.1. Saiba recusar

3.6.1.3.2. Saiba sair quando sua presença não for mais necessária

3.6.1.3.3. Até seu gerente deve entender pois objetivo dele é você trabalhando também

3.6.1.4. Tenha sempre uma programação e uma meta

3.6.2. Foco-mana

3.6.2.1. Sono influencia

3.6.2.2. Cafeína influência

3.6.2.3. Recarga com falta de foco

3.6.3. Pomodoro

3.6.4. Cuidar com inversão de prioridades

3.6.4.1. Fazer uma atividade menos prioritária porque não está afim de fazer a mais prioritária

3.7. Estratégias de teste

3.7.1. QA faz parte da equipe

3.7.1.1. Como especificadores

3.7.1.2. Como caracterizadores

3.7.2. Pirâmide de testes de automação

3.7.2.1. 1. Testes exploratórios manuais

3.7.2.1.1. ~5%

3.7.2.1.2. Intenção de explorar o sistema em busca de inconsistências

3.7.2.2. 2. Testes de sistema

3.7.2.2.1. ~10%

3.7.2.2.2. GUI

3.7.2.2.3. Não testam regras da empresa diretamente

3.7.2.2.4. Testa se as partes estão interoperando corretamente

3.7.2.2.5. São feitos por arquitetos e principais técnicos

3.7.2.2.6. Executados com menos frequência

3.7.2.3. 3. Testes de integração

3.7.2.3.1. ~25%

3.7.2.3.2. API

3.7.2.3.3. São coreografados

3.7.2.3.4. Não testam regras da empresa

3.7.2.3.5. Testam integração entre componentes

3.7.2.3.6. Somente para sistemas muito grandes

3.7.2.3.7. Escritos por arquitetos e principais técnicos

3.7.2.3.8. Testam desempenho, taxa de transferência, etc

3.7.2.3.9. Não costumam ser executados na integração continua porque demora

3.7.2.4. 4. Testes de componentes

3.7.2.4.1. ~50%

3.7.2.4.2. API

3.7.2.4.3. Escritos pelo QA com ajuda do desenvolvimento

3.7.2.4.4. Testam componentes de negócio

3.7.2.4.5. Ferramentas

3.7.2.5. 5. Testes de unidade

3.7.2.5.1. ~100%

3.7.2.5.2. XUnit

3.7.2.5.3. Implementados por desenvolvedores

3.8. Teste de aceitação

3.8.1. Comunicando requisitos

3.8.1.1. Quando negócio recebe a funcionalidade obtém uma ideia melhor do todo e muda seu conceito inicial

3.8.1.2. Isso é o princípio da incerteza

3.8.2. Decisão prematura

3.8.2.1. Negócio quer saber exatamente o que vai receber

3.8.2.2. Desenvolvedores querem saber exatamente o que vão entregar antes de estimar

3.8.3. Ansiedade de estimativa

3.8.3.1. Desenvolvedores profissionais entendem que podem fazer estimativas com requisitos de baixa precisão

3.8.3.2. Adicionar barras de erro nas estimativas

3.8.4. Ambiguidade tardia

3.8.4.1. Deixar para definir os requisitos mais tarde possível

3.8.4.2. Mesmo assim pode haver ambiguidade até em uma conversa cara a cara

3.8.5. Definição de pronto

3.8.5.1. Acabou de codificar mas não testou?

3.8.5.2. Codificou e testou?

3.8.5.3. Codificou, testou e stakeholder aceitou?

3.8.5.4. Pronto para produção!

3.8.6. Comunicação

3.8.6.1. Transparência

3.8.6.2. Precisão

3.8.7. Automação

3.8.7.1. Sempre automatizado

3.8.7.2. Razão: custo!

3.8.8. Agressão passiva

3.8.8.1. É isso que o teste diz então é isso que vou fazer, mesmo estando errado

3.8.8.2. Não é profissional

3.8.8.3. Trabalho em equipe sempre

3.8.9. Aceitação vs Unidade

3.8.9.1. Função primária documentar design, estrutura e comportamento

3.8.9.2. Unidade: de programador para programador

3.8.9.3. Aceitação: negócio para negócio

3.8.9.4. Não são redundantes, testam as coisas por caminhos diferentes

3.8.9.5. Aceitação: BDD, Selenium, testa API, testa GUI

3.9. Prática

3.9.1. Coding dojo

3.9.1.1. Kata

3.9.1.2. Wasa

3.9.1.3. Randori

3.9.2. Ampliando experiência

3.9.2.1. Projetos de código aberto

3.9.2.2. Pratique outros idiomas (linguagens)

3.9.3. Todos profissionais praticam

3.9.3.1. Pratique quando não está sendo pago

3.9.3.2. Pratique para ser pago e bem pago

3.9.3.3. Mantenha habilidades em dia

3.9.3.4. Adquira novas habilidades

3.10. Desenvolvimento guiado por testes (TDD)

3.10.1. Ciclo de tempo 30 segundos

3.10.2. 3 leis

3.10.2.1. 1. Não escrever nenhum código de produção até ter escrito antes um teste de unidade que detecte uma falha

3.10.2.2. 2. Não escrever mais de um teste de unidade do que o suficiente para a falha

3.10.2.3. 3. Não escrever mais códigos de produção que sejam suficientes para passar pelo atual teste de unidade

3.10.3. Benefícios

3.10.3.1. Certeza do funcionamento

3.10.3.2. Baixa taxa de injeção de defeitos

3.10.3.3. Coragem para mudanças e limpezas do código

3.10.3.4. Documentação no nível de design mais baixo

3.10.3.5. Força um design dissociado

3.10.3.5.1. Testes depois são defensivos

3.10.3.5.2. Testes antes são ofensivos

3.10.4. As vezes atrapalha

3.10.4.1. São exceções, mas se faz mais mal do que bem não faz sentido usar

3.11. Codificando

3.11.1. Preparação

3.11.1.1. 1. Seu código precisa funcionar

3.11.1.2. 2. Seu código precisa resolver o problema proposto por seu cliente

3.11.1.3. 3. Seu código precisa se enquadrar bem no sistema que já existe

3.11.1.4. 4. Seu código precisa ser inteligível para outros programadores

3.11.2. Atrapalham a codificação

3.11.2.1. Codificar cansado

3.11.2.2. Codificar preocupado

3.11.2.3. Zona de fluxo

3.11.2.3.1. Diminui a visão do todo

3.11.2.4. Interrupções

3.11.2.4.1. Fica bravo? Então está na zona de fluxo

3.11.2.4.2. TDD ajuda a voltar ao contexto

3.11.2.4.3. Se disponha a ajudar, a próxima interrupção pode ser sua

3.11.3. Depuração

3.11.3.1. Trabalhe para diminuir o tempo de depuração

3.11.3.2. Escreva testes e precisará depurar menos

3.11.3.3. Médicos não gostam de reabrir pacientes

3.11.3.4. Se você cria muitos bugs não está sendo profissional

3.11.4. Estabelecendo o ritmo

3.11.4.1. Programar é maratona, não corrida de velocidade

3.11.4.2. Saiba quando se afastar

3.11.4.2.1. Dê ao seu subconsciente criativo uma pausa do problema

3.11.4.3. Dirigindo pra casa

3.11.4.4. O banho

3.11.5. Atrasando-se

3.11.5.1. Você vai se atrasar

3.11.5.2. Esperança

3.11.5.2.1. Se a entrega é em 10ndias e sua estimativa 12 você não vai entregar

3.11.5.2.2. Não deixe que as pessoas tenham esperança

3.11.5.3. Apressar-se

3.11.5.3.1. Não fique tentando se apressar

3.11.5.3.2. Não tome atalhos, não pule etapas

3.11.5.3.3. Receita para o desastre

3.11.5.4. Hora extra

3.11.5.4.1. Não concorde a não ser que...

3.11.5.5. Falsa entrega

3.11.5.5.1. Talvez o comportamento mais antiprofissional

3.11.5.5.2. Defina TERMINAR

3.11.6. Ajuda

3.11.6.1. Ajudando os outros

3.11.6.2. Sendo ajudado

3.11.6.3. Ensino

3.12. Dizendo sim

3.12.1. Comprometimento

3.12.1.1. 3 partes

3.12.1.1.1. 1. Você diz que fará

3.12.1.1.2. 2. Você é honesto

3.12.1.1.3. 3. Você de fato o faz

3.12.1.2. Reconhecendo a falta de comprometimento

3.12.1.2.1. Preciso / deveria

3.12.1.2.2. Espero / gostaria

3.12.1.2.3. Vamos

3.12.1.3. Como soa o comprometimento

3.12.1.3.1. Você, pessoalmente, sempre tem algo sob seu controle

3.12.1.3.2. Eu irei... na...

3.12.1.3.3. Eu dependo da pessoa X pra fazer isso

3.12.1.3.4. Eu não sei de fato se isso pode ser feito

3.12.1.3.5. Às vezes, eu simplesmente não consiguirei

3.12.1.3.6. Profissionais não dizem sim pra tudo

3.13. Dizendo não

3.13.1. Papéis contraditórios

3.13.1.1. Gerentes e programadores

3.13.1.2. Encontrar meta em comum

3.13.1.2.1. Gerente: tela de login pra amanhã!

3.13.1.2.2. Dev: amanhã é impossível

3.13.1.2.3. Gerente: o que conseguimos entregar?

3.13.1.2.4. Dev: usuário e senha fixo e entra no sistema

3.13.1.2.5. Gerente: ok! Serve!

3.13.1.3. Tentar

3.13.1.3.1. A pior coisa a se falar

3.13.1.3.2. Quer dizer qie se aplicar esforço extra consegue entregar?

3.13.1.3.3. Então estava guardando esse esforço?

3.13.1.3.4. Tentar é se comprometer com esse esforço extra!

3.13.1.3.5. Tentar é afirmar que tem um plano novo. Qual é esse plano?

3.13.1.3.6. Se não tem um outro plano então está sendo desonesto, mentindo!

3.13.2. O custo de dizer sim

3.13.2.1. Expectativa?

3.13.2.2. Fica sem um plano alcançável

3.13.2.3. Resultado inesperado

3.13.2.4. Não tente ser herói

3.14. Profissionalismo

3.14.1. Ética de trabalho

3.14.1.1. Sua carreira é sua responsabilidade

3.14.1.1.1. Aprendizagem contínua

3.14.1.1.2. Pratique

3.14.1.1.3. Colaboração

3.14.1.1.4. Ensino

3.14.1.1.5. Conheça seu domínio

3.14.1.1.6. Identifique-se com seu cliente

3.14.1.1.7. Humildade

3.14.2. Não cause danos

3.14.2.1. Ao funcionamento

3.14.2.1.1. QA não deve encontrar nada

3.14.2.1.2. Teste, teste, teste e teste de novo

3.14.2.2. A estrutura

3.14.2.2.1. Software precisa ser fácil de mudar

4. Código limpo

4.1. Código limpo

4.1.1. Código representa os detalhes dos requisitos

4.1.2. Especificar requisitos de forma que máquinas possam executar

4.1.3. Premissa: um bom código importa!

4.1.4. O custo de um código ruim aumenta conforme o tempo, a produtividade diminui com o tempo

4.1.5. E daí a gerência só consegue fazer uma coisa: colocar cada vez mais gente

4.1.6. Requisitos ruins, prazos, pressão não são desculpas... A culpa é nossa mesmo

4.1.7. Difícil de engolir mas gerentes buscam compromissos nossos, que nós assumimos

4.1.8. Saber distinguir um quadro ruim de um bom não significa que saibamos pintar

4.1.9. Não basta escrever um código bom, ele precisa ser mantido bom

4.2. Nomes significativos

4.2.1. Use nomes que revelam seu propósito: leva tempo, mas economiza mais

4.2.2. Evite informações erradas: accounts ao invés de accountList pois list tem significado em programação

4.2.3. Faça distinções significativas: copyChars(a1, a2) para copyChars(source, destination)

4.2.4. Use nomes pronunciáveis: sem abreviações

4.2.5. Use nomes passíveis de busca

4.2.5.1. O tamanho de um nome deve ser proporcional ao tamanho do seu escopo

4.2.5.2. Lembrar das constantes!

4.2.6. Não utilizar notação húngara em linguagens atuais

4.2.7. Não usar prefixos em variáveis

4.2.8. Interfaces e implementações

4.2.8.1. Não usar I na frente, cliente não precisa saber que é uma interface

4.2.8.2. Utilizar alteração no nome na implementação

4.2.9. Nomes de classes devem ser substantivos e nunca verbos

4.2.10. Nomes de métodos devem ser verbos e nunca substantivos. Preferência pelo infinitivo

4.2.11. Quando construtores estiverem sobrecarregados utilize factory method e deixe-os privados

4.2.12. Selecione uma palavra por conceito para não ter fetch, retrieve e get no mesmo código

4.2.13. Use nomes a partir do domínio da solução: Repository, Factory, Visitor

4.2.14. Use nomes de domínios do problema: código representa negócio

4.3. Funções

4.3.1. Pequenas! Muito pequenas!

4.3.2. Blocos e indentação

4.3.2.1. Dentro de if else while devem ter apenas uma linha

4.3.2.2. Estruturas aninhadas no máximo um ou dois

4.3.3. Faça apenas uma coisa

4.3.3.1. Como saber se é uma coisa?

4.3.3.2. Pergunte PARA QUE serve!

4.3.3.3. Podem fazer coisas em níveis de abstrações diferentes

4.3.3.4. Quando fazem uma coisa só não podem ser divididas em seções

4.3.3.5. Uma função tem somente um mesmo nível de abstração

4.3.4. Ler o código de cima pra baixo: regra decrescente

4.3.4.1. Descendo o nível de abstração

4.3.5. Instruções switch

4.3.5.1. Deixar debaixo de uma factory criando estruturas polimórficas

4.3.5.2. Devem aparecer apenas uma única vez

4.3.6. Use nomes descritivos: nomes grandes e descritivos são melhores que longos comentários explicativos

4.3.7. Parâmetros

4.3.7.1. Quantidade ideal é zero

4.3.7.2. Depois vem um parâmetro

4.3.7.3. Seguido de dois parâmetros

4.3.7.4. Sempre que possível evitar 3 parâmetros

4.3.7.5. Para mais de 3 parâmetros deve-se ter um motivo muito especial

4.3.7.5.1. Mesmo assim não devem ser usados

4.3.7.6. Muitos parâmetros dificultam os testes também: como testar todas combinações?

4.3.7.7. Parâmetros lógicos são feios!

4.3.7.7.1. Já deixa explícito que a função faz mais de uma coisa

4.3.7.8. New Point(0,0) são componentes de um só valor

4.3.7.9. Agrupar valores em objetos

4.3.8. Evite efeitos colaterais: fazer algo que não está no nome da função

4.3.8.1. Função checkPassword que inicia uma sessão

4.3.9. Evitar parâmetros de saída

4.3.10. Prefira excessões a retorno de códigos de erro

4.3.11. Tratamento de erro é uma coisa só

4.3.11.1. Try e catch devem ter uma chamada de função abaixo só

4.3.12. Evite repetição de código!

4.4. Comentários

4.4.1. São no máximo um mal necessário

4.4.2. Quando o código expressa sua intenção, não precisamos de comentários

4.4.3. São para compensar nosso FRACASSO em nós expressar no código

4.4.4. Códigos mudam e comentários nem sempre acompanham

4.4.5. Bons comentários

4.4.5.1. Informativos

4.4.5.2. Explicação de intenção

4.4.5.3. Esclarecimento

4.4.5.4. Alerta sobre consequências

4.4.5.5. TODO

4.4.5.6. Docs em APIs

4.4.6. Maus comentários

4.4.6.1. Murmúrio: não se sabe exatamente o significado

4.4.6.2. Redundante: escrever o que o método faz e retorna se o nome já descreve isso

4.4.6.3. Enganadores: dizem que o código faz uma coisa que não faz

4.4.6.4. Imperativos: não faz sentido toda função ter comentários

4.4.6.5. Longos: exemplo histórico no início do arquivo... Existe versionador pra isso

4.4.6.6. Ruidosos: dizem o óbvio... Default constructor... Ahhh sério?

4.4.6.7. Evite comentário se é possível usar uma função ou variável

4.4.6.8. Marcadores de posição: raramente são necessários

4.4.6.9. Comentários ao lado de fechamento de bloco

4.4.6.10. Créditos e autoria: tem versionador pra isso

4.4.6.11. Código como comentário: não faça isso!

4.4.6.12. Informações não locais: coloque comentário perto do código que ele descreve, senão nunca será atualizado

4.4.6.13. Informações excessivas: não adicione discussões históricas em comentário

4.4.6.14. Cabeçalhos de funções: uma função curta não requer muita explicação

4.4.6.15. Docs em códigos não públicos: apenas entulhos e distração

4.5. Formatação

4.5.1. Deixe seu código organizado!

4.5.2. Formatação vertical: 50 mil linhas em arquivos não maiores que 500 linhas

4.5.3. Metáfora do jornal: manchete, artigos...

4.5.4. Espaçamento vertical entre conceitos

4.5.5. Continuidade vertical para mesmos conceitos

4.5.6. Distância vertical

4.5.6.1. Conceitos intimamente ligados devem ficar juntos

4.5.6.2. Declaração de variáveis: o lais pro no de onde serão utilizadas

4.5.6.3. Variáveis de instâncias: agrupadas em um só lugar

4.5.6.4. Funções dependentes: maior abstração acima e demais conforme ordem de chamada

4.5.6.5. Afinidade conceitual: exemplo sobrecargas de métodos (mesmo nome)

4.5.6.6. Ordenação vertical: maior abstração acima, baixo nível abaixo

4.5.6.7. Formatação horizontal: cerca de 120 caracteres são suficientes

4.5.6.8. Regra de equipes: programadores tem suas próprias regras, mas quando trabalham em equipe precisam respeitar as regras da equipe

4.6. Objetos e estruturas de dados

4.6.1. Abstração de dados é preferível: não dê acesso aos dados que o cliente não precisa saber

4.6.2. Antissimetria dado/objeto

4.6.2.1. Estrutura de dados expõem seus dados e não possuem funções significativas

4.6.2.2. Objetos usam abstrações para esconder seus dados e expõem funções que operam em tais dados

4.6.2.3. Código procedural dificulta a adição de novas estruturas de dados, pois todas funções precisariam ser alteradas

4.6.2.4. Código OO dificulta adição de novas funções, pois todas as classes precisam ser alteradas

4.6.2.5. Devemos saber escolher qual tipo de código é melhor em cada caso

4.6.2.6. Às vezes, você realmente deseja estruturas de dados simples com procedimentos operando nelas

4.6.3. Objetos de transferência de dados

4.6.3.1. DTOs: úteis para comunicação

4.6.3.2. Exigem traduções

4.6.3.3. São apenas estrutura de dados

4.6.4. Active Record

4.6.4.1. São estrutura de dados com métodos de navegação: save e find

4.6.4.2. São estrutura de dados e não devem ter regras de negócio neles

4.6.4.3. Crie objetos separados para as regras

4.6.5. Lei de Demeter

4.6.5.1. Fale apenas com conhecidos

4.6.5.2. Método f de uma classe C só deve chamar os métodos de

4.6.5.2.1. C

4.6.5.2.2. Um objeto criado por f

4.6.5.2.3. Um objeto passado como parâmetro pra f

4.6.5.2.4. Um objeto dentro de uma variável de instância C

4.6.5.2.5. O método NÃO deve chamar os métodos em objetos retornados por qualquer outra das funções permitidas

4.6.5.3. Train Wrecks (acidente ferroviário)

4.6.5.3.1. Quando é um objeto ele deve esconder sua estrutura interna

4.6.5.3.2. Quando é estrutura de dados ele expõe sua estrutura de dados

4.6.5.3.3. Híbridos: cuidar para não misturar estrutura de dados e objetos juntos na mesma classe

4.6.5.3.4. Estruturas ocultas: porque o cliente quer acessar aquele dado? Que tal mandar o objeto fazer aquele trabalho?

4.7. Tratamento de erro

4.7.1. Em muitos códigos o tratamento de erros DOMINA

4.7.2. DOMINA significa que tem muitos tratamentos de erros espalhados e isso dificulta o entendimento do código

4.7.3. Obscurecer a lógica está errado!

4.7.4. Use exceções em vez de retornar códigos

4.7.4.1. Dessa forma você divide as duas lógicas (sucesso e erro)

4.7.5. Use exceções não verificadas

4.7.5.1. Em Java precisa declarar as exceções lançadas

4.7.5.1.1. Isso fere o princípio Open-Closed, pois todas as classes superiores precisam ser alteradas

4.7.6. Forneça exceções com contexto

4.7.6.1. Deve saber a fonte e localização de um erro: mensagens informativas (operação e tipo de falha)

4.7.7. Defina as classes de exceções segundo as necessidades do chamador

4.7.7.1. Como sua exceção é capturada?

4.7.7.2. Criar wrapper para exceções

4.7.8. Não retorne null

4.7.8.1. Retorne um Special Case Pattern (Fowler)

4.7.8.2. Minimize as chances de um NullPointerException

4.7.8.3. Exemplo: retorne uma lista vazia ao invés de null

4.7.9. Não passe null

4.7.9.1. Ideal seria a linguagem não deixar passar null

4.7.9.2. Alternativa é seu método tratar através de afirmações (checks)

4.8. Limites

4.8.1. Uso de códigos de terceiros

4.8.1.1. Crie limites: Map tem muitos métodos e passá-lo adiante alguém pode dar um clear

4.8.1.1.1. Talvez criar uma classe para encapsular seja uma boa ideia: Sensores... Assim só poderão fazer o que você deixar

4.8.1.1.2. Caso haja uma mudança em Map, você mudará só está classe e o resto não será afetado

4.8.2. Testes de aprendizagem

4.8.2.1. Faça testes das bibliotecas ou APIs que irá utilizar

4.8.2.2. Sai de graça pois terá que aprender sobre a API mesmo, aprenda fazendo testes

4.8.2.3. Isso facilitará encapsular depois

4.8.3. Uso de código que não existe ainda

4.8.3.1. Se você sabe do que vai precisar, crie a interface e depois integre

4.8.3.2. Permite realizar mock com um objeto fake também e já realizar testes

4.9. Testes de unidade

4.9.1. 3 leis do TDD

4.9.1.1. 1. Não se deve escrever o código de produção até criar um teste de unidade de falhas

4.9.1.2. 2. Não se deve escrever mais de um teste de unidade do que o necessário para falhar, e não compilar é falhar

4.9.1.3. 3. Não se deve escrever mais códigos de produção do que o necessário para aplicar o teste de falha atual

4.9.1.4. Rotina de 30 segundos!

4.9.2. Códigos de testes são tão importantes quanto de produção

4.9.2.1. Devem ser implementados com cuidado e limpos, senão vão dificultar a manutenção no futuro

4.9.3. Testes de unidades mantém o código de produção flexíveis, reutilizáveis e passíveis de manutenção

4.9.4. Quanto maior a cobertura menor o medo de mudar

4.9.5. O que torna um teste limpo? LEGIBILIDADE

4.9.6. Código de testes devem poder ser lidos da mesma forma que os de produção

4.9.7. Padrão: arrange/act/assert

4.9.8. Padrão: given/when/then

4.9.9. Um único conceito por teste

4.9.10. FIRST

4.9.10.1. Fast (rapidez): devem executar rápido, caso contrário você não executará com frequência

4.9.10.2. Independent (independência): um teste não deve depender de outro

4.9.10.3. Repeatable (repetitividade): deve-se poder repetir o teste em qualquer ambiente

4.9.10.4. Self-validating (autovalidação): testes devem ter uma saída booleana, não sendo necessário analisar nenhum arquivo ou algo do tipo

4.9.10.5. Timely (pontualidade): testes precisam ser escritos em tempo hábil, antes do código de produção, senão pode ficar difícil e você não vai implementá-los

4.10. Classes

4.10.1. Organização

4.10.1.1. Mantenha um padrão de organização: variáveis métodos construtor...

4.10.1.2. Mantenha o padrão para o projeto/equipe

4.10.2. Encapsulamento

4.10.2.1. Mantenha privado mas caso necessário quebre para testes, eles tem prioridade

4.10.3. As classes devem ser pequenas!

4.10.3.1. O tamanho é medido em responsabilidades! Apenas 1 responsabilidade!

4.10.3.2. Escolher um bom nome é o início para definir a responsabilidade

4.10.4. Princípio da responsabilidade única

4.10.4.1. Uma função, classe ou módulo devem ter 1 e apenas 1 motivo para mudar

4.10.5. COESÃO

4.10.5.1. Pequeno número de variáveis de instância

4.10.5.2. Cada método manipula uma ou mais variáveis

4.10.5.3. Quanto mais variáveis de instância um método manipular, mais coeso ele é para a classe

4.10.5.4. Tente separar as variáveis e métodos em classes menores para que fiquem mais coesos

4.10.5.5. Separar funções grandes em pequenas normalmente nos ajudam a dividir classes também observando a coesão

4.10.5.6. Sempre que tivermos realizar uma alteração em uma classe e percebemos que é necessário refatorar, refatore!

4.10.5.7. SRP e Open-Closed sempre! Qual o motivo para mudar? No singular!

4.10.5.8. Classes concretas contém entalhes da implementação

4.10.5.9. Classes abstratas (e interfaces) representam apenas conceitos

4.10.5.10. Sempre que depender de alguém crie uma classe abstrata ou interface e faça sua classe depender desta abstração

4.11. Sistemas

4.11.1. Separa a construção e uso do sistema

4.11.1.1. Injeção de dependência

4.11.2. Desenvolvimento gradual

4.11.2.1. Pense em como é construída uma cidade

4.11.2.2. Você faria uma rua de 4 pistas logo de cara? Ou iria alargar conforme necessário?

4.11.2.3. Mito dizer que podemos conseguir um sistema "correto de primeira"

4.11.2.4. Arquitetura do sistema pode crescer gradualmente SE mantivermos uma separação devida de preocupações

4.11.3. Separar preocupações. Ex: estruturas de banco do domínio Validação da classe DTO

4.11.3.1. Uma forma é com programação orientada a aspectos: annotation do java

4.11.4. Use padrões sabiamente quando eles adicionarem um valor demonstrativo

4.11.4.1. Padrões de projeto quando você sabe que algo vai mudar mesmo

4.11.4.2. Arquitetura de microsserviços quando você sabe da necessidade dela

4.11.5. Sistemas precisam de uma linguagem específica a um domínio

4.11.5.1. DDD

4.11.5.2. DSL minimiza a distância da comunicação

4.12. Emergência

4.12.1. 4 regras de um projeto simples (Kent Beck)

4.12.1.1. 1. Efetuar todos os testes

4.12.1.1.1. Vai seguir SRP porque é mais fácil testar assim

4.12.1.1.2. Vai seguir DIP porque acoplamento alto é difícil de testar

4.12.1.1.3. Com testes podemos refatorar a todo momento

4.12.1.2. 2. Sem duplicação de código

4.12.1.2.1. Refatoração a todo momento

4.12.1.2.2. Template Method evita duplicação de código

4.12.1.3. 3. Expressar o propósito do programador

4.12.1.3.1. Quanto mais os outros entenderem menos tempo será gasto com manutenção

4.12.1.3.2. Manutenção de software sempre será o maior custo porque o negócio muda a todo momento e o software também

4.12.1.3.3. Padrões de projeto são modos de comunicação e expressividade

4.12.1.3.4. Testes de unidade bem escritos também são expressivos

4.12.1.4. 4. Minimizar o número de classes e métodos

4.12.1.4.1. Adotar uma abordagem mais pragmática e com menos dogmatismo

4.12.1.4.2. Excesso de SRP pode causar isso

4.13. Concorrência

4.13.1. Estratégia de desacoplamento, separa o que é executado de quando é executado

4.13.2. Mitos e conceitos equivocados

4.13.2.1. A concorrência sempre melhor desempenho

4.13.2.1.1. Só se houver um tempo de espera muito grande que possa ser dividido entre múltiplas threads

4.13.2.2. O projeto não muda ao criar programas concorrentes

4.13.2.2.1. Um algoritmo concorrente pode ser consideravelmente diferente de um de apenas uma thread

4.13.2.3. Entender as questões de concorrência não é importante quando se trabalha com um container web ou EJB

4.13.2.3.1. É melhor saber apenas o que seu container está fazendo e como protegê-lo da concorrência e deadlock

4.13.3. Princípios para proteção da concorrência

4.13.3.1. SRP

4.13.3.1.1. Mantenha o código voltado para concorrência separado do resto

4.13.3.2. Limite o escopo dos dados: região crítica

4.13.3.3. Use cópia dos dados

4.13.3.4. Threads devem ser o mais independentes possíveis

4.13.3.5. Conheça os métodos

4.13.3.5.1. Produtor consumidor

4.13.3.5.2. Editores e escritores

4.13.3.5.3. Dining Philosophers (problema dos filósofos)

4.13.3.6. Cuidado com dependências entre métodos sincronizados

4.13.3.6.1. Evite usar mais de um método em um objeto compartilhado

4.13.3.7. Mantenha suas seções sincronizadas as menores possíveis, pois criam bloqueio

4.13.3.8. ...

4.14. Refinamento sucessivo

4.14.1. Programar é mais uma arte do que uma ciência

4.14.2. Para fazer a versão final da redação, primeiro você faz um rascunho

4.14.3. Para fazer um código limpo, primeiro você faz um sujo

4.15. Odores e heurísticas

4.15.1. Comentários

4.15.1.1. C1: informações inapropriadas

4.15.1.2. C2: comentário obsoleto

4.15.1.3. C3: comentários redundantes

4.15.1.4. C4: comentário mal escrito

4.15.1.5. C5: código como comentário

4.15.2. Ambiente

4.15.2.1. A1: construir requer mais de uma etapa

4.15.2.2. A2: testes quererem mais de uma etapa

4.15.3. Funções

4.15.3.1. F1: parâmetros em excesso

4.15.3.2. F2: parâmetros de saída

4.15.3.3. F3: parâmetros lógicos

4.15.3.4. F4: função morta

4.15.4. Geral

4.15.4.1. G1: múltiplas linguagens em um arquivo fonte

4.15.4.2. G2: comportamento óbvio não é o implementado

4.15.4.3. G3: comportamento incorreto nos limites

4.15.4.4. G4: seguranças anuladas

4.15.4.5. G5: duplicação

4.15.4.6. G6: códigos no nível errado de abstração

4.15.4.7. G7: as classes base dependem de suas derivadas

4.15.4.8. G8: informações excessivas

4.15.4.9. G9: código morto

4.15.4.10. G10: separação vertical

4.15.4.11. G11: inconsistência

4.15.4.12. G12: entulho

4.15.4.13. G13: acoplamento artificial

4.15.4.14. G14: feature envy

4.15.4.15. G15: parâmetros seletores

4.15.4.16. G16: propósito obscuro

4.15.4.17. G17: responsabilidade mal posicionada

4.15.4.18. G18: modo estático inadequado

4.15.4.19. G19: use variáveis descritivas

4.15.4.20. G20: nomes de funções devem dizer o que elas fazem

4.15.4.21. G21: entenda o algoritmo

4.15.4.22. G22: torne dependências lógicas em físicas

4.15.4.23. G23: prefira polimorfismo a if/else ou switch/case

4.15.4.24. G24: siga as Convenções padrões

4.15.4.25. G25: substitua os números mágicos por constantes com nomes

4.15.4.26. G26: seja preciso

4.15.4.27. G27: estrutura acima de convenção

4.15.4.28. G28: encapsule as condicionais

4.15.4.29. G29: evite condicionais negativas

4.15.4.30. G30: as funções devem fazer uma coisa só

4.15.4.31. G31: acoplamentos temporais ocultos

4.15.4.32. G32: não seja arbitrário

4.15.4.33. G33: encapsule as condições de limites

4.15.4.34. G34: funções devem descer apenas um nível de abstração

4.15.4.35. G35: mantenha os dados configuráveis em níveis altos

4.15.4.36. G36: evite a navegação transitiva

4.15.5. Nomes

4.15.5.1. N1: escolha nomes descritivos

4.15.5.2. N2: escolha nomes no nível apropriado de abstração

4.15.5.3. N3: use uma nomenclatura padrão onde for possível

4.15.5.4. N4: nomes não ambíguos

4.15.5.5. N5: use nomes longos para escopos grandes

4.15.5.6. N6: evite codificações

4.15.5.7. N7: nomes devem descrever os efeitos colaterais

4.15.6. Testes

4.15.6.1. T1: testes insuficientes

4.15.6.2. T2: use uma ferramenta de cobertura

4.15.6.3. T3: não pule testes triviais

4.15.6.4. T4: um teste ignorado é uma questão sobre uma ambiguidade

4.15.6.5. T5: teste as condições de limites

4.15.6.6. T6: teste abundantemente bugs próximos

4.15.6.7. T7: padrões de falhas são reveladores

4.15.6.8. T8: padrões de cobertura de testes podem ser reveladores

4.15.6.9. T9: testes devem ser rápidos