4 ms·
Are those objects in the queries and queues separate and distinct types then? And, what about the object store, what types go in there? How do we handle data
by EdSharkey 9y ago
Are those objects in the queries and queues separate and distinct types then? And, what about the object store, what types go in there? How do we handle data migrations?
I like queues as much as the next developer. Queues let you scale performance Mt Everest and deal with concurrency.
CQRS as an architecture is like queue abuse.
- UK-AL 9y agoYou don't have to use queues, separate objects/NoSQL store or anything like that to use cqrs. I mean you can use them, but all CQRS means is a separate code path for queries and commands. In my system I have command objects, they operate on domain objects which contain some business logic. I have query objects which just execute custom sql code which returns a populated view. This is useful because views often display specific data from multiple domain objects. This system allows you to bring back the entire view in a single query and nothing else, rather trying to retrieve multiple domain objects which are really designed for business rules rather than queries. Often yes, people do starting adding queues, materialised views to CQRS which can make it complicated.
- EdSharkey 9y ago> Often yes, people do starting adding queues, materialised views to CQRS which can make it complicated. You don't say?? You don't say?? Sorry to be flip, I hope you can tell that I've been burned. Badly. Thanks for your detailed response. You obviously care and are not a stupid person nor do you come off sounding vain. But, you're not selling me on CQRS at all. What you've described is just classifications and organization for types in a sane sounding UI design that happen to have similar roles as types in a CQRS system. If you were selling me on CQRS, you'd start by talking about data flow. Something like, "it's a realtime, live multiuser system where all commands are queued, transformed to system events, and those events are committed to log (via another queue, we have to synchronize after all) that stretches back into time. We can replay those events, rewind time, events are merged ..." And it goes on and on into the stratosphere of architecture astronaut-hood... My problem with your response is I honestly can't trust what you say here until I do a code review. Is your actual code pathological, or are you whitewashing the constant twizzling and niggling you have to do to keep your ship afloat? How bad, honestly, do you have to work to add a new feature? What's your velocity like? I want to see how much work and layers there are in your code to do data type transformation. Data transformation is where El Diablo lives, because data transformation requires lots of people to agree and business terms to meet code - it's the unholy marriage of garbage disposal, forest fire, and whirlwind. CQRS seems to invite needless data transforms that other architectures do not require, and that's the pukey taste in my mouth when I have discussions about CQRS.
- UK-AL 9y ago"it's a realtime, live multiuser system where all commands are queued, transformed to system events, and those events are committed to log (via another queue, we have to synchronize after all) that stretches back into time. We can replay those events, rewind time, events are merged ..." And it goes on and on into the stratosphere of architecture astronaut-hood..." But that isn't CQRS. That's event sourcing, a complicated implementation of event sourcing. CQRS can work on a standard SQL system, you can design the database using a standard normalised database. All that has to be different is that commands and queries are separate. A simple implementation; A command can literally be var command= new AcceptOfferCommand(db); command.Execute(); A query can be var query = new AvailableOffersQuery(db); var viewModel = query.Execute() Inside the command you may retrieve a domain object from repository, and execute a method on it. Inside the query method you may just perform a raw sql statement which grabs data from multiple tables, populates a viewModel and returns it. Rather trying to retrieve multiple domain objects from multiple repositories and then shuffling that data into a result.. That's one way of doing simple cqrs. It can be simpler than this. But this code just made it obvious. CQRS allows you do very complicated things, but it doesn't mean you have to.
- EdSharkey 9y agoAh, 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.