4 ms·
Ah, well CQRS is only justifiable when you're selling the work if you couple it with the ES, and the more complex it is, the better the sales job and the budget
by EdSharkey 9y ago
Ah, well CQRS is only justifiable when you're selling the work if you couple it with the ES, and the more complex it is, the better the sales job and the budget. It's like peanut butter and jelly.
My main point in replying to you was that you weren't selling me on whatever brand of CQRS you think you've got. Why? It seems like you're atomizing your business logic into a fine mist, why is that good? And you still haven't talked about all the myriad transforms you do: where's the payoff? Does YAGNI apply in your case?
- UK-AL 9y agoWell each command is a use case. Each use case can be tested independently without having setup controllers and their dependencies, or big service layers and their dependencies. Plus I can run the usecases from a console frontend for quick testing without much setup. I don't really do any transforms other than mapping domain objects into the dB or database results into a query result. Why do I need it? Because I practise DDD, and domain objects are not designed for queries. To populate a single view you have pull multiple domain objects from repos. This can be slow and adds complexity. Query objects allow me to query the database using standard SQL or stored procedure and put the output into query result using only a single query. These queries can as complicated and optimised as they need to be. Meaning I can avoid all DDD abstractions that I don't need for querying, but I do need for enforcing complicated business rules on the command side.
- EdSharkey 9y agoIf you're able to reuse (through encapsulation or extension) your domain object types in your commands and queries without transformations, then your pattern sounds sane to me.
- bonesss 9y agoThe entire point of the Separation in CQRS is to avoid unnecessary coupling between reporting concerns, GUI concerns, and user concerns. The act of starting an order does not look like an order. Asking for an order cancellation does not look like an order. Using GraphQL to pull an order summary with report-specialized drill down capabilities does not look like an order. These specialized domain objects should be modeled individually. By trying to encapsulate all these facets in a single object what you get is tight coupling, compromises, domain impedance, logical errors, and slow development. In context: One of the root principles of DDD is that each domain represents its entities as is befitting that domain. Domain entities should be meaningful in their domain and _not_ corrupted by every niggling redigestion of the same facts through tens, or hundreds, of simultaneous conflicting views... Reporting concerns should be first-class citizens when solving reporting, for example.... View concerns and high-load systems often require denormalization, materialization, transformation, and replication that has very little to do with the user of origin while also _destroying_ the premises of traditional ORM driven RMDB interactions. At scale, under load, while supporting multiple N-tiered applications and their accordant services, unified domain models break down. Aggregate boundaries map these epistemological distinctions. CQRS on top of that is just good engineering. In the same way modern car-tunnel builders build two separate tunnels for traffic in each direction, CQRS isolates low-frequency user interaction from high-frequency reporting (or vice versa!), allowing independent scaling and direct delivery of features without impossible coordination activities between teams or finding silver-bullet technologies that may or may not exist. That said: these are Enterprise solutions to Enterprise issues... Scale is the reason they exist. If you aren't looking at a horrible mess around a unified domain model then these solutions might not apply. If you aren't dealing with multiple simultaneous data delivery platforms (mixing SQL server and Oracle and Mongo DB and S3 and DocumentDB and DynamoDB all at once), these solutions may not apply. If you're not balancing multiple teams working on multiple products that have a constant need for harmonic data exchange, these solutions may not apply. If you're not juggling BigData, if you're not dealing with complex business logic, if scaling up an extra ten thousand users isn't something you deal with, if you're not supporting multiple client types, and so on: these solutions may not apply.
- EdSharkey 9y agoSounds really complicated, like "usually badly designed and written code" complicated. GraphQL and Falcor are interesting, and I like the sort of query-as-befits-the-view aspect to working with it. Taking a wait-and-see on those.
- bonesss 9y agoCommands are objects that express a command. A query is something that provides a value. You can code it up in minutes, and most of the code is pure plumbing to connect to datasources. If that sounds complicated to buy independent control over data exchange then you're simply not exposed to the complex multi-layered and distributed applications that demand a structured approach to the issues CQRS handles. Unquestioned and implicit assumptions are great for small potatoes. Domains should model domains and reflect the mental models of the people who work on, and with, the system. If that is experienced as complicating the only conclusion is that you're working with subject material neither complex nor interesting enough to warrant a considered architectural approach. For someone who deals with computing (currying, monads, SOLID, etc), you should know that trying to meaningfully translate superficial domain complexity to generalizations of code quality or design quality of any given solution in all domains is laughable.
- EdSharkey 9y agoLaugh away, I'm not interested in flashy code nor resume padding. I am interested in SOLID, clean code. If you have clean code that is easy to add new features to, refactor, and teach to new developers, then good for you. I know good code when I see it. It is clear to me when developers lose sight of the forest for the trees. Your sales technique makes your project sound like torture.
- bonesss 9y agoI'm not selling anything, and you clearly are missing the forest for the trees while making assumptions & assertions about unfamiliar things. CQRS boils down to a single principle: two one-way roads make for easier road maintenance and improvement that one two-way road. Two individual channels are too complicated to code? Torturous? Inherently badly designed? Hard to add new features too? Unclean? ... Crazy talk, unsupported by reality. In fact: CQRS specifically addresses all these points you've brought up through its decoupling. Those kinds of prejudiced assumptions do not hold water, cannot be logically supported by the underlying design nor in-production systems, and reveals only domain ignorance. Successful engineering around distributed Enterprise systems tells a clear story: those maintenance and improvement concerns are predominant at scale. Opinions may vary... Informed opinions on this matter do not.