DDD: Part IV (DDD and Microservices)

(originally published on https://dzone.com/articles/ddd-part-iv-ddd-amp-microservices)

Finally, I got a chance to write the fourth part! For those of you who didn’t get the chance to read the previous parts, you can  read them starting with the Part 1 here.

In this fourth part, I will try to elaborate on the microservices architecture and its relationship with the Domain Driven Design (DDD).

Microservices Architecture

First things first: let’s describe what microservices architecture is all about.

Microservices architecture is a kind of an architectural pattern that focuses on developing/building small, reusable, and scalable services. Microservices allow us to break our large system into a number of independent collaborating processes, thus it can help to avoid a big monolith application, which is difficult to maintain, especially if you have big projects with a big team.

Microservices also can be very useful when you have to create services for polyglot devices such as wearables, Internet of Things (IoT), mobile, desktop, and web.

Microservices itself is not a new term. It was coined in 2005 by Dr. Peter Rodgers, who mentioned micro web services based on SOAP. It has become more popular since 2010.

The keys to microservices architecture are:

  1. It is independently deployable in terms of stack, framework, and/or languages used.
  2. It is deployed as a small service that keeps focusing on doing one thing well, i.e. domain-driven services.
  3. Well-defined interfaces and minimal functionality.
  4. Avoiding cascading failures and synchronous calls — reactive designing for failure.
  5. Every service has its own data and uses events/messages to communicate with other services.
  6. Every service is deployed independently and isolated from other services (usually running in its own container) and automatically scalable.

The main goal is to provide you with a small set of independent services which run independently in different environments, but can communicate with each other (tight cohesion). As we know, coupling is a two-headed beast. On one side, tightly-coupled code is difficult to test, difficult to maintain/reuse, and typically exhibits “whack-a-mole” bug behavior (i.e. fixing one bug most likely will produce one or more new bugs). On the other side, a certain amount of coupling is also necessary since completely uncoupled code doesn’t do anything; thus, coupling is necessary but should be carefully managed. This is what we call “Loosely Coupled, Highly/Tightly Cohesive.”

Microservices Benefits

  1. Easy to scale as individual components.
  2. Easy to deploy and reduce time deployment, i.e. you can deploy each module without interrupting any other module.
  3. Easy to maintain due to its smaller code size, and you can have a small, focused team.

Microservices Challenges

  1. It’s difficult to achieve strong consistency in distributed services.
  2. It’s harder to debug and trace issues compared to monolithic applications.

There are many other challenges that you will know yourself later, once you implement microservices. Nevertheless, it will depend on how you design and manage your microservices by following some well-known best practices, like API Management, Traffic Management, Services Monitoring, etc. I’ll try to encapsulate them later in another series, if I get the chance.

How Does DDD Relate to Microservices?

As mentioned earlier, in microservices, we build each service to serve only one thing and do one thing well. Each service is also isolated from the others. On this matter, DDD principles can help us to keep the scope of the service small through what it calls “bounded context.”

Subsequently, DDD is going to help you investigate and know your domain and all subdomains well through the communication you build with the domain experts. By knowing your domain and subdomains well, you will know the map contexts and how all subdomains interact with each other, which will help you in designing and choosing the type of your microservices architecture and what kind of approaches you use to implement them, whether a reactive approach, orchestration approach, or hybrid… it will depend on your knowledge about the domain you’re working on. There are pros and cons for each approach that need to be evaluated based on the project and your domain knowledge. DDD will help you make a decision on this matter.

That’s all for now… please let me know if you have any more insight into how DDD relates to microservices!

DDD Part III (DDD and Onion Architecture)

This is the third part of my DDD series. I encourage you to read the first part and second part before going further on this particular part.

Within this particular part, i’ll be talking about one of my favorite architecture called “Onion Architecture”. Nevertheless, allow me to recap first about what do we have so far about DDD as following:

DDD is all about how we design our software from the business perspective, not from the technical perspective. For that purpose, we must go together with the domain expert (a.k.a business expert) during the design process, thus we can keep align with the business want. The process always start with what we call as ubiquitous language (i.e. we need to have standard term to be used along with the design and implementation process). Subsequently, break the complex domain into smaller sub-domain known as bounded context and carefully define the boundaries and contract used to communicate between the individual bounded context. So each bounded context appears as a black box to another (only care about the contract interface, no need to care about the implementation details since its hidden from the outside).
Additionally, there are some pitfalls that need to be avoided during the design and implementation. Those are data centric mindset when modeling the problem domain, focusing on implementation details such as entities, repositories, etc instead of the core concepts, generic and specific technical terms, and focus on DB transactions instead of business transactions.

Ok, let’s start with the main topic now, shall we :-).

Onion Architecture was coined by Jeffrey Palermo. If you ever heard about Hexagonal Architecture (a.k.a. Port and Adapters) from Alistair Cockburn, the idea of Onion Architecture actually was inspired from this Hexagonal Architecture.

You don’t have to use Onion Architecture though you implement DDD. And you don’t forced to use DDD as well in order to apply Onion Architecture. Both are independent each other. Therefore, you are free to use other than Onion Architecture for DDD (even traditional architecture such as MVC still fit in DDD). However, Onion Architecture is a strong candidate and suited for DDD.

What make Onion Architecture different with the Traditional one ? Lets see the traditional first and come up with Onion later.

In the traditional architecture, the application’s structure is comprises of three tier/layer such as depicted below:

Traditional MVC Architecture

As we can see, on this particular architecture each layer highly depends on the layers beneath it, and every layers normally will also dependent to some common infrastructures (e.g. frameworks or utility services). With this kind of architecture, it will be difficult to give a separation of concerns because of the created coupling between each layer (each layer is coupled to the layers below it, and each layer often coupled to various infrastructure concerns). Yeah, coupling is important in order to create the interaction between components in our system, but what i’m trying to say here is that this particular architecture creates unnecessary coupling.

For instance, let’s say the team had decided to use SpringBoot to build their microservices which represent the infrastructure layer. Subsequently, after couple years the team has decided to change the framework to another or perhaps just drop the SpringBoot. With this kind of architecture, it will be difficult to deploy the new framework without any adjustment (changes) in the other layers since each layer is highly coupled to the framework (infrastructure) layer. Thus, there will be a possibility for the team in breaking the current business layer which contains all of the business logic (business domain). Bear in mind that, a good system should have criteria MECE (Mutually Exclusive Comprehensively Exhaustive) a.k.a. “loosely coupled, highly cohesive”. Therefore, the more coupling you created in your system, there will be more effort you need to change the system and breaking it to small independent parts.

On the other side, the biggest offender (and most common) is the coupling of UI and business logic to the data access. Transitive dependencies are still dependencies. The UI won’t work if the business logic isn’t there, same as the business logic won’t work if the data access isn’t there. Data access changes frequently, and whenever the data access changed, you will also need to adjust / change the business layer with this particular architecture. And, did i mention before ? Changing the business layer which contains the business rule will have a big risk for the company, especially when the business already stable and the current system has widely used by the users in the Company.

Here’s why Onion Architecture come to the rescue :-). Take a look at the diagram below for the Onion Architecture.

Onion Architecture

There are lot aspects of Onion Architecture, but the main goal is how it controls the coupling. The basic rule that you need to bear in your mind is all coupling is toward the center. For instance in the depicted diagram we can say as follow:

  1. The “Infrastructure” layer will know about the “Application Services”, “Domain Services”, and “Domain Model”.
  2. The “Application Services” will know about the “Domain Services” and “Domain Model”.
  3. The “Domain Services” only know about the “Domain Model”.
  4. The “Domain Model” only know about itself.
  5. The inner layer will not and should not know about the outer layer. Hence, the “Domain Model” doesn’t know about “Domain Services”, “Application Services”, and “Infrastructure” layer. Same as the “Domain Services” doesn’t know about the “Application Services” and “Infrastructure” layer, and so forth.

In the very center, we see the “Domain Model” which represents the state and behavior of the model for the Organization/Company (i.e. the application we’re trying to build). Around the domain model are other layers with more behavior where the number of the layers can be vary (i.e. no restriction of the number of the layers).

“Application Core” will glue all the layers like “Domain Model”, “Domain Services”, and “Application Services” (again, the numbers of the layers can be vary which means we can have more layers rather than just those 3 layers).

“Domain Model” is the very center, and since all coupling is toward the center, then the “Domain Model” must be coupled only to itself as mentioned before. Typically, the “Domain Model” consists collection of interfaces called Repository Interfaces those provide saving and retrieving mechanism for objects in the system. Thus, i can say that the “Domain Model” defines the contract of the object’s system behavior especially for saving and retrieving mechanisms. Remember, only the interfaces (not the implementation). We can leave the implementation later on different layers (i.e. the infrastructure layer).

The outer layer (i.e. “Infrastructure” layer) is reserved for things that frequently changed. These things should be isolated from the “Application Core”. UI, Automation Test, DatabaseAccess, NetworkAccess, FileAccess belongs to this “Infrastructure” layer.

So, how does this “Onion Architecture” related to “DDD” ? We will see later once we get to the implementation. Just “stay tuned” :-).

Any comments or suggests would be well appreciated.

DDD Part II – DDD Building Blocks

It’s been a while since i wrote the first part of DDD series. Within this second part, i will continue with one of the most important thing of DDD before you’re going further with the implementation. First thing first, you must know about DDD building blocks as you can see below:

  1. Entities
  2. Value Objects
  3. Aggregate Roots
  4. Repositories
  5. Factories
  6. Services

Tighten your “seatbelt” :-). We’re going through the details of those aforementioned blocks now.

1. Entities

Entities (or “entity” in singular form) is a plain object that has an identity (ID) and potentially mutable. Each entity is uniquely identified by an ID rather than by an attribute, therefore two entities can be considered as equal (identifier equality) if both of them have the same ID, even though they have different attributes. This means the state of the entity can be changed anytime, but as long as two entities have the same ID, both are considered as equal regardless what attributes they have.

2. Value Objects

Value Objects are immutable. They have no identity (ID) like we found in Entity.
Two value objects can be considered as equal if both of them have the same type and the same attributes (applied to all of its attributes).
They are often uses for a thing like message passing and in fact they are particularly useful in the API layer within an Onion Architecture (going to talk about this Onion Architecture later) to expose your domain concepts without necessarily expose the immutable aspect.

3. Aggregate Roots

Aggregate root is an entity that binds together with other entities. Moreover, aggregate root is actually a part of aggregate (collection/cluster of associated objects that treated as a single unit for the purpose of data changes). Thus, each aggregate actually consists of an aggregate root and a boundary. For example, the relationship between Order and OrderLineItem within SalesOrder domain can be considered as an aggregate where Order acts as the aggregate Root, while the OrderLineItem is the child of Order within SalesOrder boundary.
One of the key features of an aggregate root is the external objects are not allowed to holds a reference to an aggregate root child entities. Thus if you need access to one of the aggregate root child entities (a.k.a aggregate), then you must go through the aggregate root (i.e. you can’t access the child directly).
The other thing is all operations in general within the domain should where possible go through an aggregate root. Factories, Repositories, and Services are some exceptions to this, but whenever possible, if you can create or require that an operation go through the aggregate root, that’s going to be better.

4. Repositories

Repositories are mostly used to deal with the storage. They are actually one of the most important concepts on the DDD because they have abstracted away a lot of the storage concerns (i.e. some form / mechanism of storage).
The repository implementation could be a file-based storage, or database (SQL / NoSQL based), or any other thing that is related with storage mechanism such as caching. Any combination of those are also possible.
Repository should not be confused with the data store. A repository job is to store aggregate roots. Underneath that, repositories implementation may actually have to talk to multiple different storage locations in order to construct the aggregates. Thus, a single aggregate root might be drawn from a REST API, as well as a database or files. You may wrap those in something called the data store, but the repository is sort of a further layer of an abstraction on top of all those individual data stores. Usually, i implement the repository as an interface within the domain/domain services layer within Onion Architecture (skip for now, gonna talk about this “Onion” later), and then the implementation logic of the repository interface is going to be defined in the infrastructure layer.

5. Factories

The factories are used to give an abstraction to the object construction (see Factory design pattern from GOF).
A factory can also potentially return an aggregate root or an entity or perhaps a value object.
Often times, when you need a factory method for an aggregate root, it will be rolled in to the repository. So your repository might have a finder create method on it.
Usually factory also implemented as an interface within the domain/domainservices layer with the implementation logic defined in the infrastructurelayer.

6. Services

A service is basically exist to provide a home for operations that don’t quite fit into an aggregate root. As an example, when you have an operation that you don’t know on which aggregate root it goes into, perhaps it operates on multiple aggregate roots or maybe it doesn’t belong to any existing aggregate root, then you can put the logic into a service. However, don’t be rush to put everything into a service. First and foremost, its better to carefully analyze whether the operation fits into one of the existing aggregate root or not. If you couldn’t find the aggregate root, subsequently better to ask your self in case you have missed one aggregate root or perhaps there are domain concepts that you haven’t considered that should be brought into your domain before you put the operation into a service.

Other Important Things

I often found that many developers use term VO (Value Objects) and DTO (Data Transfer Object) interchangeably. They consider both are just the same. This is quite annoying for me. In that case, i’d like to clarify here that both are refers to the different things.
As depicted on the picture below, VO and DTO are subset of a POJO (Plain Old Java Object) / POCO (Plain Old CommonRuntime Object). Entity is also a subset of POJO/POCO. 

In the above depiction, POJO and POCO can be interchangeably used. Both are refer to the similar thing. Both are just domain object that mostly represent the domain / business object within the business application.

The term POJO (Plain Old Java Object) was coined by Martin Fowler and very popular in Java community, while POCO (Plain Old CLR Object / Plain Old Class Object) is widely used in the dotNet.

As mentioned earlier, DTO, VO, and Entity are just a subset of POJO/POCO. However they are really different things as described below:

DTO is merely a stupid data container (only holds data without any logic). Thus, its anemic in general (only contains attributes and getter/setter). DTO is absolutely immutable. Usually we use DTO to transfer the object between layers and tiers in one single application or between application to application, or JVM to JVM (mostly useful between networks to reduce multiple network call).

VO is also immutable, but what make it different with DTO is that VO also contains logic.

That’s all for now, see you on the next part :-).

DDD Part I – Introduction

The first time I heard about DDD (stands for Domain Driven Design, not Deadline Driven Design forsure), that was when i was still working as a Senior Java Developer for Hewlett-Packard on its Development Center at Cyberjaya, Malaysia. I wasn’t quite interested with the topic since it was difficult to get a good resource during that time. Someone told me to find the Eric Evan’s book (“the blue book”), and gotcha..i got the book and added it to my PDF collection :-).

Few months ago, i started to join Bhinneka.com (i.e. one of the pioneer for e-commerce in Indonesia), and guess what.., as the new head of architecture and backend in Bhinneka, i decided to implement Domain Driven Design in our reengineering process (yes, you hear me right, we’re going to build Bhinneka’s software from scratch, not merely refactoring).

During this time, DDD is quite new (especially in Indonesia), thus only few companies have successfully implemented this DDD. And somehow IMO, i found that many DDD resources were too difficult to be grasped by most of the readers (i.e. they are too abstract and lack of good examples). Therefore, i’m planning to pick up this awesome topic and write it in a series, equipped with an application sample to be followed step by step.

This is the first part of another series those are still in my head as follow:

  1. DDD Part I, Introduction –> You are here
  2. DDD Part II, Domain Building Blocks
  3. DDD Part III, DDD and Onion Architecture
  4. DDD Part IV, DDD and Microservices
  5. DDD Part V, ES and CQRS – DDD’s best part (coming soon)
  6. DDD Part VI, Application Sample (coming soon)

In this first part of Introduction, i would like to start with some basic concepts as written below:

  1. What is DDD all about ?
  2. How do we get started ?
  3. What should we avoid in DDD ?

Let’s get started  :-).

1. What is DDD all about ?

To start this section, I’d rather took the definition from one of DDD’s community (i.e. dddcommunity.org), that describes DDD (Domain Driven Design) as an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.
As the definition implies, DDD is suitable for you if you’re building a software that has complexity on its business process (business domain). So, not every software is suitable for DDD (e.g.: CRUD application doesn’t suitable for it since it’s not quite complex).
Eventually, team work is very important within DDD since you need to keep in touch with the users/clients (a.k.a Domain Experts). Moreover, you build the software for them, not for you (you got the point right). Just like someone said: “the software can fail either in two ways, you build the things wrong or you build the wrong things”. In that case, you have to ensure that you understand correctly the business that you’re going to build. This is DDD all about.
To summarize, DDD can be described as a technique for developing software that focuses on collaboration between technical experts and domain experts. Therefore, we must keep focus with the domain experts instead of the nitty gritty details of the technical stuffs.

2. How do we get started ?

First thing first, as mentioned earlier, the big point is to keep in touch with the business/domain expert.

Following, i had recap several points those we can use as the guidance while we have discussion with the domain expert:

  1. Learning about the problem domain, i.e. the specific problem the software you’re working on is trying to solve. Look at the big picture of the current business process.
  2. Breaking the domain into sub-domains.
  3. Focusing on one sub-domain at a time with the domain expert, and always use ubiquitous language to define working out terminology.
  4. Creating a bounded context between sub-domain (again, ubiquitous language should always be used throughout the bounded context, from conversations to code, in the diagram, on the whiteboard, in the design document, team discussion, etc. The point is to use the bounded context everywhere).
  5. Ideally, there will be different team, codebase, and database for each bounded context.
  6. Since everyone are working for their bounded context, so they are free to change anything within their context.
  7. For all cross cutting concerns those are shared between bounded context (we call it shared kernel), any changes should be known and agreed between all team in every bounded context.
  8. Always stay focus with the domain’s behaviors rather than domain’s state (favor rich model over anemic model).

To summarize, always use ubiquitous language (i.e. same terminology) across the team, break the domain into smaller subdomains and give an isolation (i.e. bounded context) by defining the boundary and think about how the subdomain within the bounded context can communicate to each other using interfaces / crafted software contract.

3. What should we avoid in DDD ?

On the other hand, during our DDD implementation, we need to be careful for certain practices those are too common among software developers. These are :

  • Using data centric view when modelling the problem domain.

Usually data model is the first thing that an architect/developer would start to design. They always consider that data is the most important thing because data is all what we need to report. If you start with DDD, you must change this mindset. Data on its own is meaningless. Only logic gives data a meaning !!!, and the same data can have different meaning in different contexts. Therefore, we must start with context and logic instead of data.

  • Focusing on implementation details like entities, value objects, services, factories, repositories, etc instead on the core concepts discussed earlier.

Entities, value objects, repositories, and so forth don’t have a meaning until we defined the ubiquitous language, bounded contexts, and the interfaces /crafted software contract. If we start to early with the implementation details like entities, then it’s a good chance that the result would be an anemic domain surrounded by a lot of services and business logic scattered everywhere.

  • Using generic and developer specific terms and concepts when implementing the application.

We should never use concepts like save, update, delete, handle, manage, etc. Those concepts are too technical or abstract concepts with no specific meaning. Instead, we must stay focus with the business concepts. Those aforementioned concepts (i.e. save, update, etc) are not related to business concepts. To understand this, i encourage myself to always imagine the client run his errand/business without computers (i.e. doing specific task manually). So, always think from the business/domain expert perspective, and give a clear context on it. Avoid generic term that can lead to different meaning in different context (i.e. use specific context).

  • finally overrating DB transactions instead of focusing on the business processes or transactions.

Within DDD, business transactions is more important than DB transactions. DB transaction is ACID, strongly consistent, and short running, while business transaction is not. In fact, in the real life, we don’t know about DB transaction, we just know about business transaction. For example, imagine when you sit in the restaurant and order some foods and/or beverages. Within the order transaction, realize it or not, there will be a process with some asynchronous tasks with many possible inconsistent state changes, even by the end all states will be consistent (eventually consistent). And this blackbox process is works, scalable and widely acceptable by everyone.

Therefore with DDD, do not ever think about DB transactions, instead always think about the real world process such as what the possible actions (behaviors), and their possible outcome or about how to compensate the actions if some failures occurred.

You don’t have to understand all the aforementioned points for now. I know that most application developers not too familiar with the idioms and peculiarities of those concepts. Just keep reading for now, and hopefully they will become clear when the other parts coming.

Read the next part here.

Why do I choose Gradle Over Maven ?

Hi guys, it’s been long-long time since last time i wrote about JAXB (that was about 2+ years ago 😮 ).

Ever since that time, after leaving Hewlett-Packard (HP) in Cyberjaya, Malaysia, I had moved and being stucked here in Jakarta again when I received good offering from one of the DJARUM group’s company, PT. Global Digital Niaga which can be recognized from their product, known as blibli.

I was working for them as a permanent employee for almost 2 years since then. But now, I’m working as a freelance consultant and trying to create my own startup company.

For those of you that ever lived here (Jakarta), I strongly believe that You would agree with me if I say that Jakarta’s traffic is really horrible. In my opinion, if you live in Jakarta, working from home is more productive than working at the office. That’s one of the primary reason for me to choose working as a freelance consultant, because i don’t have to go to the office everyday and spent many hours on the road without doing anything (probably this will be different if you have your own driver ^_^. You can sit and coding with your laptop while you’re stuck with the traffic).

OK, enough with the chit-chat. Now, as mentioned in the subject, I will be quickly describing here several things why i won’t use maven and prefer to use Gradle as my project automation tools.

I’ve been using Maven for quite long. I ever heard gradle before, but never had the chances to try it until two months ago when I got an offer to develop KPI’s application in GMF Aeroasia (Garuda Indonesia Group). There are several issues which I’ve just noticed from Maven :

1. Maven promises “convention over configuration”, nonetheless it also promises about custom configuration such we found in Ant. However, writing custom extensions (plugins) in maven is overly cumbersome. You’ll need to know about MOJOs, including how to provide a plugin descriptor (XML based).

2. Sometimes, the default structure and lifecycle in maven can be restrictived and may not fit our project’s needs. Indeed, I don’t like the way of maven in customizing their lifecyle.

3. As i’ve known so far, Maven doesn’t automatically update their own core plugins. e.g. : support for unit tests (junit) to the latest version. Let’s say, if you’re trying to create new maven project from console by using command mvn archetype:generate…, you’ll get default maven pom which will be pointing to junit version 3.x (currently it’s already in version 4). so you’re gonna need to replace it’s version mannually.

Those are the reasons why I’d prefer to use Gradle now. Overall, Gradle was borned to addresses all of the issues which we found in Ant and Maven.

And for those of you, that having a plan to migrate your existing Maven’s project into gradle, You don’t need to be worried since Gradle has the ability to import any existing Ant/Maven build scripts and translate into Gradle rule set. How do you think ?