Código Limpo Dual

Preview:

DESCRIPTION

Apresentação sobre Código Limpo para os desenvolvedores Progress e .NET na empresa Dual.

Citation preview

CÓDIGO LIMPO

Melhorando a qualidade do código

Nomes significativos

Use nomes relevantes, que mostrem sua intenção int d; //quantidade de dias int dias; int diasAno; int diasAteFinalDeAno;

Não use o prefixos/sufixos só porque já existe a variável com o mesmo nome Produto x ProdutoInfo x ProdutoData lista, lista1, lista2, aLista, outraLista, listaFinal

listaFinal do quê?

Nomes significativos

Redundância A palavra variável nunca deve aparecer no

nome de uma variável. Assim como a palavra tabela nunca deve aparecer no nome da tabela.

Como é que NomeString é melhor que apenas Nome?

Use nomes pronunciáveis Facilita a leitura do código int qtdeDiaDpsFinAno; int quantidadeDiasDepoisFinalDoAno;

Nomes significativos

Métodos/funções Devem ser verbos ou frases verbais, ações.

Salvar() PodeSalvar() FoiSalvo() CalcularICMS() EstaValido() GerarFeriados() ObterProdutoAtivo()

Small!

“A primeira regra dos métodos é que eles devem ser pequenos, a segunda é que eles devem ser menores ainda.”

Robert C. Martin (Uncle Bob)

“Functions should do one thing. They should do it well. They should do it only.” O maior problema é saber o que é essa “uma

coisa”.

Exemplo: quantas coisas a função a seguir (Processamento de Pedidos) está fazendo?

Small!

É fácil mal interpretar e dizer que está fazendo 3 coisas: 1. Verificando se o pedido é válido 2. Processando pedido valido 3. Processando pedido inválido

Small!

A função tem 3 passos, mas esses passos estão no mesmo nível de abstração: Para Processar o Pedido, nós verificamos se

ele é válido; se sim, o processamos como pedido válido, senão, o processamos como pedido inválido.

O nível de abstração seria “Processar o Pedido”. O método não deve fazer nada além disso.

Por exemplo, o método não poderia Salvar o Pedido processado no banco, pois fugiria do Processar o Pedido.

Isso deveria ser feito por outra classe ou método.

Comentários

“Não comente código ruim – reescreva-o.”

Brian W. Kernighan

O melhor comentário é o próprio código. O que é melhor?

Ou...

SOLID

Princípio de Responsabilidade Única

Princípio de Responsabilidade Única

Uma classe ou método deve ter uma única responsabilidade.

Uma classe ou método deve ter uma e apenas UMA razão para mudar. Exemplo:

ValidarTotalItensPedido(Pedido pedido) 1. Valida se a soma dos Itens bate com o total do Pedido.

Se não bate, lê o parâmetro 103 do sistema para ver qual atitude tomar.

Toma a decisão que o parâmetro 103 propõe. O parâmetro diz para buscar a entidade principal...

2. Retorna se está válido ou não.

Princípio de Responsabilidade Única

Então como fazer nesse caso? ProcessarPedido(Pedido pedido)

estaValido = ValidarTotalItensPedido(pedido) SE estaValido = FALSE

ProcessarPedidoInvalido()

ValidarTotalItensPedido(Pedido pedido) Retorna se a soma dos Itens bate com o total

do Pedido. ProcessarPedidoInvalido()

LerParametro(103) BuscaEntidadePrincipal()

Princípio de Responsabilidade Única

Qual a vantagem disso? Ler o código e de imediato saber o que ele está

fazendo e como ele está fazendo. Ler como você estivesse lendo instruções ou até

mesmo um livro. Para Processar o Pedido, verifica-se o Total dos Itens

desse Pedido. Se o total não bater, o pedido é inválido. Para Processar um Pedido Inválido, lê-se o parâmetro

103, para descobrir qual providência tomar. De acordo com o parâmetro 103, busca-se a entidade

principal. Com a entidade principal...

Princípio Aberto Fechado

Princípio Aberto Fechado

Separação de Pedidos CRM Antes – SeparaPedidosNegociacao(...):

SE ehParaSeparaPedidos SeparaPorLinhaComercial()

SENAO PedidoUnico()

Princípio Aberto Fechado

Quebrando o princípio: Depois – SeparaPedidosNegociacao(...):

SE estrategia = POR_LINHA_COMERCIAL SeparaPorLinhaComercial()

SENAO SE estrategia = POR_REPRESENTANTE SeparaPorRepresentante()

SENAO PedidoUnico()

Princípio Aberto Fechado

Usando abstrações e Strategy Pattern: Depois – SeparaPedidosNegociacao(...):

estrategias = CarregarEstrategiasDeSeparacaoDePedidos()

PARA CADA estrategia EM estrategias SE estrategia.UsarEssaEstrategia()

estrategia.SepararPedido()

Inversão de Dependência

Inversão de Dependência

Módulos de alto nível não devem depender de módulos de baixo nível. Alto nível: regras e entidade de negócios. Baixo nível: acesso a dados: banco,

arquivos ou WebService. Módulos de alto nível devem utilizar um

mecanismo para obter os dados de baixo nível, mas não depender dos detalhes desse mecanismo.

Inversão de Dependência

ParametroDataAccess

SeparacaoPedidos

Inversão de Dependência

IParametroDataAccess

ParametroDataAccess

SeparacaoPedidos

Referências

Software Practices, Pluralsight Principles of Object Oriented Design Design Patterns

Clean Code A Handbook of Agile Software Craftsmanship, Robert C. Martin

DDD Quickly, Abel Avram & Floyd Marinescu Resumo de DDD por Eric Evans

Agile Principles, Patterns, and Practices in C#, Robert C. Martin