The last version is a version 2.x. Apart from possible urgently needed bugfix releases – let’s hope that won’t be necessary – there won’t be another version 2.

A version change in the so-called major version usually only occurs when there is a very fundamental change to the software product. With the version change from 1 to 2, for example, completely new functionality was added with the file functions, which required, among other things, the additional permissions to the file system access on your devices.

After more than three years of more or less uninterrupted development, the GC Wizard has become much bigger and more complex than it could even have been dreamed of at the beginning. The steadily growing complexity also led to many problems in the internal development. So it is now time to take the underlying code base and critically review it. Is the structure and approaches chosen at that time still appropriate concerning the today’s project? And can it still support further potential growth?

Software Architecture

Decisions about the structure of code and the programming principles can – roughly speaking – be described as Software Architecture. The decisions that led to the current architecture were based on assumptions of much less supported tools and also the pessimistic view that no one but me would ever really work on the project permanently. Now, thanks to Thomas and Mike, I’ve been proven wrong, and on the other hand, I’ve had to realize that the decisions I made back then no longer meet today’s requirements.

We have many places where the code base no longer meets the requirements of clean code. The most serious part is the current Technical Layering. This means that I had originally decided to strictly separate calculation logic and output entirely, i.e. the representation in the app, which is a as classical approach in the theory of software architecture. This leads to writing the code for the logic of a concrete tool into one directory and the code for the presentation into a directory in a completely different path. This works well as long as one thinks in small scales.

But by now, in addition to program logic and displays, we have translation files, files for searching, the registry for the main menu, and more. So a new tool, as small and simple as it may be, immediately spreads all over the entire project, which now has over a thousand folders. So it’s increasingly hard to keep track of which part belongs to a certain tool and where you would find it.

The solution is a so-called Domain Layering. Here, the technical view “calculation logic vs. output” does not take precedence, instead it is tried to keep all parts of a specific tool, a closed domain, together. After that, you can think about how to do the technical layering – just on a smaller scale, exclusively at the tool level and not project-wide. This makes it easier for us to get an overview and also simplifies the entry for potential future co-developers.

Technical Layering
Domain Layering

The Steps

First, of course, a lot of files and directories have to be rearranged. Here we can rely a little on the support of our development environment, but there is still a lot of manual work to do within such a complex construct.

After that, it should also be checked whether certain files can be merged or should be separated. Do they still fit into the context in which they were introduced earlier? In the worst case, this leads to a manual review and check of all files.

We have two files, which are several thousand lines long – much too long to still master them as a human being – because we register all our tools there, i.e. for the main menu. The goal is to create a possibility, where also here on the one hand the complexity of these files is reduced, but on the other hand also the here likewise existing spreading of the tools further to reduce (the file for the main menu is naturally not to be found somewhere at a certain tool, but is a further point somewhere in the code). This possibility is called Reflection, which is common in the area of other programming languages, like Java, but is not easy to realize in our Dart-based system. It will technically work, but in some circumstances this could give significant speed penalty on app launching. However, we can only try this out. And if the worst comes to the worst, we will have to look for a compromise.

Conclusion

Currently, the largest internal rebuild that the project has seen so far is taking place. Many things have to be considered and in the end everything should remain the same for the user. The user does not benefit from a change of the version number so far, but for us as programmers this Sisyphos work is a huge step to make the project more future-proof.

But of course, from the user’s point of view, a lot of things will happen after the rebuild and great things are in the offing. More about that later 🙂