Everytime I have to fix a bug, I follow the same workflow: when someone at the QA team found a bug, she/he send me a bug report with the steps to reproduce (STR) the issue. And if I do not understand the STR, I generally come to see her/him so that she/he can show me the bug on her/his computer.
This workflow seems quite common in many companies and I often say to myself that it must have a better way to get the context of an application before a bug happened.
But what could be this better way? Ideally it could be great to make a snapshot of the application before the bug occured so that we could fix the issue from that state.
For example let’s say that we have an application in the state we want and that we can save that application into a format that can be then loaded to restore that state. For sure the resolution of the fix would be faster and easier.
In fact, the new worflow could be something like that:
In this example we have a todo app (the basic TodoMVC app) in a specific context (with one task). We export the context of the application in a bundle (a stringified JSON object), open a new blank page and then install that bundle. Then we see our application running on the new page with the correct context. So we can start using the application from that context.
It means that, as a developper, I will have only to load a JSON that someone at the QA team send me to get the context of the application and fix that bug. Much simpler, does it?
In the video, we can export the state of this application and restore it at runtime because:
- the application was designed as a system and
- the application objects (components, methods, models) are stored at runtime in a tiny NoSQL Database.
When we create an application, we create in fact a system. A system is defined by a model, is composed by components and reacts to events with behaviors. As you see, these concepts are quite common with the applications we create every day.
So what differ a system from an application ? With systems we focus first on the design before focusing on the code. How to do that ?
- First design the model of your system,
- then find all the components that you will need to start your system and
- then create these components and implement its behaviors (with methods).
You need to make a complete disctinction between the design and the runtime of your system. Design must always be declarative and execution imperative. How to do that? Use UML to define your model and integrate it into your development workflow.
Once we have the system ready to be executed, we need to store it in a NoSQL Database. It is possible because everything you have created can be managed as a document. Let’s say we want to store an object in a database, we need to serialize it in JSON, but if we only store its state this process will be easier. And it is what is done in the video. Models and behaviors are also serialized so that the entire system is stored in a database.
And what about runtime? What if we update an object in the current application? Because all objects states are stored in a database, we have a complete ODM (Object-Document Mapper). It means that an update to an object of the system will automatically update its state on the database.
So now exporting the current state of the system is like making a dump of the database. And restoring the state of the system is like importing the dump into the database. Quite simple, isn’t it?
I will develop the concepts and patterns I talked about in a forthcoming post but if you want to create some systems right now you can:
- read the book Thinking in Systems from Donella H. Meadows. A great introduction to the world of systems.
Credits: cover image by Ant Rozetsky.