



This article explains the approach we took to design and implement Rewards and Benefits systems for the global retailer company. It covers Domain-Driven Design strategic techniques used to distill models together with adequate system boundaries. All of it resulted in a fully functional, understandable and modernised system.
Very often within big organisations there is this convincing need to improve existing software, catch up with new technology, generally speaking, modernise existing IT infrastructure. Undoubtedly, it is a huge task and even the greatest effort to plan modernisation according to business served by the company. The worst-case scenario is a more complicated design and countless boundary dependencies.
This article explains the approach we took to design and implement Rewards and Benefits systems for the global retailer company. It covers Domain-Driven Design strategic techniques used to distill models together with adequate system boundaries. All of it resulted in a fully functional, understandable, and modernised system.
Almost all large organisations struggle with the increasing complexity of their domain. This is an inevitable side effect of the company growing, expanding its domain and evolving the way it operates. Also, from the technical perspective – adding new features, integrating more systems or changing existing ones leads to the creation of a more and more tangled web of dependencies where no single person can ever understand the software as a whole.
Complexity in software is the result of inherent domain complexity (essential) mixing with technical complexity (accidental). – S.Millet
As a result, adding new blocks to the organisation’s systems is increasingly more complicated, risky and expensive. Sometimes, it is better to pause for a moment to understand the environment around. Blind assumptions about how business works may lead to overcomplicated design to an already complex system and technology-driven design not necessary will fit the business needs.
As an example, we would like to show you the journey we took to understand and design ‘Employee Rewards and Benefits’ system for the global retailer company and explain why strategic Domain-Driven Design played a huge role in our project to deliver the service that not only ‘works’ but also fits perfectly within already existing surroundings.
We all know that hierarchy is almost unavoidable while working in a big and multinational organisation. A well-known Conway’s Law states it clearly.
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure. – Melvin E. Conway
Our team was in a very similar situation. Fortunately, there are ways to work efficiently even in such an environment. Firstly, let’s think about what the main focus is and what requires the biggest effort.
Fig. 1: Too wide Retail domain
Obviously, for the retailer company, everything is related to retail. Nevertheless, “everything” sounds too large. When we took a closer look at the current site of internal APIs a little better representation was discovered.
Fig. 2: Organisation silos
Some sets of API are more customer-facing when others are more employee-facing. The Employee Experience might be a good candidate to put it in later. But, thinking about our area of interest which is Rewards and Benefits for employees it wasn’t so obvious. At the very first kick-off meeting, we heard about our first goals – Discount Cards and Savings. It didn’t take long to understand that Discount Cards not only exist for employees but also for customers. There is a relation that each employee can be also a customer and some customers might be also an employee.
Fig. 3: Overlapping Rewards and Benefits domain
It meant that our area of interest is somewhere between the employee and customer silos. We didn’t feel quite comfortable with such overlapping vision. At that moment we started digging deeper into existing structures, business units and tried to align it with strategic Domain-Driven Design patterns like domains. Good inspiration to visualise domains are DDD Domain Charts
Fig. 4: Domain chart
As presented in the chart [Fig. 4], we can distinguish between:
Fig. 5: Domains on the chart
The above chart is a result of multiple meetings with a relevant representative from the Employee Experience, Rewards and Benefits, HR, Payroll and Customer spaces. For us, it was very important to understand where our solution will sit, thus where our problem space is. The diagram depicts the importance of each domain and where it is located in terms of complexity.
Our space supports a core business. It needs to know about Customer Discount Cards and is driven by the Employee Work cycle. The generic Payroll and HR domains influence both Employee Workcycle and Rewards and Benefits.
So far we have discovered where potentially sub-domain of Rewards and Benefits sits. Let’s elaborate on useful tips that help with discovery.
Another game-changing approach to discover and learn is Event Storming, specifically Big Picture at this phase.
Fig. 6: Big Picture Event Storming for Rewards and Benefits domain
We as a team would like to understand what business says and business would like to communicate its ideas clearly. The Big Picture Event Storming is a perfect tool to start naming and grasping concepts from the ubiquitous language. Each domain event visible in the [Fig. 6], represented as an orange sticker, should reflect an important behaviour within our domain. It should follow the language spoken by key stakeholders. Taking a look at explored domain events, you might notice that visible concepts are more about entitlements. For us, this discovery was eye-opening because it brought a totally different perspective on what we are going to implement. Thus, it was very important to invite the Big Picture Event Storming session to the most relevant people from our project perspective. In our case, a mix of below individuals worked quite well.
Although Big Picture Event Storming is an exhaustive activity that consists of many steps, we learned a lot about flows, reasons and started speaking the same language. In this chaotic exploration, we discovered not only domain events and their sequence but also who and what external system can be involved in the process and how it changes over time. For example, the same physical employee in one place is called just “Employee” in another “Primary Card Holder”. Even if the result wasn’t perfectly layered, for us it was a good enough starting point to think about model, boundaries and dependencies.
The next steps were to enforce a timeline better and find processes boundaries.
Fig. 7: Big Picture Event Storming with bounded contexts
As you can see in the [Fig. 7], yellow straps divide the board into logically connected pieces. In the Domain-Driven Design terminology, such pieces are called Bounded Contexts. First of all, a Bounded Context is a linguistic boundary around the meaning of the domain model. Furthermore, it is a natural software boundary, so we’ve just entered the solution space.
To achieve it, we followed below heuristics:
In our domain of Rewards and Benefits, we distinguish between below Bounded contexts.
Fig. 8: Big Picture Event Storming with bounded contexts boundaries
As we learned, there are some dependencies between them. Such dependencies could influence architecture, collaboration and business feature planning. In order to understand existing relations between we used a context map.
Fig. 9: Context map
We can distinguish between patterns such as:
As you can see on the map [Fig. 9], Employee Workcycle is an important bounded context but only acts as an upstream team relation. As a result, we decided to build an anticorruption layer inside each bounded context to ensure that we operate only on our own model.
In our organisation, most Open-Host Service patterns are implemented using RESTful architecture. Undoubtedly, it was a straightforward way to plan integration with Discount Cards and Fraud Investigation. However, the latter team works close to our domain and we would have liked to adjust our API to their needs.
The Payroll team is our partner in the delivery. In case of integration with Payroll, we established a well-structured file exchange as it was the only supported option.
When planning a work needed to implement particular features from the bounded context it is highly recommended that in a single bounded context works only one team. Our cross-functional team owns Savings, Permanent Employee Discount Entitlements and Contractor Discount Entitlements. Therefore, a Shared Kernel pattern for a common discount entitlement model sounded reasonable.
Let’s iterate over already discovered artifacts:
Now it is time to think about some software to be implemented.
Around discovered bounded contexts, we can start designing architecture, organise codebase, build integrations, populate metrics and finally implement the domain model.
In the era of microservices, a blind approach might be to build a separate microservice for each bounded context. For our purpose, we decided to at least have 2 – Savings and Discount Entitlements. They don’t interact with each other, have different models and reasons to exist. Nevertheless, they have one thing in common – integration with the Employee Work cycle. It was a good opportunity to build an anticorruption layer once as it serves the same purpose for Savings and Discount Entitlements.
Next, there is a shared kernel model propagation between Permanent Employee Discount Entitlements and Contractor Discount Entitlements. That is a perfect fit to a module shared between them and each of them can be implemented in a single codebase but in separate modules. Especially, that language used in both of them is the same, just different use-case and set of rules.
Looking at the bounded context complexity in terms of domain events sequence and flows, it easy to notice that Savings context looks much simpler than Discount Entitlements. It is a valuable indicator for simpler patterns even like CRUD compared to Discount Entitlements where maybe tactical Domain-Driven Design building blocks suit better. We encourage you to proceed with the below steps to even better understand requirements:
All covered patterns and above additional list of steps will help you to create a tailored-made software reflecting real business needs.