[Conceitos] Command-Query Separation (CQS)

Blz, pessoal?

Retornando com mais um conceito neste post curto. Desta vez, falarei sobre o Command-Query Separation (CQS), princípio proposto por Bertrand Meyer.

Este princípio diz que um método pode ser um comando ou uma query, mas nunca ambos.

Um comando é um método que altera o estado do objeto que o define, não retornando nenhum valor:

public void AlterarEndereco(Endereco novoEndereco)
{
    this.endereco = novoEndereco;
}

Já uma query retorna algum resultado sem alterar o estado do objeto que a define. Em outras palavras, queries são funções livres de efeitos colaterais (side-effect-free functions):

public double CalcularMedia()
{
    return (this.X + this.Y) / 2;
}

Seguindo essa guideline, seus métodos ficam mais claros e com um único objetivo (o Princípio da Responsabilidade Única também deve ser considerado em métodos).

Além disso, eles passam a ser mais confiáveis. Uma query pode ser chamada mais de uma vez em sequência sem resultados indesejados. Outra forma de pensar sobre isso é que “uma query responde uma pergunta e responder uma pergunta não pode alterar a resposta”.

Portanto, vale a pena considerar esse princípio ao escrevermos nosso código.

Já consideraram? Quais os exemplos mais comuns que quebram esse princípio?

Até a próxima!

Anúncios

8 comentários em “[Conceitos] Command-Query Separation (CQS)

  1. Bem legal esse conceito!
    O padrão Find or Create não vai totalmente contra esse conceito?

    1. Olá, Francisco!

      Se seu método não altera o estado do objeto, ele continua atendendo o CQS (continua sendo uma query), pois ele não tem efeitos colaterais (você poderia chamar o método 2 vezes, por exemplo, que o resultado seria o mesmo), mesmo que ele esteja fazendo isso ora buscando um já existente, ora criando um novo.

      Ficou claro?
      Qualquer coisa, estamos aí.
      []s!

      1. Entendi sim, valeu pela explicação! Ficou bem claro e didático, parabéns pelo post, bem legal 🙂

  2. Haha! Martin Fowler deu um ótimo exemplo de quebra desse principio no Java, no C# poderíamos considerar o MoveNext do IEnumerator, Retorna True ou False, e move o enumerador para próxima posição, não sei se entraria no caso os métodos Try[AlgumaCoisa] da vida. Bom, o próprio Meyer disse que há exceções a esse princípio não? Que no caso seria:
    Desafio qualquer um a dar um ‘pop’ numa ‘stack’ sem quebrar esse principio.

    1. Parabéns!! 🙂
      Pois é, tem coisas mais conceituais que acabam sendo assim. Se está desempilhando já entrega o item retirado da pilha (“Normal”).

      Enfim, o CQS é um ótimo guia a se seguir pra escrever código limpo, mas tudo tem suas exceções.

      []s

Participe! Vamos trocar uma ideia sobre desenvolvimento de software!

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s