Quão granular deve ser um comando em um modelo CQ [R] S?


17

Estou pensando em um projeto para migrar parte de nossa SOA baseada em WCF para um modelo de barramento de serviço (provavelmente nServiceBus) e usando alguns pub-sub básicos para obter a Separação de Consulta de Comando .

Não sou novo em SOA, nem mesmo em modelos de barramento de serviço, mas confesso que até recentemente meu conceito de "separação" estava limitado ao espelhamento e replicação de bancos de dados comuns. Ainda assim, sinto-me atraído pela idéia, porque ela parece fornecer todos os benefícios de um sistema eventualmente consistente , enquanto evita muitas das desvantagens óbvias (principalmente a falta de suporte transacional adequado).

Eu li muito sobre o assunto de Udi Dahan, que é basicamente o guru das arquiteturas ESB (pelo menos no mundo da Microsoft), mas uma coisa que ele diz realmente me intriga:

À medida que obtemos entidades maiores com mais campos, também temos mais atores trabalhando com essas mesmas entidades, e maior a probabilidade de que algo toque algum atributo delas a qualquer momento, aumentando o número de conflitos de simultaneidade.

[...]

Um elemento central do CQRS é repensar o design da interface do usuário para nos permitir capturar a intenção de nossos usuários, de modo que tornar o cliente preferido seja uma unidade de trabalho diferente para o usuário do que indicar que o cliente mudou ou que conseguiu casado. O uso de uma interface do usuário semelhante ao Excel para alterações de dados não captura a intenção, como vimos acima.

- Udi Dahan, CQRS esclarecido

Da perspectiva descrita na citação, é difícil argumentar com essa lógica. Mas parece ir contra o grão em relação aos SOAs. Uma SOA (e realmente serviços em geral) deve lidar com mensagens de granularidade grossa, de modo a minimizar as conversas na rede - entre muitos outros benefícios.

Percebo que as conversas na rede não são um problema quando você tem sistemas altamente distribuídos com boas filas de mensagens e nenhuma bagagem de RPC, mas não parece aconselhável descartar completamente o problema. Udi quase parece estar dizendo que toda alteração de atributo (ou seja, atualização de campo) deve ser seu próprio comando, o que é difícil de imaginar no contexto de um usuário que potencialmente atualiza centenas ou milhares de entidades e atributos combinados, como costuma acontecer com um servidor tradicional. serviço de internet.

Uma atualização em lote no SQL Server pode levar uma fração de segundo, dada uma boa consulta altamente parametrizada, parâmetro com valor de tabela ou inserção em massa em uma tabela de teste; o processamento de todas essas atualizações, uma de cada vez, é lento, lento, lento e o hardware do banco de dados OLTP é o mais caro de todos para aumentar / diminuir .

Existe alguma maneira de conciliar essas preocupações concorrentes? Estou pensando da maneira errada? Esse problema tem uma solução conhecida no mundo CQS / ESB?

Caso contrário, como alguém decide qual deve ser o "nível correto" de granularidade em um comando? Existe algum "padrão" que se possa usar como ponto de partida - como o 3NF nos bancos de dados - e apenas desviar quando o perfil cuidadoso sugerir um benefício de desempenho potencialmente significativo?

Ou isso é possivelmente uma daquelas coisas que, apesar de várias opiniões fortes serem expressas por vários especialistas, é realmente apenas uma questão de opinião?

Respostas:


7

No tópico "cada alteração de atributo"

Você não entendeu. O Sr. Udi Dahan está dizendo que você deve capturar a intenção do usuário como um comando. Um usuário final está preocupado em poder indicar que um cliente foi movido. Dependendo do contexto em que o comando possa conter uma identificação do cliente, o novo endereço (dividido em rua, número da rua, CEP, ...), opcionalmente, um novo número de telefone (não incomum quando você se move - talvez menos com todos esses celulares) . Esse dificilmente é um atributo. Uma pergunta melhor é "como faço para projetar comandos?". Você os projeta de uma perspectiva comportamental. Cada caso de uso, fluxo, tarefa que um usuário final está tentando concluir, será capturado em um ou mais comandos. Os dados que acompanham esses comandos vêm naturalmente, à medida que você começa a argumentar sobre eles com mais detalhes. O que deve ser observado são os dados que são interpretados como "pode ser uma indicação de que você precisa dividir o comando. Espero que você nunca encontre esse padrão em relação à granularidade de comandos. Boa pergunta!


Essa definição ainda parece muito arbitrária para mim; o modelo conceitual de um CSR pode agrupar o status preferencial e o status marcial da mesma maneira que agrupa o endereço e o código postal. Não pretendo dividir os cabelos, apenas me parece que, para realmente entender se são comportamentos diferentes, você precisa prever os efeitos a jusante, e OTOH toda a ideia de ESB e CQS e pub / sub é que você não deveria saber ou se importar com o que acontece a jusante. Obrigado pela sua resposta, eu aprecio isso, embora eu não posso dizer que me sinto mais iluminado até agora ...
Aaronaught

@Aaronaught: A definição é arbitrária. A granularidade de um comando deve ser o que fizer sentido para o seu cenário específico . Não existe um tamanho único para todos. Existem várias diretrizes, como a correspondência de comandos para usar casos, tarefas ou ações disponíveis na interface do usuário - outra é preferir comandos mais granulares do que comandos menos granulares (principalmente como Yves disse desconfiar dos dados que são interpretados como fluxo de controle lógico) - mas nenhuma regra rígida e rápida. Existe um cenário real em que "um usuário atualize potencialmente centenas ou milhares de entidades e atributos combinados"?
Quentin-starin

Esse é o ponto! Não se amontoem. Divida de acordo com o comportamento! Não coloque dados no comando que não esteja alinhado com a intenção do comando / usuário final. E isso não é sobre sistemas a jusante.
Yves Reynhout 8/04

@ qes: Em nossos sistemas, existem vários cenários, muito reais e muito necessários. Para declarar da maneira mais simples possível, eles precisam modificar seqüências inteiras de dados e essas sequências só fazem sentido como sequências. É claro que eles geralmente não fazem essas alterações registro por registro, aplicam algum algoritmo à maior parte dele e corrigem algumas exceções. Talvez este não seja apenas um cenário apropriado para o CQS, mas essa decisão é apenas um subconjunto da minha pergunta mais ampla.
Aaronaught

1
@ qes: É justo, e isso é uma resposta por si só. Eu certamente entendo o conceito de uma operação lógica (é assim que os serviços existentes são modelados), acho que apenas me preocupei que o CQS pareça alterar algumas das regras sobre como você deve definir uma operação. A SOA "tradicional" parece começar da definição mais grosseira possível e descer a escada de abstração, se necessário; meu entendimento do CQS até agora parece indicar o contrário, comece pela definição mais granular possível e abstrata se parecer muito com RPC ou fluxo de controle.
Aaronaught

2

A mensagem que Udi está tentando transmitir é que o CQRS é mais do que apenas CRUD. Por que eu criei esse registro? Por que estou mudando esse registro? Por que está sendo excluído / marcado como excluído?

Os comandos devem corresponder às ações / casos de uso que o usuário faz com o sistema e expressar a intenção da ação, em vez de apenas dizer mudar isso. Além disso, pode parecer com uma granulação mais fina, mas pode ser muito mais grossa do que parece à primeira vista. Por exemplo, a atualização para o status gold pode envolver uma alteração em vários atributos e vários outros agregados podem até responder e mudar em resposta ao evento correspondente.

O CQRS trata da captura do idioma dos negócios na camada Serviço, para que a interface do usuário não precise se preocupar com o que acontece quando eu faço a atualização do status gold ou a remessa foi marcada como não entregue pela transportadora ou o funcionário foi promovido ao gerente do grupo de tecnologia. Bem, tecnicamente, eu estou falando sobre o Event Sourcing agora, mas você entendeu. Existem mensagens mais distintas, mas elas não são necessariamente mais refinadas que o CUD padrão.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.