When starting to work on a new project, developers tend to jump straight into programming. And that’s ok — it’s their job after all. But sometimes it might be good idea to jump on the breaks and start with some software designing.
Software design can be done with several different ways. It can be done utilizing some software using some modeling language, such as UML, it can be written text and images or it can even be a drawing on a whiteboard. Important here is that the design can be saved and revisited during the development of the software — The design will need some refining so if you don’t want to always draw the design to the whiteboard from scratch, it might be good idea to stay with digital ways of doing the design. This and how it’s done of course depends on your projects needs. Small projects can easily be just drawn or written on a single paper while bigger projects usually tend to change a lot during their lifetime affecting also the software design.
I must admit that I am one of those persons who like to jump into the code straight away and I haven’t done so much software design, at least not very detailed, in my previous projects. Also I have somewhat hated all the bureaucracy what software design can introduce to the work at its worst. Of course I have done single component designs drawn on a whiteboard or to a notebook but most of these designs are forgotten and never maintained once the code has been completed. During my current position I have learned a lot about software design and while there is lot more to learn, I have noticed and would like to share some good things about it and why it’s important.
You should be able to split your software into smaller pieces with maybe maximum of 5–10 interfaces. These interface “groups” are called software components. Main idea of the software component is to provide a single purpose for the software that is being developed. Example of this would be Game statistics for a Super Mario Bros 3 that is responsible of keeping book of score, lifes and other things needed by the GUI renderer.
When you have a modular software, it’s easy to move or even remove things if needed and even share the design work between multiple developers per software component. Having modularity also increases maintainability by making it easier to find necessary information to edit from the right component. It can also be basis for your source code namespacing or structure ase well as isolating the test cases per component.
With good software design it’s easier to maintain the software. You can spot straight away from the design how much a bug fix or introduction of a new feature will change the existing code base. As good design should also show interactions between software components and their interfaces, it will also reveal possible effects of changing code in another component that depends on the one needing the change. Working especially with old code bases that do not have any software design can be very painful and cause many unexpected bugs.
When doing the design I have noticed a lot of unnecessary interfaces that are not actually needed and not requested by the customer. While this kind of things can easily be found from the code, usually no one pays attention to the extra functionality. Extra functionality means extra maintaining, testing and development. No one really wants that so one should keep it simple and do what needs to be done, nothing more.
Good software design can be used to easily pinpoint performance bottlenecks in your software — especially if the design is done to the level of that granuality. This means the design should tell how your system works internally and how it uses resources such as threads, database connections and other things that might make a hit to the performance. Sometimes it’s very easy to debug or use some logging functionality to find the bottlenecks from the source code but sometimes the design can tell it by a single image.
While it’s good to have detailed software design, you should never over-design it. Not every loop or condition needs to be designed — doing that would make the maintainability of the design a living hell as the iterations between design and development goes on. Also it does not bring any extra value to the developers nor the customers who might see your software design in a form or another.
By including dependencies to other software modules, such as 3rd party libraries, in to your design makes the software much easier to port into another environment. Having these documented in a single place makes it super easy to discover what needs to be changed if using another environment or if it can be done at all.
Yet again you might not want to design all function calls to 3rd party software as updating the version or changing the underlaying library would mean total redesign. Here again, remember to do what’s necessary for everyone to understand how the software works.
Generating a design document for your customers from the software design is a good idea. It provides them an overview how the software they are about to take into use works. You might need to consider if you want to publish only your public interfaces and leave your internal design out of the document as good design makes it possible to very easily write the software from scratch.
The design also works as a great starting point for new-comers. Instead of making them look through all the source files you can just point them to the software design where they find all information they’ll need to get started.
Usually projects have requirements coming from either a customer or from an internal source. Good design also tracks the requirements and proves on the design level that all that is required from a piece of software is actually there and that it’s understood correctly. This brings even more value to the provided design document as the customers can actually see what of their requirements are done and where. To integrate this with source code, some kind of linking between the design, requirements and the source code is more than advised.
Design should also provide information what the software deliverables are and where should they be placed in the deployment. This information is very important for your customers as well as integration as they need to know where to look for your library/executable/whatever your software is about. It makes it easier to spot right away if the latest delivery is missing some crucial parts of the software by simply taking a look at your design.
Now that I have pointed out some topics why software design is important it’s time to think what it takes. Doing a great software design takes discipline and commitment from the whole team working with the software. Sometimes it takes a lot of iterations to get the design and the software match — even if you are super hero of the computer age, you might not notice all things before you start writing the code. And that’s ok, iterations will strengthen the code as well as the design. It just takes time and some hard work but eventually it will pay off and reduce all kinds of risks with the software. If you don’t believe me, try it out with your next software project!
I am Heikki Hellgren, Software Expert and technology enthusiast working at Elektrobit Automotive. My interests are in software construction, tools, automatic testing and all the new and cool stuff like AI and autonomous driving. You can follow me on Medium and Twitter. Also you can check out my website for more information.