Handling Complex Business Scenarios with Domain Modeling — Part 1

Do you still use process-oriented code in an object-oriented language for your business? Does your business suffer from complex business logic?

Oftentimes business requirements and organizational changes are much more varied than the underlying technological infrastructure. Packaging these changes requires good business understanding, abstraction, and modeling capabilities.

Today we invite Alibaba senior technical expert Zhang Jianfei to talk about why domain modeling is necessary, what a good model looks like, and how to build it.

Why Is Data Modeling Necessary?

That’s why, in a simple business scenario, I strongly recommend using event scripts. They are simple, intuitive, and easy to use. However, for complex business scenarios, you will not be able to take this course of action, because once the business becomes complex, event scripts quickly become difficult to deal with and easily result in code pancaking. The speed and complexity of system corruption will increase exponentially.

Currently, the most effective approach is domain modeling, because the domain model is object-oriented, encapsulates business logic, and enhances the cohesion and reuse of objects because of the use of Ubiquitous Language. This gives explicit expression to hidden business logic, making complex governance possible. Talk is cheap, so let’s get into the example of a bank, compare event scripts with the domain model, and see which is more advantageous.

Benefits of Domain Modeling


  • Polymorphism: OverdraftPolicy with policy mode (a typical application of polymorphism) improves code extensibility.

Explicit Business Semantics

  • Explicit: This refers to extracting hidden business logic from a pile of if-else statements, use language to name them, write code, expand it, and then turn it into an explicit concept. For example, the crucial business concept of the “Overdraft Strategy.” According to the way in which we write the event script, its meaning is all over the code logic but is never explicitly dated. Anyone looking at the code would be flabbergasted; however, the domain model uses a strategic method to abstract it, not only increasing the usability of the code but making it much more scalable.

How Do We Implement Domain Modeling?

Modeling method

So what is the two-step modeling method? It only takes two steps to create the model; first, we find nouns and verbs from the user stories, and then use the UML class to draw the domain model. Pretty streamlined, right? Just because something is streamlined doesn’t mean that it’s simple. This is often the holy grail for business architects and system analysts.

For example, if we design an intermediary system, then a typical user story might be “The user is looking for work, and the agent asks him to leave his phone number to be contacted if there is a job available.” The keyword here is likely the domain object we need. The user is a job seeker, while the phone number is a property of job seeker. The Agent contains two keywords in agency and agent, and the job is a keyword domain object. Notifying this verb tip, we use observation mode. Then, sort out the relationship between the domain objects. A job seeker can apply for multiple job opportunities. Also, multiple job seekers can also apply for the same job, which is an M2M relationship, and intermediary companies can include numerous employees, which is an O2M relationship. In a simple scenario like this, this kind of modeling is sufficient.

Of course, our business scenarios are always more complicated than this, and not all nouns are domain objects; they could be properties. Likewise, not all verbs are methods; they could be domain objects, so we need to use specific solutions for specific problems. This process of problem-solving requires that we have an excellent understanding of the business, abstract ability, and modeling experience (we know now why the job model of all those companies emphasize that technicians have a keen ability to understand business and abstract). For example, in most situations, price and inventory are just properties of an order and a product; however, at Alibaba, the complexity of price calculation and inventory reduction would make your head spin. Therefore, as an e-commerce platform, treating price and inventory as separate domains is a matter of necessity.

Moreover, modeling is far from a one-time job. Our view of the overall picture will always change as business changes, and our understanding of it improves, so iterative restructuring is unavoidable; making Modeling Agile, is crucial.

Model Unification and Model Evolution

Both parties have difficulty accepting the other’s model because it doesn’t fit their own experience. In fact, they need a new abstraction. This abstraction needs to combine the “liveness” of the snake with the “water spraying” of the fire hose. This abstraction should also exclude some of the inaccurate interpretations of the previous two models, such as fangs or that ability to be rolled up and put in the back of a truck. This is how we can unify the models.

The only thing in the world that doesn’t change is the change itself. Models and code also need constant reconstruction and refinement. After each refinement, developers should have a clearer understanding of the domain. This makes breakthroughs in understanding possible.

Afterward, a series of rapid changes result in models that are more user-friendly and more realistic. Its functionality and descriptiveness increase rapidly, and complexity disappears.

This breakthrough requires us to have a deeper understanding of the business and thought processes behind it. Then we build up the courage and ability to restructure. Courage comes when the project deadline is tight, and you have to decide if you can even dare to restructure. Ability indicates whether or not you have a complete CI to guarantee that restructuring the code won’t break other existing business logic.

Let’s look again at the example of account transactions that kicked off this piece. Let’s consider complex case where we have to support cash, credit card, Alipay, Bitcoin, and other payment channels. The restrictions for each channel are different, and we have to support one to many transactions. In this case, we can’t possibly still use a transfer(fromAccount, toAccount) method. Instead, we need to abstract a specialized domain object called Transaction so that we can better express the business. The evolution of this object is as below:

Continue reading Part 2 of the article.



Follow me to keep abreast with the latest technology news, industry insights, and developer trends.