Designing Systems
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
1. Understand the problem
Always remember that you are human
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.
Be inclusive
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.
Speak the same language
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.
2. Design your system
Take a paper and a pen
Because if you can not design it, you can not explain it to other.
Create the border
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.
Find what are the events that provoke a response from the system
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.
Design the model
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.
Find the core components
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.
3. Agree on the design
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.
4. Refine your Design
Describe the model
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 the initial states of the core components
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 the messages
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.
5. Generate your system
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.
There are many tools that can use to the model generation, find the one that fills your needs. If you focus on JavaScript, you can try System Designer, a web IDE that I have created in order to design and create systems. It is open source and free.
Conclusion
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.