Hot answers tagged

85

You seem to suggest that the complexity of an interface is measured by the number of elements it has (methods, in this case). Many would argue that having to remember that the charge method can be used to return the balance of a Client adds much more complexity than having the extra element of the getBalance method. Making things more explicit is much ...


28

IMO, replacing getBalance() with charge(0) across your application isn't a simplification. Yes it is fewer lines, but it obfuscates the meaning of the charge() method, which could potentially cause headaches down the line when you or someone else needs to revisit this code. Although they might give the same result, getting the balance of an account is not ...


13

It's important to remember that your code should be self-documenting. When I call charge(x), I expect x to be charged. Information about balance is secondary. What's more, I may not know how charge() is implemented when I call it and I definitely won't know how it's implemented tomorrow. For example, consider this potential future update to charge(): float ...


11

Disclaimler: I'm only taking my first steps in the CQRS world, but I can offer my current understanding of the matter and we'll see if others confirm. All I write below has an underlying "as I see it" theme, and is not authoritative. The 80% case To answer your question, commands are indeed a point-to-point affair. When a command enters a controller (MVC ...


11

There are always trade offs to consider between conflicting design principles. The way to resolve it is to look at the underlying reasons behind the principles. In this case, being unable to run a query without running the command is problematic, but being unable to run a command without running the query is generally harmless. As long as there's a way to ...


10

Decoupling only works if there really is separation. Consider if you have an ordering system: Table: CUSTOMER Table: ORDER If that's all you've got, there's no reason to decouple them. On the other hand, if you have this: Table: CUSTOMER Table: ORDER Table: CUSTOMER_NEWSLETTER Then you could argue that ORDER and CUSTOMER_NEWSLETTER are part of two ...


10

You've run into a problem that many have before you...a database optimized for reading is seldom good for write efficiency and vice versa. One approach that has evolved from this read-write impediment is CQRS (Command Query Responsibility Segregation). Despite Wikipedia linking the two together CQRS and CQS are technically different. CQS just demands that a ...


8

To try and answer your question, lets look at where the pattern came from. Command Query Separation (CQS) where the querying will not change the state of the object (Only the commands would). The key point (in this context) is a class would consist of both Commands and Queries. Command Query Responsibility Segregation (CQRS), holds the same principal ...


8

Funny, this question just reminded me of exactly same conversation I had with one of our engineers about communications library I was working on. Instead of commands, I had Request classes and then I had RequestHandlers. The design was very much like what you are describing. I think part of the confusion that you have is that you see the English word "...


8

Perhaps it is too naive, but did you consider making a fresh database for your fresh application and writing some converter from the old (badly designed) database to the new one? That converter would be hard to code, but you'll get some more cleaner data from it.


7

Not sure that there is a 'one true way' answer for a design approach that, to be fair, is still evolving. First, DDD and CQRS are not the same thing although the CQRS folks seem to have derived from a DDD-influenced starting point. There's a lot going on in the DDD mindset and much of it has to do with properly defined boundaries of problems, communication ...


6

You shouldn't delete the events from your event store. These represent something that happened. If something happens now, then you should know it too, therefore add an event that will force your aggregate to go back to some previous state. That's a pity to delete information from your database. think about the example of the cart from greg young and the ...


6

Where I work we have an ESB to which 6 different applications (or should I say "endpoints") are connected. Those 6 applications work with 3 different Oracle schemas on 2 database instances. Some of these applications coexist in the same schema not because they are related but because our database infrastructure is managed by an external provider and ...


6

(Disclaimer: I am the author of Scritchy) I can not talk for the other frameworks, but in my case, Scritchy merely exists because I wanted to provide a quick and easy to use tool for writing CQRS apps, also taking away some of the burden of writing similar command handlers over and over... As the experts are saying: CQRS in it's most basic representation ...


6

I've seen the worst possible nightmares in software architecture due to data integration, and the best weapon against this type of mess that I've encountered so far id DDD-Style Bounded Contexts. Which is not very far away from "SOA done right", on a certain sense. However, data itself is not the best way to attack the problem. One should focus on the ...


6

The idea in Udi's post, as I gather, is that no kind of item appears out of thin air. There is (almost) always something, or more specifically, some domain operation, which caused the item to be created. Just like Udi's example of a user actually being born out of a visitor registering to the site. At that point and at that bounded context Visitor is the ...


6

What is "eventual consistency"? How does it compare to "transactional consistency"? When does it happen? Consistency models describe how a system (nominally a distributed system) responds to change. In an eventually-consistent system, all nodes will eventually have a consistent view of the overall system state. However, there will be a period of time ...


6

You could use an index. This is generally not something that you will find in an eventstore, so you will most likely need to use an external indexing engine for this. This index would then have to be updated everytime that someone changes a carts contents, and this index update would most likely be async. This would mean that you cannot rely on your index ...


5

Decoupling databases and keeping the data consistent between them is an expert level task. It is very easy to get wrong and end up with the problems of duplicates etc, that the current system is designed to avoid. Frankly, taking a working system and doing this is pretty much a guarantee of introducing new bugs for no real value to the users.


5

REST works OK with a command model... the commands basically become nouns, or worker resources. So instead of using /blah/blah/SearchByName You'd have a "search" (noun) resource /blah/blah/search?Name= I've always felt that's kind of a word game, but it does has the benefit of keeping your semantics resource oriented. In the case where the ...


5

How should I deal with this legacy data that "breaks the rules". So the starting point is to talk to your domain experts. What do they do with the "invalid" data in the legacy system today? Also, is the legacy system the book of record? or does it describe entities that are actually controlled somewhere else? A mix of both? You may need to consider ...


4

There are several ways of going about this. You know your team best. It's best to ask yourself at what level of abstraction you need to speak for them to comprehend. Cqrs is really about seperating read logic from write logic. This is best explained by comparing it to todays layered architecture as promoted by database vendors (video section over on http://...


4

I haven't heard of Command-Query-Separation(CQS) before, but it seems that it would relate to Single Responsibility Principle(SRP), which states that a function/class ideally should be responsible for doing one thing and one thing only. If your command code is 20 lines of code and query code is another 30 lines and they are all in one function body, clearly ...


4

CQRS and DDD are separate/orthogonal concepts, and I think you divided the terms pretty close to right. Events under DDD are called Domain Events, and are somewhat different from the Messaging events often mentioned with CQRS. Messaging events usually have more to do with Event Sourcing. Your CQRS category is a conglomeration of a number of patterns, and ...


3

I tend to resolve these naming conflicts by simply choosing different names. Perhaps you have already started calling these things by different names internally, if so, have the codebase reflect that. If not, think of something (UserCommand vs WriteCommand, Command vs Request, Action vs Command...) Basically, the overloading of the word "command" creates ...


3

For completeness I thought to include an relevant snippet from Martin Fowler about ways to revert state: As well as events playing themselves forwards, it's also often useful for them to be able to reverse themselves. Reversal is the most straightforward when the event is cast in the form of a difference. An example of this would be "add $10 to ...


3

I'd do the simplest possible thing that would work, which (for me) would be to keep everything in a database. I'd probably store the media outside the database, just to reduce the load on the connection pool (transferring several GB of data can tie up a DB connection for a long time), but other than that just keep it simple. Write every configuration ...


3

With multithreading, you just can't separate queries and commands, unless you have an external lock which serializes calls. The usual approach looks like this: // query + command // moves value at top into external thread-local storage `value` // may fail and return `false` bool ThreadSafeStack::try_pop(Value& value) { lock_guard guard(m_lock); //...


3

Besides "CQRS" solutions, what's often applied is an ESB (Enterprise Service Bus). CQRS is all around messaging and these types of frameworks exist around messaging. MassTransit http://masstransit-project.com/, https://github.com/MassTransit/MassTransit NServiceBus http://www.nservicebus.com/, https://github.com/NServiceBus/NServiceBus Eh, BizTalk, sorta. ...



Only top voted, non community-wiki answers of a minimum length are eligible