DEV Community

CodingBlocks

Episode 63 – Software Architecture – Explicit Constraints, Processes, Specification Pattern, and more

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.

Sponsors

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 http://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?

#yop-poll-container-40_yp5962e3679599c { width: 1000; background:#fff; padding:10px; color:#555; overflow:hidden; font-size:12px; } #yop-poll-container-40_yp5962e3679599c input[type='text'] { margin:0px 0px 5px 0px; padding:2%; width:96%; text-indent:2%; font-size:12px; } .yop-poll-name-40_yp5962e3679599c { font-weight:bold; background:#327BD6; color:#fff; padding:5px; text-align:center; font-size:12px; } #yop-poll-questions-container-40_yp5962e3679599c { font-size:14px; margin:5px 0px; } .yop-poll-question-container-40_yp5962e3679599c { padding: 2px; } .yop-poll-question-40_yp5962e3679599c { background:#327BD6; color:#fff; margin-bottom: 21px; margin-top: -10px; font-style: italic; text-align: center; width: 100%; padding:5px; } .yop-poll-answers-40_yp5962e3679599c { } .yop-poll-answers-40_yp5962e3679599c ul { list-style: none outside none; margin: 0; padding: 0; } .yop-poll-li-answer-40_yp5962e3679599c { font-style:normal; margin:0px 0px 10px 0px; padding:0px; font-size:12px; margin-bottom:20px; } .yop-poll-li-answer-40_yp5962e3679599c input { margin:0px; float:none; } .yop-poll-li-answer-40_yp5962e3679599c label { margin:0px; font-style:normal; font-weight:normal; font-size:12px; float:none; } .yop-poll-results-40_yp5962e3679599c { font-size: 12px; font-style: italic; font-weight: normal; margin-left: 15px; } .yop-poll-customs-40_yp5962e3679599c { } .yop-poll-customs-40_yp5962e3679599c ul { list-style: none outside none; margin: 0; padding: 0; } .yop-poll-li-custom-40_yp5962e3679599c { padding:0px; margin:0px; font-size:14px; } /* Start CAPTCHA div style*/ #yop-poll-captcha-input-div-40_yp5962e3679599c { margin-top:5px; } #yop-poll-captcha-helpers-div-40_yp5962e3679599c { width:30px; float:left; margin-left:5px; height:0px; } #yop-poll-captcha-helpers-div-40_yp5962e3679599c img { margin-bottom:2px; } #yop-poll-captcha-image-div-40_yp5962e3679599c { margin-bottom:5px; } #yop_poll_captcha_image_40_yp5962e3679599c { float:left; } /* End CAPTCHA div style*/ .yop-poll-clear-40_yp5962e3679599c { clear:both; } #yop-poll-vote-40_yp5962e3679599c { } /* Start Result bar*/ .yop-poll-results-bar-40_yp5962e3679599c { background:#f5f5f5; height:10px; } .yop-poll-results-bar-40_yp5962e3679599c div { background:#555; height:10px; } /* End Result bar*/ /* Start Vote Button*/ #yop-poll-vote-40_yp5962e3679599c div#yop-poll-vote-40_yp5962e3679599c button { float:left; } #yop-poll-vote-40_yp5962e3679599c div#yop-poll-results-40_yp5962e3679599c { float: right; margin-bottom: 20px; margin-top: -20px; width: auto; } #yop-poll-vote-40_yp5962e3679599c div#yop-poll-results-40_yp5962e3679599c a { color:#fff; text-decoration:underline; font-size:12px; } #yop-poll-vote-40_yp5962e3679599c div#yop-poll-back-40_yp5962e3679599c a { color:#555; text-decoration:underline; font-size:12px; } #yop-poll-vote-40_yp5962e3679599c div#yop-poll-archive-40_yp5962e3679599c a { color:#555; text-decoration:underline; font-size:12px; } #yop-poll-vote-40_yp5962e3679599c div { float:left; width:100%; } /* End Vote Button*/ /* Start Messages*/ #yop-poll-container-error-40_yp5962e3679599c { font-size:12px; font-style:italic; color:red; text-transform:lowercase; margin-bottom:20px; text-align:center; } #yop-poll-container-success-40_yp5962e3679599c { font-size:12px; font-style:italic; color:green; margin-bottom:20px; text-align:center; } /* End Messages*/#yop-poll-container-40_yp5962e3679599c img { max-width: 1000; } .yop-poll-forms-display{}
How many monitors do you use?
  • Just one.
  • Two is the minimum.
  • Three. Like. A. Boss.
  • More than three. Because if it's worth doing, it's worth over-doing.

News

  • 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/

Gear

Want some Coding Blocks swag? Check out http://www.codingblocks.net/swag to get the things you need.

Explicit Constraints

  • “[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.

Specification Pattern

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.

Intention-Revealing Interfaces

  • “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.

Side-Effect-Free Functions

  • There are two types of operations:
  • 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

Tip of the Week

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 http://www.codingblocks.net/review and let us know your thoughts.

Episode source