Principles and patterns for highly variable systems
Author: Martin Becker, Fraunhofer Institute for Experimental Software Engineering (IESE)
Contribution – Embedded Software Engineering Congress 2015
A look at industrial practice shows that most products and services are offered in multiple variants, and this variety is increasing. This presents a particular challenge for companies that manufacture embedded systems: how can this variety be managed efficiently and effectively? Besides ad-hoc approaches, such as cloning existing solutions, more strategic approaches, such as platforms, modular systems, or product lines, are often pursued. Appropriate product structuring is of paramount importance when dealing with systems with a high number of variants and has far-reaching consequences. But what characterizes good product structures? Are there principles and patterns that have proven successful at the architecture, design, and implementation levels? How do others do it? This article addresses these questions.
Identification of typical variant drivers
Before focusing on optimizing the product structure, it is essential to first consider the drivers of product variants. Reis et al. [1] conducted a study on product variety and its management. Based on 60 studies across various manufacturing and service sectors, they examined both internal and external drivers of product variants. According to their findings, the main factors are differing customer needs, the evolving range of technological implementation options, and cost pressures. These drivers are generally only partially controllable, making it often difficult to avoid product variants altogether.
Especially regarding the software component of embedded systems, there's a prevailing opinion that it can be adapted quickly and cost-effectively to new requirements, which, compared to hardware, is initially true due to its extremely low production costs. Naturally, the necessary adjustments are then shifted to the software. Over time, this quickly leads to highly customizable, configurable, and parameterizable software solutions that become increasingly difficult to maintain and configure. Many embedded software developers have experienced this preprocessor or Makefile hell firsthand in one form or another.
The evolution of the relatively compact operating system FreeRTOS provides a good example of how the initially clear product structure is increasingly affected and eroded by the introduction of new product features. Figure 1 (see PDFThe diagram shows three code states over time, with the internal features controlled by preprocessor directives colored differently. If changes need to be made in the colored areas, where many features have an impact, significantly increased implementation and quality assurance efforts, as well as a higher risk of errors, are to be expected.
A primary recommendation regarding product structuring is that variant drivers—even if they cannot be eliminated—should at least be identified as early as possible and considered during planning. This allows for proactive and appropriate measures to be taken within the product structure, thus enabling better control of evolution. In practice, scoping workshops, conducted periodically, have proven effective in maintaining a shared understanding between sales, marketing, and engineering regarding which new product features should be implemented in future releases and at what cost. This shared understanding is often lacking, leading to unnecessary erosion of the product landscape.
Structuring principles
In general, the same architectural principles that apply to single systems also apply to the structuring of systems with many variants. Reference [2] presents, among others, the following general principles relevant to software engineering: the principles of abstraction, structuring, binding and coupling, hierarchization, and modularization. These principles lead to a clearer product structure and thus also facilitate necessary adaptations.
When dealing with numerous product variants, it's essential to maintain an overview of where the variants are structurally similar and where they differ. This can be achieved through a documented reference or product line architecture that clearly illustrates the differences. It's crucial to precisely identify the points where changes occur (the so-called variation points) and to demonstrate the relationship between these differences and the core product characteristics. Such an overview should definitely include the technical perspective, i.e., the product's components (keyword: bill of materials) and its construction. However, it's also highly beneficial to have this overview for the logical and functional perspectives as well. In practice, this is often lacking, and the resulting shortcomings typically lead to increased development costs when changes are required, as the necessary modifications couldn't be accurately estimated.
When structuring the product, care should be taken to ensure that the influence of a variable feature on the structure is clearly understood and that the structure is optimized, if necessary, to facilitate the implementation of planned changes. For example, if scoping reveals that the collected environmental data, and consequently the embedded system's sensor data, is likely to change frequently over time (this is schematically illustrated in Figure 2, see...), then... PDFIf this is the case, then the product structure should be specifically optimized for this change. For example, sensor connectivity and data processing should be moved to modules that can be easily replaced. A structure where the individual aspects of data acquisition and processing are broadly distributed across the product structure (see Figure 2) is also recommended. PDF), would then lead to increased change costs each time.
With regard to improved modifiability and thus maintainability of source code, the SOLID principles, coined by Robert C. Martin [3], have proven very helpful. These principles can also be applied to product structure. The acronym SOLID stands for:
| principle | Key message |
| Single Responsibility Principle | Modules should have clear responsibilities. |
| Open-Closed Principle | Modules are open to extensions, but closed to modifications. |
| Liskov substitution principle | If modules are replaced, then the special modules should behave like the base module. |
| Interface segregation principle | A module must not depend on functions of another module that it does not use. |
| Dependency inversion principle | Avoid strong coupling between modules through appropriate interfaces. |
Table 1: SOLID principles
The open-closed principle is often disregarded in practice. Analysis of software implementations frequently reveals modules where new variants of a feature have been added over time, such as new sensor drivers or filter functions selected via preprocessor directives or conditional execution. The module's structure then resembles that of the module shown in the lower left of Figure 3 (see...). PDFHere, the various aspects of the variants are not clearly separated but combined in a single module. With each extension, the module becomes increasingly larger and more difficult to understand, and the quality of the entire module must be ensured. A division into smaller sub-modules, which are then selected and integrated via an external mechanism, as shown in Figure 3 (bottom right), would significantly simplify the necessary changes. This approach employs a so-called module replacement mechanism in conjunction with indirection as a variability mechanism, and the open-closed principle is taken into account.
The open-closed principle is particularly recommended where variants with open diversity arise, meaning that new variants emerge during development. Typical examples include collected and processed data, sensors/actuators, communication channels, user interfaces, and external interfaces to third-party systems.
One final recommendation in this article concerns the separation of common and variable components. Ensure that these are clearly separated and that this separation is easily understood by both humans and machines. For example, simple structuring and naming conventions allow different module types or preprocessor constructs to be easily identified and analyzed using tools [4]. This makes managing the evolution of the product structure significantly easier. So, here too, the adage holds true: a well-structured approach is half the battle.
Bibliography and list of sources
[1] A. da Cunha Reis, LF Scavarda, and BM Pancieri, „Product variety management: A synthesis of existing research,“ African Journal of Business Management, vol. 7, no. 1, pp. 39-55, Jan. 2013.
[2] Helmut Balzert, „Textbook of Software Engineering: Basic Concepts and Requirements Engineering“, Springer 2009
[3] https://de.wikipedia.org/wiki/Prinzipien_objektorientierten_Designs
[4] Bo Zhang, Martin Becker, Thomas Patzke, Krzysztof Sierszecki, and Juha Erik Savolainen, „Variability evolution and erosion in industrial product lines: a case study“. In Proceedings of the 17th International Software Product Line Conference (SPLC '13).
Software Engineering Management – our training courses & coaching sessions
Do you want to bring yourself up to date with the latest technology?
Then find out more here MircoConsult offers training courses/seminars/workshops and individual coaching on the topic of Software Engineering Management / process, project and product management.
Training & coaching on the other topics in our portfolio can be found here. here.
Software Engineering Management – Expertise
Valuable expertise in software engineering management / process, project and product management is available. here Available for you to download free of charge.
You can find expertise on other topics in our portfolio here. here.
