Separando comandos e consultas

Separando comandos e consultasOlá, leitores! Se eu pedir para que vocês leiam um livro e escrevam um artigo ao mesmo tempo, vocês conseguiriam? Provavelmente não! O objetivo deste artigo é justamente demonstrar essa analogia na programação e o risco de introduzir funções “escondidas” no código. Prontos para mais um artigo sobre Clean Code?

Certo dia, a mãe de João diz: “Filho, vá comprar batatas para o almoço”. Mais tarde, além das batatas, João também volta com tomates, irritando a mãe, que diz: “Você não deveria ter comprado os tomates, não era necessário!”. Porém, João retruca: “Mãe, sempre quando vou comprar batatas, você também me pede para comprar tomates. Já me acostumei”.
Agora, imagine se um método de uma classe fizer algo que não deveria, mas que foi imposto pelo desenvolvedor. Ao invés de irritar a mãe, irritaríamos centenas ou milhares de usuários.

Considere o código abaixo e verifique se há algo de estranho:

function VerificarEstoque(const CodProduto: integer): integer;
begin
  try
    Query1.SQL.Clear;
    Query1.SQL.Add('Select Estoque from PRODUTOS where Codigo = :pCodProduto');
    Query1.ParamByName('pCodProduto').AsInteger := CodProduto;
    Query1.Open;
 
    if Query1.FieldByName('Estoque').AsInteger > 0 then
    begin
      AplicarDescontos;
      GerarBaixaNoEstoque;
    end;
 
    result := Query1.FieldByName('Estoque').AsInteger;
  finally
    Query1.Close;
  end;
end;

Descobriu?
Em primeiro lugar, o método acima possui “funções escondidas”, causando um efeito colateral no código. Observe que, embora o nome do método seja “VerificarEstoque”, ele também aplica descontos e gera a baixa no estoque. Qualquer desenvolvedor que encontrar a chamada deste método, jamais irá imaginar que ele também realiza essas duas operações adicionais.
Esse é o tipo de situação em que o mesmo método é chamado em situações diferentes, provocando inconsistências. Ao emitir um pedido de compra, o método funciona perfeitamente. No entanto, ao chamá-lo em outras situações, como na emissão de um orçamento, consulta de um produto ou no relatório de inventário, haverá uma baixa no estoque desnecessária, aliás, incorreta. E então, o desenvolvedor se pergunta:

“Por que o método gera a baixa se estou somente verificando o estoque?”

O motivo é que existe uma função “camuflada” no método e que não deveria estar lá! Ou seja, o método está fazendo mais do que lhe foi incumbido. Se a responsabilidade do método é somente verificar o estoque, então que seja somente isso!
A situação acima causa um efeito conhecido como Acoplamento Temporário, que significa a dependência entre os métodos que são invocados. Para resolver a baixa incorreta, o desenvolvedor terá de incluir condições dentro do método ou, ainda pior, duplicar o método e chamar cada um em ocasiões distintas. Nem preciso dizer a confusão que isso causa, não é?

O segundo problema no código acima diz respeito ao tipo de responsabilidade que o método exerce. Além de uma consulta (do estoque), ele também realiza algumas operações nas quais deveriam estar separadas deste método. Nenhum método deve realizar duas coisas ao mesmo tempo, caso contrário, também estará sujeito a criar efeitos colaterais no comportamento do software. Isso é o que definimos como Separação Comando-Consulta no contexto do Clean Code, originalmente conhecido como CQSCommand Query Separation. Um método deve possuir somente uma responsabilidade: realizar uma consulta ou executar uma operação.

Métodos cujos nomes contêm verbos como “Verificar”, “Consultar”, “Retornar” e “Obter” devem deixar claro que não realizam operações de escrita, apenas de leitura. Por outro lado, “Gravar”, “Executar”, “Salvar” e “Registrar” são verbos que condizem com ações e devem ser utilizados em nomes de métodos que têm esses comportamentos. A maior vantagem dessa separação é a transparência trazida ao código, evitando tanto as funções escondidas quanto a dupla responsabilidade.

Pessoal, por hoje é só! Lembrem-se de separar comandos e consultas!
E nem tentem ler um livro e escrever um artigo ao mesmo tempo. No final das contas, você não vai conseguir fazer nem uma coisa e nem outra, rsrs.
Abraço!


Compartilhe!
Share on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Pin on PinterestEmail this to someone

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Preencha o campo abaixo * Time limit is exhausted. Please reload CAPTCHA.