In my previous post I explained that, as a developer, you do not create applications but in fact systems, living entities that react to their environment (browsers, servers, …). On this post I will describe a process that you can follow in order to create systems. This process has been inspired by the amazing work of Donella H. Meadows, the B-Method that I learned at the University and the Domain Driven Design.
This process is composed of 5 steps:
- Understand the problem
- Design your system
- Agree on the design
- Refine your design
- Generate your system
In order to create systems you need first to realize that you perceive things and understand the world as a human beeing. It means that when we think to a specific problem, we resolve it with our own mental representation of the world. We are never objective when we think. We are limited by our culture, life experience, mother tongue, … We can miss useful informations because we can not see them from our perspective. As a result the more you are and diverse you are to solve a problem, the better solution you get. So create the most diverse team you can and invite them to a meeting to start designing the system.
First of all listen without interruption people that are asking for a feature/solving a problem/… . Then ask questions about the context. Get the maximum informations you can and make all the team talk. It is very important. Everybody needs to feel heard during the meeting in order to be able to share without difficulty their own understanding of the context.
The main issue in project is always communication, so be sure that everyone speak the same language, the user language, and not a technical one. For that purpose note on a paper all the words you use to define the context and write their definitions. So that everyone will know what you are talking about.
Because if you can not design it, you can not explain it to other.
Draw a big circle that represents the border of the system. Then write all the words taken from the list you made.
Write inside the circle the concepts that you think are part of the system. Write outside the circle the concepts that you think are not part of the system.
The border depends on your comprehension of the system and could change from one perspective to another. For example: when designing a web app, you can include the server in the system… or not. It depends on where you put this border.
Then look at the concepts that you put outside the system. Think how these concepts can interact with your system.
Create arrows that go into the system for each message that could be send to the system. And name the event responsible for this message.
Create arrows that go out the system for each message that could be send from the system. And name the event responsible for this message.
Now look at all the words that you put inside the system. Create a square around each word. Then draw a line between each square that you think are related together. Do not add information on the link, just draw a line. The idea is to have an global overview of the concepts and their relations.
Name the components that you need to have to start the system and draw little circles that represents them. We will call them the core components.
Now we have a complete overview of the system. We know:
- what is the border of the system,
- what are the events that provoke a response from the system,
- what is the model of the system and
- what are the core components of the system.
Be sure that everyone agree on the design and understand how the system is composed.
Now that everyone agree on the design, you can describe more precisely the model. To do that, you need to ask:
- What are the properties of the model?
- What are the behaviors of the model?
- What are the type of links. Are they collection, inheritance, …?
- What are the events send by the model?
I encourage you to use UML to define the model. But keep it simple like we did before. Always use design that everybody can understand.
Find what are the initial values of the core components of the system. The question you have to answer is simple: at which states the core components needs to be in order to start the system?
I encourage you to describe these values in a JSON object. It is human readable format that you can easily update.
Define what are the types of the messages send to the system and returned by the system.
Use also UML to define the structure of the messages.
Now you have define the model and find the initial states of the core components, generate the system from the model. Do not start to code, otherwise your code will be always desynchronized with your model. Then implement the behavior of your system from the generated code.
Designing a system is a complex task that needs the work of everyone. Technical skills are not necessary to design a system, but human skills are mandatory.
It was a quick overview of the process I use when I create systems. I did not go into specific details, I only described the main steps of this process so that you can adapt it to your work.
In my next post I will go more deeper on the model designing process and explain how to have a model synchronized with your running system.
Credits: cover image by Sergey Zolkin.