Guia de Boas Práticas e Procedimentos
Desenvolvido por Hugo Norte @hugonorte
última atualização: 12/09/2024
Sumário
1. Sobre esse guia
Esse guia tem como objetivo condensar em um documento as regras para o desenvolvimento de software da empresa. O guia deve ter caráter conservador, no sentido de ser elaborado a partir de referências das instituições já estabelecidas e reconhecidas no mercado que já passaram pelo teste do tempo. Desse modo, uma primeira boa prática a ser sugerida aqui é que todas as práticas descritas aqui devem ter um link para a documentação de onde foram inspiradas.
Muito embora esse documento seja de responsabilidade do gestor de conhecimento da empresa, o que estiver escrito aqui pode e deve sofrer ajustes a partir de atualizações de padrões existentes bem como nas práticas que tiverem sua eficácia e eficiência estabelecidas na rotina da empresa. Boa leitura!
2. Comunicação
Talvez o tópico mais importante do trabalho em time e do mundo corporativo. A comunicação é fundamental Pelos seguintes aspectos:
Principais benefícios
- Transparência e Confiança
- Alinhamento de Objetivos
- Resolução Eficiente de Problemas
- Criação de Cultura Organizacional Positiva
- Inovação e Criatividade
- Melhoria do Desempenho Individual e Coletivo
- Redução de Conflitos
- Redução de desinformação ou mal entendidos
- Maior Engajamento e Retenção de Talentos:
Ferramentas de registro de comunicação:
- Atas (registradas em alguma ferramenta e enviada aos participantes por e-mail)
- Vídeoconferência
- Áudio
As reuniões que decidem algo novo ou alterações no projeto devem sempre ser gravadas em vídeo ou registradas em ata
Valores complementares
- Simplicidade
- Feedback
- Coragem
- Respeito
- Time
Simplicidade
Fazer o código explícito e de fácil leitura. Sem utilizar artifícios sofisticados e muito abstratos de construção. A meta é fazer código que qualquer programador iniciante entenda.
Feedback
Ao analisar uma informação recebida e surgir uma dúvida, crítica construtiva ou sugestão, dê o feedback ao seu par ou gestor imediato o mais rápido possível. Ao demorar na troca de comunicação, a equipe inteira pode estar sendo prejudicada.
Coragem
Coragem de assumir um erro e comunicar ao time Coragem de assumir a responsabilidade por tarefas Coragem de refatorar um código se ele estiver prejudicando o funcionamento de um sistema (nesse caso, a refatoração deve ser comunicada antecipadamente ao seu coordenador ou gestor imediato)
Respeito
Além de debater sobre como desejamos ser respeitados (e devemos exigir respeito), esse tópico abrange o respeito em diversas dimensões:
- Construa o Repeito a seu nome e a sua história como profissional
- Respeite o seu ambiente de trabalho
- Respeite o código que já foi construído. Mesmo que perceba que um código precisa ser refatorado, um programador que veio antes de você passou por diversas questões até chegar na solução que está implementada. Em vez de criticar, bata um papo com o seu colega e troque experiências até chegarem a um código que seja o melhor para o projeto e não para interesses pessoais.
- Respeite o tempo que a empresa está remunerando você. Use com responsabilidade o tempo de descanso (que é necessário), no entanto, avalie constantemente se não há excessos e se esse tempo não está artapalhando a sua entrega do dia.
- Respeite os processos e normas da empresa
- Respeite os seus limites e trabalhe apenas as 40 horas por semana.
- Elogie em público e critique, sempre de forma construtiva, no particular.
Time
- Todos tem responsabilidade sobre as tarefas e sobre o código
- Evite trabalhar 100% do tempo sozinho. Combine com um colega e busque sempre trabalhar em par.
3. Ambiente de Desenvolvimento
3.1 - IDE:
- Utilizaremos o Visual Studio Code - Para baixá-lo, clique aqui
Sobre linters, veja o item 3.6 deste guia
3.2 - Repositório de código:
- Utilizaremos o Github
3.2.1 - Uso do Git
Ao utilizar o git para gerenciamento de código em equipe, utilizaremos as seguintes práticas:
- Nenhum código deve ser escrito diretamente na Branch master;
- A branch master não deve ser apagada no github em nenhuma hipótese;
- Qualquer desenvolvimento, por mais simples que seja, deve ser criado utilizando-se um branch criado a partir do branch master;
- Para não haver perda de código, os commits + push devem acontecer, pelo menos, uma vez por dia.
- Para não haver conflitos no código principal (master) com o código de uma branch que esteja com mais de 3 horas de uso, a branch de trabalho (que necessariamente é derivada da branch master), deverá sofrer um git merge com a branch master a cada 3 horas ou a cada novo checkout (o que ocorrer primeiro);
- Após o pull request ser aprovado pelo revisor, o branch de trabalho deverá ser apagado do github;
- Fazer commits separados por funcionalidades resolvidas.
4. Codificação
Regras para qualquer linguagem:
4.1 Uso de condicionais:
- Para padronização de leitura de código, as condicionais devem ser feitas na forma explícita. O uso do formato ternário deve ser evitado.
- Em C#, não usar o LINQs.
- Deve ser evitado o uso de condicionais ('ifs') aninhados. Quando múltiplas condições precisarem ser testadas, utilizar a estrutura switch/case (Javascript) ou match (Python)
- Nas funções onde algum dado é retornado, utilizar sempre o early Return. Ver item 4.2
4.2 Early Return:
- Para aumentar a eficiência do código e da leitura, abandonar ifs aninhados e uso de else desnecessários, utilizaremos o Early Return:
Exemplos:
Não Recomendados:
- Código em Python
#Muitos ifs aninhados
#O programa fica tempo desnecessário checando diversos ifs e elses
#Mais linhas de código
#Menor eficiência
def return_stuff(argument1, argument2):
if (argument1.is_valid()):
if (argument2.is_valid()):
other_val1 = do_some_stuff(argument1, argument2)
if (other_val1.is_valid()):
otherVal2 = do_another_stuff(other_val1)
if (otherVal2.is_valid()):
return "Stuff";
else:
throw new Exception();
else:
throw new Exception();
else:
throw new Exception();
else:
throw new Exception();Recomendados:
- Código em Python (mas deve ser aplicado para qualquer linguagem)
#Sem ifs aninhados
# #O programa já sai da função e parte para a próxima etapa caso uma condição seja satisfeita
# #Menos linhas de código
# #Maior eficiência
# #padronização facilitando a leitura
def calc(argument1, argument2):
if (!argument1.is_valid()):
throw new Exception();
if (!argument2.is_valid()):
throw new Exception()
SomeObject otherVal1 = do_some_stuff(argument1, argument2)
if (!otherVal1.is_valid())
throw new Exception()
SomeObject otherVal2 = do_another_stuff(otherVal1)
if (!otherVal2.is_valid())
throw new Exception()
return "Stuff"Referência: Padrão Early Return
4.3 Nomeação de variáveis:
4.3.1 - Título:
- As variáveis deverão conter um título que descreva resumidamente o que ela armazenará. Use nomes semânticos: Escolha nomes que comuniquem claramente o propósito da variável. Por exemplo, em vez de dados, use dados_do_usuario ou dados_de_entrada.
- Seja descritivo: O nome da variável deve refletir seu propósito e significado no contexto do código. Isso ajuda a tornar o código mais legível e compreensível.
- Seja conciso: Evite nomes de variáveis muito longos. Tente manter os nomes curtos e significativos.
- Evite nomes genéricos: Evite nomes como x, y, temp, etc. Use nomes que descrevam o que a variável representa.
- Seja consistente: Mantenha um estilo de nomenclatura consistente em todo o seu código para facilitar a leitura e a manutenção.
4.3.2 - Idioma:
- Para universalização da leitura, o idioma utilizado para nomear uma variável será o inglês:
- Comentários e documentações devem ser escritos em inglês;
4.3.3 - Caixa (Case):
Python
- O título da variável deve ser escrito no modelo caixa baixa e alta, sem espaços, também conhecido como snake case Referência: Python.org
Javascript
- O título da variável deve ser escrito no modelo caixa baixa e alta, sem espaços, também conhecido como camel case
Exemplos:
Não Recomendados:
Python
python#Não descritivo #Não está em inglês #Não está em snake case ErrosencontradosemGER = []Javascript
javascript//Não descritivo //Não está em inglês //Não está em camel case ErrosencontradosemGER = []
Recomendados:
Python
pythongenerator_errors = []Javascript
generatorErrors = []4.4 Uso de constantes:
- Para valores do tipo string, numérico ou boleanos, caso eles sejam do tipo constante (que não se alterarão nunca durante a execução do programa), utilize sempre a declaração de constantes para melhor organização e leitura.
Exemplos:
Não Recomendados:
Código em Python
python#Não está claro o que cada número significa def some_calcs(argument1): diametro_turbina = 2 * 3.14 * 1.35 custo = 42 * calcula_custo_unitario()
Recomendados:
- Código em Python (mas deve ser aplicado para qualquer linguagem)
#Maior legibilidade
NUMERO_PI = 3.14
RAIO = 1.35
TOTAL_DE_TURBINAS = 42
def some_calcs(argument1):
diametro_turbina = 2 * NUMERO_PI * RAIO
custo = TOTAL_DE_TURBINAS * calcula_custo_unitario()4.5 Tipagem:
- Sempre detalhar nas nas funções que tipo de valores elas retornam:
#Maior legibilidade
def saudacao(nome: str) -> str:
return f"Olá, {nome}!"4.6 Funções devem fazer apenas uma coisa, e fazer bem:
Seguir o Princípio da Responsabilidade Única leva a um código mais limpo, modular, reutilizável e fácil de manter, o que é fundamental para o desenvolvimento de software de alta qualidade. Facilita a Manutenção do Código, Promove a Reutilização do Código, Aumenta a Legibilidade, Facilita os Testes Unitários, Ajuda na Evolução do Código
4.7 Quebre linhas muito longas:
Não Recomendados:
Código em Python
python# Quebre linhas longas para melhor legibilidade resultado = funcao_muito_longa(argumento_longo1, argumento_longo2, argumento_longo3, argumento_longo3)
Recomendados:
# Quebre linhas longas para melhor legibilidade
resultado = funcao_muito_longa(argumento_longo1,
argumento_longo2,
argumento_longo3,
argumento_longo3)4.8 Lançamento de Exceções
Ao criar uma estrutura Try/Except, procure criar uma estrutura que mapeie o tipo de erro que poderia acontecer e evite mensagens de erro genéricas que não dão detalhes ou dicas de como atacar o problema.
4.9 Estrutura de diretórios
Projetos em Python
Para melhor organização, leitura, filtragem e padronização de código, nos projetos em Python utilizaremos nos repositórios sempre o esqueleto de estrutura a seguir:
nome_do_projeto/
│
├── README.md
├── main.py
├── requirements.txt
├── setup.py
│
├── pacote_de_codigos_do_projeto/
│ ├── __init__.py
│ ├── modulo1.py
│ ├── modulo2.py
│ └── subpacote (opcional)/
│ ├── __init__.py
│ └── modulo3.py
│
├── scripts/
│ ├── script1.py
│ └── script2.py
│
└── testes/
├── test_modulo1.py
└── test_modulo2.py
Onde:
- README.md - Arquivo Markdown contendo detalhes importantes para o setup, inicialização e uso do projeto.
- requirements.txt - Arquivo contendo todas as dependências do projeto.
- setup.py - Arquivo contendo todos os detalhes para a distribuição do projeto
- arquivo init.py - Este arquivo é um marcador especial que indica ao interpretador Python que o diretório pacote_de_codigos_do_projeto deve ser tratado como um pacote Python.
- modulo1.py - Arquivo contendo o código (ou parte do código) do projeto
- diretório scripts - autoexplicativo
- diretório tests - autoexplicativo
Exemplos práticos de cada arquivo:
README.md
Nome do projeto:
- Descrição: Arquivo Markdown contendo detalhes importantes para o setup, inicialização e uso do projeto
requirements.txt
matplotlib==4.6.2 numpy==1.24.5 pandas==1.5.1
setup.py
from setuptools import setup, find_packages
setup(
name='mypackage',
version='0.1',
packages=find_packages(),
install_requires=[
# lista de dependências
],
)- __init__.py
# Arquivo __init__.py do pacote calculadora from .operacoes import somar, subtrair, multiplicar, dividir
4.10 - Para projetos em Python, desenvolva utilizando ambientes virtuais
É altamente recomendável usar ambientes virtuais para todos os projetos Python, independentemente de eles utilizarem ou não bibliotecas externas. Ambientes virtuais fornecem um ambiente isolado para cada projeto, garantindo que as dependências específicas do projeto sejam instaladas e mantenham-se separadas de outras dependências de outros projetos ou do sistema em si.
Mesmo para projetos simples que não dependem de bibliotecas externas, usar ambientes virtuais pode evitar conflitos entre versões de pacotes e garantir que o ambiente de desenvolvimento seja consistente em diferentes máquinas.
Portanto, é uma prática recomendada utilizar ambientes virtuais para todos os projetos Python. Isso pode ser feito facilmente usando ferramentas como virtualenv ou o módulo venv incorporado no Python 3.3 e posteriores.
Para outras linguagens, utilize o que for correspondente ao ambiente virtual. O mais importante é que o ambiente de desenvolvimento de todos do time trabalhando no mesmo projeto seja o mesmo
Na prática:
- Antes do desenvolvimento:
# Criando o ambiente virtual (no Linux, no Windows os comandos são diferentes)
python3 -m venv venv# Ativando o ambiente virtual
source venv/bin/activateDURANTE O DESENVOLVIMENTO:
# Instalar Dependências: Com o ambiente virtual ativado, instale as dependências do seu projeto usando o pip, por exemplo:
pip install nome_da_bibliotecaAPÓS O DESENVOLVIMENTO:
# Desativar o Ambiente Virtual: Quando terminar de trabalhar no seu projeto, você pode desativar o ambiente virtual:
deactivateDOCUMENTAÇÃO
Todo projeto deve ter um documento read.me. Esse documento deve ter:
- Nome do projeto
- Cliente (quem demandou)
- Coordenador(es)
- Descrição resumida
- Principais regras de negócio
- Descrição do uso e principais passos para a manutenção (Arquivos, Ambiente, Compiladores, Sistemas operacionais, etc.)
ATUALIZAÇÃO DO SISTEMA
Todos os dias, no início do dia, rodar o script de atualização do sistema operacional
sudo apt update && sudo apt upgrade -y
5. Utilitários
5.1 Uso de linters:
Para Python:
Pylint
Pylance
Python Debbuger
Para Javascript:
- EsLint
Para HTML:
- Prettier
5.2 Uso de completador de código com IA:
Qualquer um dos que estão em alta no mercado seriam úteis.
AWS Code Whisperer (grátis)
Github Copilot (pago)
Tabnine (freemium)
6. Referências:
Esse manual foi inspirado nos seguintes conteúdos:
Guia de estilo da linguagem Python