Skip to content

QEP: Enhancement of code structure and software design

felix edited this page Sep 27, 2020 · 9 revisions
Author: Fredo Erxleben
Status: WIP
Created: 13th November 2014
Updated: Felix (2016-2020)

Link to associated github project. Work in progress.

Motivation and Aim

The current code structure of Qucs has grown organically over the last years. The initial design can not cope with the extensions that were made. Especially the lack of unified coding style and additions made in parallel by differnt people led to a very heterogenous and uncoordinated structure of the project. Further addition will only worsen this situation if the currently stable code is not cleaned and partially redesigned.

The goal of a extensive code refactoring and cleanup is to provide a basis for future independent additions, allow a better maintainance and make it easier for new developers to get familiar with Qucs.

Issues and proposed solutions

Design

  • Model and representation are completely merged They should be strictly seperated from each other. Currently, the model is derived from the visual layout of the schematic.Classes often represent things in the model and the view at the same time and the different aspects are merged together into a incomprehensible design. To counter this, a new class structure with strictly defined responsibilities needs to be defined.
  • Very broard inheritance tree for Components. Components need a deeper class hierarchy, instead of inheriting everything directly from the component class. Introduction of intermediate levels also would reduce code duplication and maintainance issues.
  • Iteration over composite structures are elaborate. The parts of which a schematic is composed should implement a visitor pattern to ease the countless iterative tasks on the model which arise e.g. during netlist and HDL generation or GUI refreshes.
  • To avoid issues with deeper class hierarchies, the visitor may be combined with a strategy pattern.
  • Some parts of the implementation do not reflect modern development techniques. Structs and Typedefs should be removed. At least C++11 should be used. This interleaves with the coding-style issue.
  • Visibility is mostly public. This contradicts the principle of least visibility and must therefore be changed.
  • Enumerations are often done via #define. Proper types (e.g. enumerations) should be used instead.
  • A lot of things are in the default namespace. The namespace structure should be more granular and nothing should be in the default namespace at all.
  • Const Correctness Mutable pointers to random instances passed around for external modification is hard to track down and error prone. Interfaces without proper constness decorators are sometimes hard to understand. Const correctness should be implemented whenever code is modified.
  • Proxies Instead of multiple dereferencing, proxies should be implemented and used. Proper names help the reader understand what is going on.
  • Reveal Problems If you edit code that you identify as bogus, add a comment for other developers. Unless you have time to refactor right now.

Organisational

  • No common coding style is agreed upon.
  • Documentation coverage is low. Everything should be documented extensively. Ensuring a good documentation quality requires to only allow pull-requests of sufficiently documented code into the master-branch. A good opportunity of drastically increasing the code coverage would be during the refactoring. Any class that is refactored should not be pushed into the refactoring-branch unless it is documented completely. Even things that are not visible to the outside must be provided with documentation for later developers.
  • Test coverage is low. Unit tests should cover at least 85 percent of all code. Since Qucs already is build a lot on the Qt-framework, using the provided QTest environment might be a good choice. Additional optional features are:
  • Automated running of tests upon upload
  • Measuring of actual test coverage

Proposed procedure

Initial steps

The earlier improvements on the source code start, the less work there will be. Any ongoing task should be completed and no new task started. From then on the current functionality of Qucs will be frozen. After refactoring, this functionality level should still be achieved.

At this time, a target design and coding style could be agreed upon.

During refinement

Refinement should take place in a dedicated branch. During refinement, no new features must be added.

After refinement

The proper working of all functions has to be confirmed.