Know what Joe and Waldo have in common? We can’t find either, as this week, it’s just Allen and Michael to continue the dive into Domain Driven Design.
- FreshBooks.com/Coding – Use code “CODING BLOCKS” in the “How Did You Hear About Us?” section
- Linode – Use code “CODINGBLOCKS17” for $20 towards hosting (up to four months free!)
Start Slack’ing Now.
We’re so happy you’ve found us and now it’s time to become a part of the community. Head to https://www.codingblocks.net/slack to join in on the fun today.
Survey says …
This week, our stand-in Joe, JoeRecursionJoe, asks us to ask: How many monitors do you use?
- Thanks to everyone that left a review!
- iTunes reviews: polymorphcrism, Vijay Duvvuri, SoundsNeedWork, Brett Santore, Bisraelwalter
- Stitcher reviews: Still Useful for JS
- The Order domain object vs the OrderBatch domain object.
- Be a thought leader – do tech-talks with your group of developers at your job…
- Grab your Energy Sword – the Halo Championship Series comes to Atlanta – https://atlanta.dreamhack.com/17/
Want some Coding Blocks swag? Check out https://www.codingblocks.net/swag to get the things you need.
- “[Constraints] often emerge implicitly, and expressing them explicitly can greatly improve a design.”
What is a constraint?
- A constraint can be as simple as a boundary check, i.e. <, >, <=, >=
- Instead of _just_ using the math, instead, put that logic into a specific method. Or a class.
- A fundamental concept in MODEL-DRIVEN-DESIGN is that it’s easy to “see” relationships in the model
- By giving it a name, we can now discuss it as necessary
- By giving it an intention-revealing name, others will understand it’s purpose without caring about its implementation
- If a constraint obscures the objects responsibility, it may be time to factor that constraint out into a separate class or set of classes with relationships
- This can be done using the Strategy Design Pattern – example in the book uses the overbooking policy from Shipping Cargo p. 17
How to know that your class is distorted by constraints
- “Evaluating a constraint requires data that does not otherwise fit the object’s definition.”
- “Related rules appear in multiple objects, forcing duplication or inheritance between objects that are not otherwise a family.”
- “A lot of design and requirements conversation revolves around the constraints, but in the implementation, they are hidden away in procedural code.”
Processes as Domain Objects
- So, procedural code in our model right? Well no.
- An example is a service
- A service allows us to express a process explicitly and encapsulate any complex logic within it.
But, what if it can be done in multiple ways?
- Make the algorithm, or some key part of it, an object of its own
- Each “process” object represents a different *strategy*
Q: How to tell when a process should be explicit?
- Do domain experts talk about this process?
- If so, make it explicit
- No, it’s just part of the overall mechanism.
- If so, keeping it hidden is OK. Maybe even preferred.
Before we get into what the pattern is, let’s talk about how things typically are done … You have a class with complicated validation / business rules and you start baking all that into methods in your class – it quickly becomes hard to reason. OK, that didn’t work so well, let’s move that logic out into a layer abstracted away – now your domain object has lost it’s meaning and it’s more or less turned into a property bag and your application layer has gotten very complicated.
- “Business rules often do not fit the responsibility of any of the obvious ENTITIES or VALUE OBJECTS”
- Moving those business rules out of the domain object is not the answer because now the object model is no longer expressive
- “A specification states a constraint on the state of another object, which may or may not be present.”
- “… a specification can test _any_ object to see if it satisfies the specified criteria.”
- Specifications are VALUE OBJECTS
- Specifications keep the rules in the domain layer.
- Why? As business rules become increasingly complicated in an object, the clarity of the role of the object can get lost in all the conditions
- Nice example of the specification pattern: https://www.codeproject.com/Articles/670115/Specification-pattern-in-Csharp
Another use for factories
- Use a factory to create/configure a specification using information from multiple sources
- This way, only the factory has those or knows of those dependencies, keeping your domain objects clean
Applying and Implementing
- To validate that an object is ready to fulfill some need
- To select objects from a collection
- Specify creating a new object for a specific need
Another way to use repositories
- Because repositories are the mechanism for querying access to domain objects, specifications are a great fit
What is a specification not?
- It is not a filter for preexisting objects. That’s querying.
- It is not a test for an existing object. That’s validation.
So what is it?
- A whole new object, or set objects, are created or configured to satisfy a specification.
- “If a developer must consider the implementation of a component in order to use it, the value of encapsulation is lost”
- Clean Code anyone?!
- “The names of classes and methods are great opportunities for improving communication between developers…”
- Kent Beck wrote of the Intention-Revealing Selector (1997)
- “Name classes and operations to describe their effect and purpose, without reference to the means by which they do what they promise.”
- “Write a test for a behavior before creating it, to force your thinking into client developer mode.”
- Michael loves this idea. Never before considered that TDD makes you think about your code as some other developer (i.e. user) might.
In the public interfaces of the domain …
- State relationships and rules, but not how they are enforced
- Describe events and actions, but not how they are carried out
- Formulate the equation, but not the numerical method to solve it
- Pose the question, but don’t present the means by which the answer shall be found
When writing unit tests …
- Write your tests they way you would _like_ to use the class under test
- Write your tests to explore the interface design of your class under test
- _Then_ make it compile.
- There are two types of operations:
- Queries – Obtain information
- Commands – operations that affect state
- CQRS – https://martinfowler.com/bliki/CQRS.html
- Side effect – “… in computer science, it means any effect on the state of the system.”
- Functions – operations that produce a result without side effects
- “Perform all queries and calculations in methods that cause no observable side effects. (Meyer 1988).”
- Value objects (immutable) and functions are safer to use and easier to test
- Put as much logic as you can into functions.
- When using commands, keep them segregated, keep them simple, and do not let them return domain information
- Control side-effects by keeping complex logic in value objects whenever possible
- Maintaining invariants in Entities is much more difficult to replacing VALUE OBJECTS
Resources We Like
- Domain Driven Design – Tackling Complexity in the Heart of Software by Eric Evans (available at Amazon)
- Los Techies (https://lostechies.com/) – Great articles on all types of programming topics, including DDD. “See Habla Code”
- Domain-Driven Design Fundamentals by Julie Lerman and Steve Smith (available at Pluralsight)
- Modern Software Architecture: Domain Models, CQRS, and Event Sourcing by Dino Esposito (available at Pluralsight)
Tip of the Week
- Get Caller information using C# Attributes (docs.microsoft.com)
- Use plain ol’ object to debug your Web API parameters (Stack Overflow)
Spread the Word
Here’s a crazy thought. You might know someone that hasn’t yet learned about Coding Blocks. Do us a favor. Share Coding Blocks with that person. We’d appreciate. They’d appreciate it. It’s really a win-win.
And, hey, speaking of appreciation, we’d super love it if you’d leave us a review. Find links to your favorite podcast aggregators at https://www.codingblocks.net/review and let us know your thoughts.