It's not about Creation, it's about Mutation

When building systems, we've for decades now tried to lump properties together into cohesive bundles. We've created Customer objects, Order objects; arguing that "well - a system must support Customers, right?" Well, yes - and it's easy to get started that way. The issues with the Customer object, to make a concrete point, is that one model cannot possibly encompass all aspects of a real person or a company - a Customer - that we are trying to model. Furthermore, we often want to track people - potential customers - before they've bought something (which is arguably the definition: once you buy something from someone or enter a contract that promises that you will, you're not really a customer, are you?).

This is all to say, that whereas it's easy to create a Customer class early on in a greenfield project to encompass customers, your professional life will be must better spent if you focus on Mutation rather than Creation: Things that Change together should be Stored together.

Some suitable questions you could ask yourself, are: 

- Does it make sense that a customer's first name changes, when their postal address changes? No? Then, they should not be stored together.
- Does it make sense that a customer's e-mail address changes when their mobile phone number changes? No? Then, there's no homogenous ContactInformation class/table either.
- Does it make sense that a customer's zip code changes when their street name changes? Yes, that probably makes sense - a PostalAddress model should contain all required fields to successfully send a parcel to the customer.

The next set of questions to ask yourself would be - what causes an entity to change? Take the address one again - the customer's address changed because ... the customer moved, most likely. Therefore you'll want to store the event leading up to the eventual mutation as well: CustomerMoved (Guid customerId, Guid addressId, DateTimeOffset utcTimestamp). If you need to handle misspellings, then create another event for AddressCorrected or somesuch.

In short, model your systems with small models, representing areas of change. Just because you can Create a large object with a bazillion properties up front, doesn't mean it makes sense to Change all of the properties at once. Design your systems to cope with Change.

Comments

Popular posts from this blog

Auto Mapper and Record Types - will they blend?

Unit testing your Azure functions - part 2: Queues and Blobs

Testing WCF services with user credentials and binary endpoints