A separação de comando / consulta se aplica a um método que cria um objeto e retorna seu ID?

12

Vamos fingir que temos um serviço que chama um processo de negócios. Esse processo chamará a camada de dados para criar um objeto do tipo A no banco de dados.

Depois, precisamos chamar novamente outra classe da camada de dados para criar uma instância do tipo B no banco de dados. Precisamos passar algumas informações sobre A para uma chave estrangeira.

No primeiro método, criamos um objeto (estado de modificação) e retornamos seu ID (consulta) em um único método.

No segundo método, temos dois métodos, um (createA) para o salvamento e o outro (getId) para a consulta.

    public void FirstMethod(Info info)
    {
        var id = firstRepository.createA(info);           
        secondRepository.createB(id);
    }

    public void SecondMethod(Info info)
    {
        firstRepository.createA(info);
        var key = firstRepository.getID(info);
        secondRepository.createB(key);
    }

Pelo meu entendimento, o segundo método segue a separação da consulta de comando mais completamente. Mas acho um desperdício e contra-intuitivo consultar o banco de dados para obter o objeto que acabamos de criar.

Como você reconcilia o CQS com esse cenário?

Apenas o segundo método segue o CQS e, em caso afirmativo, é preferível usá-lo neste caso?

Gilles
fonte
2
se A e B forem criados juntos com qualquer frequência, provavelmente faria um procedimento armazenado criar ambos de uma só vez, e então você eliminaria o potencial de criar um B primeiro ou um A criado sem um B, se esses forem problemas.
Ryathal
Entrar no final do jogo para oferecer a opção de usar um parâmetro out. Tecnicamente, não é um valor de retorno! ;)

Respostas:

13

O CQS é uma diretriz e não uma regra absoluta. Veja o artigo da wiki para exemplos de atividades impossíveis sob CQS estrito.

No entanto, nesse caso, se você quiser manter o CQS, poderá criar o ID no lado do cliente (como um GUID) ou o cliente poderá solicitar um ID do sistema antes de criar qualquer objeto, o que parecer mais limpo. eu do que criar o objeto e depois consultá-lo (mas é mais difícil do que apenas usar uma coluna de identidade).

Pessoalmente, eu apenas retornaria o ID e o chamaria de uma daquelas situações em que o CQS não é um bom ajuste.

Outro bom artigo com exemplos: Martin Fowler

Misko
fonte
3

Se você segue uma metodologia e ela parece levá-lo a caminhos ruins, você deve reavaliá-la.

Vejo que o identificador de um objeto recém-criado é uma coisa válida para ter como parâmetro de retorno - não é apenas conveniente, mas também é "bom" - como você pode ver, o código é melhor quando o faz.

De qualquer forma, não estou familiarizado com "separação de consulta de comando", mas duvido muito que ele não permita que os comandos retornem informações sobre a execução do comando e, se houver, lixeira - o sucesso / falha está sempre lá, e eu faço não pense que "seu objeto foi criado OK" de "seu objeto foi criado OK e seu ID é xxx" para ser muito diferente.

alex
fonte
-1

Somente o segundo método segue o CQS.

Considero o CQS uma diretriz para incentivar boas práticas de codificação. Use boas práticas de codificação durante o desenvolvimento e, se descobrir mais tarde que esse método contém código crítico de recursos, você ainda poderá otimizá-lo.

Otimização prematura é a raiz de todo o mal :)

cheesus diz parar de atirar mods
fonte
O que é particularmente bom no segundo método?
CheatEx
Eu não disse que o segundo método é 'bom'. Eu disse que segue o paradigma CQS. Se você não seguir o CQS, suponho que o segundo método não seja bom para você. Se você quer saber por que algumas pessoas tentam seguir CQS, consulte http://en.wikipedia.org/wiki/Command-query_separation
cheesus diz mods parar de disparar
Você disse que o CQS está incentivando boas práticas de codificação, se for verdade, devemos observar algum tipo de "bondade" no segundo método. Cadê?
CheatEx
Aparentemente, você não leu o link que forneci. Frase do CQS: Fazer uma pergunta não deve alterar a resposta . No seu primeiro método, você tem um método ('createA') que fornece uma 'resposta', mas ele muda a resposta toda vez que você pergunta. No segundo método, você não tem isso, essa é a 'bondade' nele. Para ser claro: não sou purista do CQS, não o sigo o tempo todo.
cheesus diz para de disparar mods