Services, Factories and Repositories
using the Command Query Separation Design Pattern
Definition | CQS? | Impedance | The Platform | |
The Domain | Services | Factories | Repositories | |
Select a content section anchor button and then use the Browser’s back button to return to selections |
The Command Query Separation Design Principle was introduced by Bertrand Meyer in 1988.
His groundbreaking book: “Object-Oriented Software Construction“, commonly referred to as “OOSC”.
His work won the Jolt Award in 1994.
He extensively revised his book and expanded the new edition to more than 1300 pages!
Object-Oriented Software Construction was republished in 1997.
A method should either Change the State of an Object [the COMMAND],
or Return a Result [the QUERY],
but Not Both [the SEPARATION]
– Bertrand Meyer
What is Command Query Separation?
To understand the practical value of the CQS Design Principle we must first understand the concept of the Dependency Inversion Principle (DIP).
DIP creates the ability to implement the Dependency Injection Design Pattern (DI).
We can then use Command Query Separation with the Request/Response Design Pattern implemented within our Service, Factory and Repository Domain Layer Components.
What is Data Impedance Mismatch?
Application “Data” being referenced in this context are Object Structures that encapsulates Application State defining Information Fields as Properties using “Nouns”.
Data Object Structures do not contain
Action Behavior methods as “Verbs”
Interestingly enough, the term “Impedance“, now bandied about in software engineering circles, is borrowed from the Electronics Industry.
Impedance is the Measure of the Amount that some Object impedes, or obstructs, the flow of Electrical Current
Impedance might refer to Resistance to current, Reactance to the current as in a Coil, or some complex combination of the two
An example to illustrate impedance mismatch:
Imagine you have a low current flashlight that normally uses AAA batteries.
Don’t try this at home, but suppose you could attach your car battery to the flashlight.
The low current flashlight will pitifully output a fraction of the light energy that the high current battery is capable of producing.
Likewise, if you attached the AAA batteries to Batman’s Spotlight, you’ll also get low output.
However, match the AAA batteries to the flashlight and they will run with maximum efficiency.
Back to software engineering:
Imagine the flow of Data to be analogous to a current,
then the impedance of a Relational Data Model
is not matched with the Impedance of a ORM Object Hierarchy.
The Data will not Flow with Maximum Efficiency due to the Impedance Mismatch.
The Command Query Separation Principle helps us better manage the Data Impedance Mismatch.
The mismatch occurs between the Infrastructure Data Structures, as Complex Data Transfer Objects (DTOs), and the Rich Domain Entities that are transformed into Complex JSON Serializable Objects.
The Advanced Architecture Platform (AAP)
The architecture we will be using to show the value of CQS is our Opinionated Hybrid .Net and the JavaScript MEAN.js Stack.
This stack uses a Microservices Isolation Abstraction Layer to decouple the .NET platform WebAPI from the Open Source JavaScript MEAN.js framework.
The AAP Advanced Architecture Platform
The AAP Domain Components Architecture
These diagrams represent an Opinionated Hybrid Technology Stack that creates an opportunity to integrate Legacy Technology Middleware Stack Layers with New Responsive Mobile First Frameworks.
This Design can bring Cost Effective
New Technology to a Company’s
Mature Technologies
The Domain Services Component
The Domain Service Component has the responsibility to process the Client’s Entity Request Object sent from the Microservices WebAPI.
The Service Component then Dependency Injects the Entity Name, as a String Type, from the Entity Request Object property into the “Populate” call, the Query, to the Factory Component.
The Factory Component returns the requested Complex Domain Entity, with its Metadata and Error Handling Information, for final processing into the Client’s Entity Request Object.
The fully populated Client’s Entity Response Object is returned to the Calling Client’s Request through the Microservice WebAPI.
The Service Component uses the Entity Name to create the requested, the Command, for the Client Entity Response Object.
The final populated item added, if required is a check for errors and adding a User centric error message.
The Client Entity Response Object is then returned to the Requesting Client via the WebAPI Microservice Isolation Abstraction Layer.
The Service Component Benefits
The Single Responsibility Principle (SRP) along with the Open / Closed Principle (OCP) are implemented in the Services Component.
By delegating the “Responsibilities” of acquiring, formatting and assembling the Entity Response Object to the Factory Component we comply with both of those Design Principles.
This Architecture also Follows
Good Object Oriented Design
By Encapsulating the behavior to the Lower Layer Levels, through the Repository Component abstraction, we comply with two of the Pillars of Object Oriented Programming.
A .NET Code Example for the Domain Services
The Domain Factory Component
The domain Factory Component has the responsibility of processing the Entity Request Object, the Command, sent by the Service Component.
The Factory Component sends a Command to the Repository Component for population.
The component populates the returned Entity Response Object from the Repository Component.
The Entity Object is retrieved from either the In-memory Cache or a call to the Infrastructure Data Access Layer’s Object Relational Mapper (ORM).
The Factory Component Benefits
The entire process of managing the Data Impedance Mismatch issue is encapsulated within the Factory Component.
All of the Public Methods within the Factory Component returns a Void.
By implementing the Dependency Inversion Principle (DIP) we can use Dependency Injection to provided the Concrete Return Object for processing through Method Constructor Injection.
This component layer encapsulates all Data Structure Mappings and Data Hides the process from the Repository Component and the Services Component.
A .NET Code Example for the Domain Factory
The Domain Repositories Component
The domain Repository Component has the responsibilities of populating the Entity Response Object, a Command, sent by the Factory Component and return a Void, as stated by the CQS Principle.
1 – The Infrastructure Layer through the Data Access ORM
2 – The In-memory Object Cache managed by the Cache process
The Repository Component checks the requested Domain Entity Name sent by the Factory Component in the Cache to see if the object exists.
The Domain Entity is acquired and then returned to the Factory Component for processing, the Command, and returns a Void as the Entity is injected using Constructor Injection.
If the ORM was used, the Domain Entity is automatically added to the In-memory Cache.
The Repository Component Benefits
The Repository Component is the “Domain Object Manager“.
It manages the Cache and ensures that the Domain Object is acquired using the least expensive method of acquisition.
A .NET Code Example for the Domain Repository
Concluding Thoughts
The Command Query Separation Principle allows us to decouple the Assembly of Complex State Response Object from the creation of the requested Response Object.
By implementing Dependency Injection we can control the creation of the Response Object from the “Highest Layer of Abstraction“.
This is the Layer that has the Most Understanding
of what is Required within the Complex Object
Stay Tuned to the Modern Developer
for More Cutting Edge Concepts
Wisdom Pearl # 121 – Work Quality Concept
Your Work is Only as Good
… As How it is Perceived by the Next Person who Touches It
Positive Acceptance of your Work is Your Preeminent Responsibility
Latest posts by Brad Huett (see all)
- DevOps: A Bridge to Your DevOps Culture - March 25, 2016
- Embracing Test Driven Development (TDD) - March 25, 2016
- DevOps: Delivering Agile Projects - March 25, 2016