Entities of a different kind

FeaturedHexagonal Architecture

Note: In what it follows, the term “Entities” refers to both Entities and Aggregates indistinctly.

The Hexagonal Architecture sets a clear distinction between Domain and Application layers, which drives us to locate all entities in the Domain layer for it is there where the meaning (what the software is about) has its home, whereas we must put whatever run factual changes in those entities, as use cases require, in the Application layer.

For example, Customers and Items, as entities, belong to the Domain layer, whereas Sale an Item, Bill an Order, or Ship some Items, belong to the Application layer because they represent in the application (translated to the language the software can understand) what in real life we would consider facts that happened concerning particular Customers and Items.

Just as a brief reminder, in this same Hexagonal Architecture, the UI layer would be where what triggers those changes live, whereas the Infrastructure layer would be where we put every piece of software needed to have the application run (frameworks, ports connecting to databases, file system, message transporters, etc.).

Not all entities are created equal

A simple inspection through the list of entities in any given application would show us that some entities play a role, and have a life span, fundamentally different than others:

  • There are Master Entities, which represent in the Domain model that every particular application implements what in real life we would call “entities” too: Customers, Items, Suppliers, Service Providers, Employees, etc. One of the elements of external reality (external to our software) they exhibit is an id of their own: either you decide relying on those ids to identifiy instances of these entities in your application or not, that is a property (ISBN, Tax ID, Social Security Number, etc.) you are likely to handle somehow.
    Master entities change in a very slow pace: once created, and approved, you would change them seldom, for instance, to add a new Customer Address, or update the description of an Item, or mark an Employee as not working in the organization anymore. Conversely, master entities show a long lifespan, ordinarily of years.
  • There are Transaction Entities, which play in the Domain model what in real life are Orders of any kind (sales, purchases, work orders, etc.), Bills, Shipments, etc.
    Transaction entities may suffer plenty of changes, for each change represents a step in the fulfillment of the business process in progress. However, once completed, these entities never change again, and so their lifespan is very short, commonly not more than days.
    In opposition to Master Entities, your application will surely need to provide unique ids for every instance of these Transaction Entities.

That distinction between master entities and transaction entities has indeed a long history behind if you accept database tables as true ancestors of entities. In fact, I took both names from the field of Business Intelligence, in which, quite approximately, transaction entities constitute the data origin read to feed the so-called fact tables, whereas master entities play the role of dimension tables, due to their role as axis in the charts where the calculations provided by the BI engine are pictured.

Incidentally, there is another feature that is also different in magnitude between master and transaction entities: their number. With time, the number of transactions grows far quicker than the number of instances of any master entity. Although this is not true in all cases, for it depends on every particular organization, it is often true that the number of Customers is far less than the number of Sales Orders.

So, we might be tempted to state that master entities are fundamental and transaction entities are accidental, for master entities are supposed to be there, perfectly defined and steady, even though while nothing happens to them.

Jose Ortega y Gasset
Ortega y Gasset

However, as the Spanish philosopher José Ortega y Gasset said, “I am me and my circumstance“; hence, Mr. Ortega would be a master entity, and his circumstances (what impacted, or happened to him), a plethora of transaction entities.
In other words, no matter how permanent we humans might look, our self is defined by a never-ending interaction with our surroundings, in a way that makes us a work in progress which never gets accomplished. It’s that dialogue what really makes us.

Everything in its right place

Time to come back to software. In my opinion, the different roles that both master entities and transaction entities play in the application constitute a fundamental trait which must be made apparent in how we organize the elements of the code.

One easy way to achieve that purpose is to keep them both in the same Domain layer, but segregating one set of entities of the other, for instance, in separated folders. This option is quite conservative, so it might avoid unexpected surprises to eyes dropping a casual gaze on a repo organized like this. But it looks wrong because it ignores the key fact that master entities exist before any use case might run, whereas transaction entities are tightly intertwined to the execution of use cases: with no execution of a particular use case, there cannot be any instance of the related transaction entity whatsoever.

We might say that master entities keep the major part of the meaning of the Domain, whereas the transaction entities only carry an operational meaning. Though appealing, this is wrong, because ultimately all entities are defined out of operational foundations. For instance, Customers are defined because of their action of buying something to the organization; Items are defined because they are what the organization sells, buys, or utilizes somehow.

All Entities, either master or transaction, are defined out of operational traits

Therefore, what looks more natural to me is to relocate the transaction entities in the Application layer. For they belong there as the use cases do too, and, as I said above, with no use cases, there are no transaction entities neither. IMHO, it is not enough that transaction entities are persisted as well to keep their place in the Domain layer, compared to the key facts we have seen:

  1. Master entities have a lifespan far longer than transaction entities.
  2. Master entities pre-exist transaction entities, for the former may exist without the latter, but the opposite is not true.
  3. Master entities have got their own unique ids, whereas transaction entities need to be provided with one by our software.

Does this feel right to you?

Copyright notice: featured image taken from the Java Viet Nam blog, though it is not original of the blogger.

The fallacy of state recovery from event storage

Here are the contents of my talk in the 3d DDDBarcelona meetup, the 8th of November. It was an excellent occasion to learn about the experiences with DDD of other fellows in the audience, as well as learn from the other two speakers: Aleix Morgadas, who talk about Adopting DDD in the teams, and Daniel Solé, who introduced us to the techniques of Domain Storytelling.

My talk was about how possible it may be to reproduce knowledge about the Domain from an Event Storage. However, and for a better understanding of the topic, I thought that a brief introduction might be helpful. You have the slides and video below.

Events

Events are representations of Facts, and Facts are those petty pieces of external reality such as A Customer purchased 3 units of Item A for 15.99€, for instance.

In other words, facts are taken as atoms of truth. Hence actual facts might be wrong (i.e. that did not happen that way, or did not happen at all), but they cannot be false.

For software production purposes, facts are the atoms of truth.

That truth is carried over to the Domain by making Events immutable: once they are dispatched, Events stay readonly.

Events map Facts to the Domain, meaning that they express facts with the words of the Ubiquitous Language, which is the language the Domain can talk.

In that sense, Events are not neutral. As any other representation, some details from the Fact are taken, and translated, into the Events whereas other details are ignored.

State

Events bring change into the Domain by triggering Commands, Application Services, or Domain Services to run. From the point of view of the Domain, this change is perceived as modifications in the values of properties of some Entities, as the creation of new instances of some other Entities, or the removal of instances of other Entities.

These changes in the Domain details triggered by Events allow us to define States.

A State is any summary of the values of some properties of Entities at any particular moment in time

There is no restriction on what kind of States we may define. In Finance and Accounting they are being dealing with States for years, even centuries: Profits and Losses, as well as Balance Sheets, are States as we just defined them.

Example: inventory

This slideshow requires JavaScript.

Provided Events bring change into the Domain, it looks like a healthy measure for data consistency (i.e., to ensure that every change in data is traceable) to reverse the scenario and set that no change in the Domain should happen unless triggered by some Event.

No matter how hard this goal might look, it is not impossible: Accounting stands as the proof that it is possible, thanks to a very short list of States to keep an eye on, and an Event storage (in this case, the ledger books) filled under very strict a set of rules.

State Recovery

So, provided that every State was triggered by Events, we should we able, in theory, to rewind and rerun Events from start and up to any specific point in time and produce any State exactly as it was then.

Trouble comes when we have to deal with either uncompleted, or mistaken information. Is it possible to fix the past, i.e., to act retrospectively on States? Being the Events immutable as they are, how could we, for instance, modify right now a State referring to yesterday 8:00pm?

This was the topic of my talk, which I hope you’ll enjoy.

Video

Slides

Dive into DDD – Part II

After presenting the fundamentals of DDD in the Part I of this Dive into DDD series, it is time we got our hands dirty with some practice.

As I mentioned there, the purpose of the examples I am going to introduce in this series is not only to illustrate how to produce software under the principles of DDD, but also how to make it with PHP 7. However, do not hesitate to produce your own solutions to the case using the language you choose, because, as a methodology, DDD is not linked to any specific language or framework.

The case

During our very first conversation within the team of people in charge of distilling the Domain, and produce the software to represent it, we were able to collect the following summary of information:

We, ACME CORPORATION, run a digital store of products and services on behalf of other companies, our Providers.

After signing up on our site, Customers may order one or more items at a time, from the whole Catalogue available.

Occasionally, we may offer them discounts based on different conditions (for instance, because they may be living in a country we are interested in increasing our market share; by ordering specific items, by ordering at least a given number of units, by reaching a given total order amount, on special dates, etc.).

Our sales spread over twenty countries in two continents. We buy and sale under five currencies, and our site runs eight languages.

How should be start exploring this, or any other, Domain? I am presenting a technique and a couple of tools just in a minute, but before I’d like to remark that Exploring a Domain is a creative activity similar to play a music instrument or writing tales: you may learn the basics from others, but ultimately you would need to acquire your own style and pool of techniques, and to adapt them to the particular needs in place.

Now, back to the case, let’s avoid the mistake of restricting ourselves to the obvious, and the obvious mistake here is to think of the Domain as limited to an e-commerce site. Beyond customers, actual and potential, the items on sale, and their providers, there is more at stake here not to forget.

So let’s keep our eyes and ears wide open and start exploring.

In 101 of Domain Exploration, the teacher’s advice is to draw what is called a Context Map. A Context map is a picture showing all the bounded contexts in the Domain, for instance, as labels enclosed into rectangles or circles, and arrows or similar depicting the relationships among them. You may show them closer if they are functionally closer too; even though, a Context Map is not the place to display actual processes, for processes belong to a lower, more detailed level of knowledge.

A Context Map is the broader, higher level vision of the Domain you might picture.

To draw a Context Map is an excellent activity whenever a new DDD project starts. It is also a great tool to rely on whenever a summary of the project has to be displayed to upper levels of the company, in internal events, etc.

Why not we produce a Context Map for this case? Below I put an example depicting just a brief list of apparently relevant (at least, to me) bounded contexts.

A context map example for this domain
A context map example for ACME’s Domain

The Domain Vision Statement

As long as you explore deeper and deeper the Domain, you may version a collection of Context Maps. Some talks may enrich the Context Map in unexpected directions, drawing new bounded contexts and relations, while other conversations may end with some bounded contexts split or joined.

However enlightening, to explore the domain is not an activity meant to merely increase our knowledge, but to support our creation of new quality software, and to produce software the team must focus on something.

So an improved procedure for Domain Exploration is to highlight the center (the core) of the Domain and organise the bounded contexts according to their relationship to the core.

Teams often write a sentence which states the main value provided by the Domain, which is its purpose, and pinpoints the direction to which further software features should go. This sentence is often called the Domain Vision Statement.

To achieve an agreement on a Domain Vision Statement may be easy for some teams, and almost impossible for others. No matter the words of the Statement eventually agreed upon, it must suggest which is the central core of the Domain, otherwise it is not only useless, even counterproductive.

In our example, and under my personal point of view, the value provided by a store comes from the catalog of products available for sale, for these items are the reason why customers may sign up and buy. Therefore, the Domain Vision Statement may be to Provide a rich catalogue of products and services for sale to the markets the company perceives as profitable.

Therefore, the Item bounded context in the Context Map above is, in my opinion, key to the Domain. That puts it in the core, for nothing else looks more central.

Likely other bounded contexts will be part of the core as well, whereas others would be classified as supporting bounded contexts. For instance, Orders, which stands for to the whole Order fulfilment process, looks quite central to me as well; instead, Taxes looks secondary.

A first sketch of the Ubiquitous Language

During that first conversation, the team must be able to produce a brief list of terms as the Domain’s Ubiquitous Language. This is my version of it:

ACME’s Domain Ubiquitous Language

  • Discount: money we cease to take from Customers in her Orders under certain conditions particular to every Discount. The money discounted must be less, or equal, the Unit Gross Margin either of the Item deserving that Discount, or the Gross Margin of the whole Order.
  • Item: every product or service a Customer may buy. The same Item might be purchased to more than one Provider.
  • Order: every unique operation of purchase made by Customers in our site.
  • Provider: the organisation in charge of providing us with the Items we sell. We’ll need to pay them for those Items according to the specifics of Purchase Agreement signed with them.
  • Purchase agreement: list of conditions agreed with a Provider. It holds prices, delivery terms, quality assurances, an any other conditions either the Provider or we consider relevant for our mutual operations.
  • Tax: money we collect from the Customers in their Orders on behalf of the local administration.
  • Unit Price: the amount of money a Customer would need to pay for one unit of a given Item, before any discount and Taxes may be applied.
  • Unit Cost: the total amount of money we must spend for an Item, i.e., the money we should pay the Provider for one unit of the Item, etc.
  • Unit Gross Margin: the result of subtracting the Unit Cost from the Unit Price. It is commonly understood as a percentage, though it may be represented otherwise.

As we saw in Part I of this series, the Ubiquitous Language is an evolving creature which not only sets the ground for the whole DDD methodology to rely on, a goal which claims for stability, but its openness to improvement also acts as a driver for further talks, a purpose which claims for variability. Such a magnificent instrument it is!

To Do List

What’s next? We need to implement a persistence layer for at least three different Entities: ItemsProviders, and Purchase Agreements. They are the constituents of our Domain so far.

So far I am making use of the common meaning of Entity, i.e., as a unit of persistence. In the Part III of this series I will state a more proper definition of Entity, as it is used in the reign of DDD.

We also need to implement a View showing a list of available Items for sale, which is going to be part of a UI layer. In the context of a Request and Response model, we should also implement a Controller function.

This all is a powerful remembering of the Model View Controller (MVC) pattern. No matter how old-fashioned, MVC it is such a common, and language agnostic, design pattern in the software community that it just looks suitable to pick it here. Later on in this series, we will see other ways to organise our software which fit better with DDD.

So, our To Do List should be like this:

  • 3 models (Item, Provider, and Purchase Agreement),
  • 1 View (Product Catalogue),
  • and 1 Controller (GET the Product Catalogue).

We will review my code, produced according to what we have seen in Part I and Part II of this series, in its next instalment, in which we are also going to learn a lot more about DDD.

So, let’s code, and see ya in Part III of this series!

 

 

Dive into DDD – Part I

Recently, while I was participating in an interview with a candidate to a software developer position, we asked the candidate for a definition of DDD (you know, Domain Driven Design).

Unfortunately, the candidate’s answer was unsubstantial, and actually wrong:

“To practice DDD is to develop software according to the Domain”

I’d got to stop myself from asking the candidate “Which software is not?“, because it is unfair to blame anyone for not knowing something.

Ultimately I decided to write some blog posts explaining, using my own words, what DDD is.

A second thought made me refine my first intention though. There are already other information sources to learn about the concept of DDD. One of them is very obvious: the Eric Evansbook itself. However, most of them are full of examples using compiled languages, like Java. So I decided to reconsider my original intention and write a brief review of the key concepts of DDD, illustrated with code written in PHP, the most popular programming language for the web right now.

This all set, just get it started.

DDD: a better way to develop software

Domain Driven Design is a methodology to produce software built upon the intimate connection between the actual code and the knowledge about the application shared among all the participants in the conversations with the people in charge of developing that software and the people who knows about the business.

So in practice, DDD is a methodology which key feature is that the code and the conversations among the participants in the development of that code are tightly intertwined. Important detail: the code should be runnable at any stage during its development, so that everyone participating in the conversations may play with it whenever they want to.

In a way, DDD is like the dance hall where code and knowledge dance together cheek to cheek.

Beyond practical details, there is nothing else in DDD that this dance.

But, if this is so, why so serious about The Domain?

Because the word is a very useful abstraction. As a term, the Domain refers to the whole bunch of information that may be relevant, no matter how, to the software we are building. We should think of the Domain as an unstructured set of data as wide as needed so that anything relevant remains in it, and consequently the Domain boundaries are not strictly painted on the floor.

My personal experience is that people in the teams are used to think of applications with clear limits: the Shipping Application, the Accounting Application, the Marketing Application, and so on. Actually this is the traditional way of producing software.

In DDD we must look wider: unless there is absolutely no connection between the Shipping application, the Accounting application, and the Marketing application, they all are part of the same Domain. Even third-party applications, like payment providers, public tax agencies, etc, are in the Domain since there are functional relationships that connect them to our software.

Now that we learn that we must think wider in order to play with DDD, let’s narrow the focus.

The Ubiquitous Language

The most important tool DDD relies on in practice is the list of terms which condense the shared knowledge. Given the specifics that every software application implements, this list of terms is also specific to the application, and consequently we may say that the meaning of every one of those terms is domain-specific.

Being such an important tool, this list of domain-specific terms gets its own name: it is called Ubiquitous Language.

What does it mean domain-specific? That any given word may have a different meaning in different Domain’s Ubiquitous Language. This circumstance is very clear with common-use words, like “customer“, “product“, or “contract“, which differences in meaning might seem slightly but actually deepen as we dive into each Domain’s details, otherwise we would be dealing with one and only Domain again and again.

In fact, the very same application developed in two different companies would ultimately produce a slightly different UL, for those companies must have competitive uniquenesses which clearly become very relevant in their particular Domains, and therefore in their particular UL.

As fas as I know, teams are used to writing their UL in documents, either digital or in paper. Personally, I love to write the words in the UL in paper and stick them on the walls where the team works, so that they stand as close as the eye as possible. They even may be taken out of the wall and passed during conversations.

But, what if one term has different meanings in different parts of the Domain? Is that even possible? Yes, it is, because company language comes out of the culture, the company’s culture, and its environment culture, and culture is inconsistent per se.

For instance, every one in Accounting is used to talk about “accounts“, and they all know what they are referring to. But those “accounts” have nothing in common with the “accounts” that people in Finance are used to. The former stands for a way to classify the ledgers, and so there are Income accounts, and Fixed Assets accounts, etc, in Accounting. While the latter refers to money held in Banks on behalf on its owners.

Whenever this happens in DDD, we say we just found two separated Bounded Contexts.

Bounded Contexts

A Bounded Context is like a Domain which belongs to a bigger Domain, because there are relationships that connect it to other Bounded Contexts in the same Domain. Some operations in Accounting accounts have impact on Bank accounts, for instance whenever the company pays a bill to one of its suppliers. And the opposite holds as well, for instance when customers pay their bills.

Some operations may even impact on more than two bounded contexts. For instance, whenever the company pays its taxes, there are at least three bounded contexts involved: Accounting, Finance, and Taxes.

Every Bounded Context has its own Ubiquitous Language. At the same time, there is a unique, application-wide Ubiquitous Language that includes terms common to all Bounded Contexts.

What happens at the boundaries between BCs?

Well, the culture reigns there. I have seen companies failing to implement DDD mostly because some terms were commonly used everywhere, but hold a different meaning in some parts of the company. That made software pieces less understandable, because they had to invent translations which were no used beyond the contracts between BCs.

For instance, a team found that Sales and Marketing both used the term “lead” to refer to people at any stage of their way to become a customer. But Sales and Marketing were actually two different BCs for other reasons, and conflicts in their common relationship happened because of the simple fact that a person who is a lead in Marketing may, or may not, ultimately become a lead in Sales.

As a mistake, this might not look a big deal, but it is actually because it breaks an implicit rule in DDD which says that the software and the shared knowledge must be so intertwined that any person in the team must be able to read, and understand, the code.

In other words, a mess. Mess not as a question of philosophy, or aesthetics. Mess as chaos which spreads, mess that makes people lose focus, so that the software they produce gets more and more buggy, hard to change, and ultimately far less efficient.

Some times this mess catastrophe is avoided thanks to brilliant people in the team, who keep the translations clear in their minds. Unfortunately, this is risky, because people ultimately goes away.

Following the example above, in another company I also worked with, Marketing people handled “Marketing Qualified Leads“, or MQLs, whereas Sales people worked with “Sales Qualified Leads“, or SQLs. And this gets even better because they had already defined one single operation (what we later are calling a Domain Event) which converts an MQL into an SQL. All this was previous to start working with DDD, but it clearly made our code extremely more understandable.

The task of looking into the Domain, to identify BCs and the relationships among them, and to make explicit the Ubiquitous Language, is a team task which requieres some individual work between conversations, and that never ends. There is a beautiful term for this task, to explore the Domain, a task I love insanely.

Operations

Since it comes out of a dance between knowledge and code, DDD is iterative by nature. Almost all software development methodologies are iterative nowadays, so DDD is not special by this.

What makes DDD special is that the code and the conversations by which the shared knowledge arises, are intertwined. A capital consequence of this tight relationship is that the software must be runnable at every stage of the process, and that the code must be readable by every participant. These two requirements impact the code deeply, as we’ll see in the examples.

One way to ensure that the software reflects exactly what the knowledge out of the conversations say is by producing tests. Therefore, tests are instrumental in DDD. But tests are a key instrument, which allows teams practicing DDD to practice TDD techniques as well.

Also, the requirement that the code must be runnable at every stage, and available to every participant in the conversations, makes Continuous Integration and Continuous Deployment operational practices a must. CI/CD are not only convenient to save time but also necessary to make possible that every participant may run the code as it is at every moment.

All these operational techniques help DDD keep the conversations, and so the shared knowledge, and the software alligned and evolving together.

So, as a resume, we see that practice DDD requieres teams to:

  • Do tests, even TDD, in a Continuous Integration environment.
  • Run Continuous Deployment.
  • Produce code understandably readable by every participant, and structured in a way that purely reflects the shared knowledge.

To say it plainly: DDD is not easy, it requieres skilled people to make it work.

On the other hand, DDD can be extremely efficient producing runnable software, in the sense that it is software less prone of error, very close to the business needs it was produced to serve, and easier to evolve since every one can understand what it does.

TL;TR

  1. DDD is a methodology to produce better software in an efficient way.
  2. DDD works by gathering skilled people in a team and let them talk. Some of them are software developers, and some of them are not.
  3. Conversations must be followed by new code which reflects the shared knowledge collected during them.
  4. Code must be runnable after every iteration.
  5. Code must be readable and understandable by every participant in the conversations.

In addition to this, there are some common terms very common in DDD:

  • The Domain is an abstract term to refer to the whole information, explicit or not, which is relevant for the application.
  • The collection of terms and their specific meaning in the Domain is called Ubiquitous Language.
  • Some parts of the Domain are functionally closer than others. These parts are called Bounded Contexts, and they all have their own Ubiquitous Language.
  • Relationships among Bounded Contexts requiere to set ways to union their individual Ubiquitous Languages. Whenever an intersection exists among these Languages, conflicts might happen. Therefore solutions must be put in place before going on with the code that implements those relationships.

Let’s practice with an example of this in the next post in this series. In the meantime, do not hesitate to drop your comments below.