Experience Embedded

Professionelle Schulungen, Beratung und Projektunterstützung

Gut strukturiert ist halb gewonnen

Autor: Martin Becker, Fraunhofer Institut für Experimentelles Software Engineering (IESE)

Beitrag - Embedded Software Engineering Kongress 2015

 

Der Blick in die industrielle Praxis zeigt, dass die meisten Produkte und Dienstleistungen in mehreren Varianten angeboten werden und dass diese Variantenvielfalt steigt. Dies stellt gerade auch Firmen, die eingebettete Systeme herstellen, vor die Herausforderung, wie diese Variantenvielfalt effizient und effektiv beherrscht werden kann. Neben ad-hoc Ansätzen, wie dem Klonen existierender Lösungen, werden dabei häufig auch strategischere Ansätze, wie Plattformen, Baukästen oder Produktlinien verfolgt. Eine angemessene Produktstrukturierung ist beim Umgang mit varianten-reichen System von größter Wichtigkeit und bringt weitreichende Konsequenzen mit sich.  Doch wodurch zeichnen sich gute Produktstrukturen aus? Gibt es Prinzipien und Muster, die sich auf der Architektur-, Design-, und Implementierungsebene bewährt haben? Wie machen es andere? Mit diesen Fragen beschäftigt sich dieser Beitrag.

Identifikation von typischen Variantentreibern

Bevor man sich mit der Optimierung der Produktstruktur beschäftigt, sollte zunächst betrachtet werden, wodurch die Produktvarianten getrieben werden. Reis et al. [1] haben hierzu eine Studie zu Produktvielfalt und deren Beherrschung durchgeführt. Anhand von 60 Studien in unterschiedlichen Fertigungs- und Dienstleistungsbereichen haben sie sowohl interne als auch externe Treiber für Varianten untersucht. Hauptfaktoren sind danach die unterschiedlichen Kundenbedürfnisse, die sich ändernde Vielfalt an technologischen Realisierungsmöglichkeiten und der Kostendruck. Diese Treiber lassen sich in der Regel nur begrenzt beeinflussen, wodurch die Vermeidung entsprechender Varianten oftmals schwer fällt.

Gerade für den Software-Anteil der eingebetteten Systeme herrscht die Meinung vor, dass dieser schnell und kostengünstig an neue Gegebenheiten angepasst werden kann, was im Vergleich zur Hardware aufgrund der äußerst geringen Produktionskosten zunächst auch richtig ist. Naheliegender weise versucht man die erforderlichen Anpassungen also in die Software zu verlagern. Dies führt dann im Laufe der Zeit recht schnell zur hochgradig anpassbaren, konfigurierbaren und parametrierbaren Softwarelösungen, die immer schwerer zu warten und zu konfigurieren sind. Viele Embedded Software Entwickler haben diese Präprozessor- oder Makefile-Hölle in der einen oder anderen Form schon am eigenen Leib gespürt.

Am Beispiel der Evolution des recht kompakten Betriebssystems FreeRTOS zeigt sich recht gut, wie die initiale klare Produkturstruktur immer mehr durch die Einführungen von neuen Produktmerkmalen beeinträchtigt wird und erodiert. Abbildung 1 (siehe PDF) zeigt drei Code-Stände im Laufe der Zeit, bei denen die internen Features, die durch Präprozessordirektiven gesteuert werden, unterschiedlich eingefärbt wurden. Müssen Änderungen in den bunten Bereichen durchgeführt werden, in denen sich sehr viele Features auswirken, ist mit stark steigenden Implementierungs- und Qualitätssicherungsaufwänden und erhöhtem Risiko von Fehlern zu rechnen.

Eine erste Empfehlung im Hinblick auf die Produktstrukturierung ist, dass die Variantentreiber – wenn sie nicht eliminiert werden können – doch zumindest möglich frühzeitig erkannt und bei der Planung berücksichtigt werden sollten. Dann lassen sich in der Produktstruktur proaktiv geeignete Vorkehrungen treffen und die Evolution damit besser beherrschen. In der Praxis haben sich hier Scoping-Workshops bewährt, die von Zeit zu Zeit durchgeführt werden, um ein einheitliches Verständnis zwischen Vertrieb, Marketing und Technik aufrecht zu erhalten, welche neue Produktmerkmale zu welchen Kosten in den nächsten Releases bereitzustellen sind. Dieses Verständnis liegt oftmals nicht vor, was dann zu unnötiger Erosion in der Produktlandschaft führt.

Strukturierungsprinzipien

Generell gelten für die Strukturierung von variantenreichen Systemen die gleichen Architektur-Prinzipien, die auch für Einzelsysteme gelten. In [2] werden unter anderem folgende allgemeinen Prinzipien vorgestellt, die für die Softwaretechnik relevant sind: Prinzip der Abstraktion, der Strukturierung, der Bindung und Kopplung, der Hierarchisierung, und der Modularisierung. Sie führen zu einer klareren Produktstruktur und erleichtern damit auch notwendige Anpassungen.

Beim Umgang mit vielen Varianten ist es zunächst hilfreich, stets einen Überblick zu behalten, wo sich die Varianten hinsichtlich ihrer Struktur ähnlich sind und wo sie sich unterscheiden. Dies gelingt über eine dokumentierte Referenz- oder Produktlinienarchitektur, die die Unterschiede klar aufzeigt. Dabei ist es wichtig die Stellen präzise zu identifizieren, wo sich Änderungen ergeben (die sogenannten Variationspunkte) und den Zusammenhang zwischen den Unterschieden und den zentralen Produktmerkmalen aufzuzeigen. Solch eine Übersicht sollte auf jeden Fall für den technischen Blickwinkel, d.h. aus welchen Teilen das Produkt besteht (Schlagwort Bill-Of-Material) und wie es gebaut wird, bestehen. Es ist aber auch sehr hilfreich, wenn diese Übersicht auch für den logischen und den funktionalen Blickwinkel vorliegt. Dies ist in der Praxis häufig nicht der Fall, und wird dann in der Regel mit erhöhten Entwicklungskosten im Falle der Änderung bezahlt, da die notwendigen Änderungen nicht richtig abgeschätzt werden konnten.

Bei der Strukturierung des Produktes sollte darauf geachtet werden, dass der Einfluss eines variablen Merkmales auf die Struktur klar bekannt ist und die Struktur gegebenenfalls auch so optimiert ist, dass die vorab geplanten notwendigen Änderungen möglichst einfach zu bewerkstelligen sind. Wurde zum Beispiel beim Scoping festgestellt, dass sich die erfassten Daten über das Umfeld und damit auch die Sensorik des Embedded Systems im Laufe wahrscheinlich häufiger ändern wird (dies ist in Abbildung 2 schematisch dargestellt, siehe PDF), dann sollte dies bei der Strukturierung dahingehend berücksichtigt werden, dass die Produktstruktur für diese Änderung gezielt optimiert wird. Zum Beispiel sollten dann die Sensoranbindung und Datenverarbeitung in Module verlagert werden, die sich einfach austauschen lassen. Eine Strukturierung wo die einzelnen Aspekte der Datenerfassung und –verarbeitung breit auf die Produktstruktur verteilt ist (in Abbildung 2, siehe PDF), würde dann jedes Mal zu erhöhten Änderungskosten führen.

Im Hinblick auf verbesserte Änderbarkeit und damit Wartbarkeit von Quellcode haben sich die SOLID-Prinzipien, die von Robert C. Martin [3] geprägt wurden, als sehr hilfreich erwiesen. Diese Prinzipien lassen sich auch auf die Produktstruktur übertragen. Das Akronym SOLID steht für:

Prinzip

Kernaussage

Single-Responsibility-Prinzip

Module sollten eine klare Verantwortlichkeit haben.

Open-Closed-Prinzip

Module sind offen für Erweiterungen, aber geschlossen für Modifikationen.

Liskovsches Substitutionsprinzip

Falls Module ersetzt werden, dann sollten sich die Spezialmodule wie der Basismodul verhalten.

Interface-Segregation-Prinzip

Ein Modul darf nicht von Funktionen eines anderen Moduls abhängen, die er nicht nutzt.

Dependency-Inversion-Prinzip

Starke Kopplung zwischen Modulen durch entsprechende Schnittstellen vermeiden.

 

Tabelle 1: SOLID-Prinzipien


Gerade das Open-Closed-Prinzip wird in der Praxis oftmals nicht berücksichtigt. Bei der Analyse der Software-Implementierung finden sich dann häufig Module, in denen im Laufe der Zeit neue Varianten eines Merkmales hinzugefügt wurden, z.B. neue Sensor-Treiber oder Filter-Funktionen, die über Präprozessor-Direktiven oder bedingte Ausführung ausgewählt werden. Die Struktur des Moduls ähnelt dann der des Moduls unten links in Abbildung 3 (siehe PDF). Hier werden die verschiedenen Belange der Varianten nicht klar getrennt, sondern in einem Modul vereint. Mit jeder Erweiterung wird das Modul immer größer und schwerer verständlich, und die Qualität des kompletten Moduls muss gesichert werden. Eine Auftrennung in kleinere Teilmodule, die dann über einen externen Mechanismus ausgewählt und eingebunden werden, wie dies unten rechts in Abbildung 3 dargestellt ist, würde die notwendigen Änderungen deutlich erleichtern. Hier kommt ein sogenanntes Module-Replacement in Verbindung mit Indirection als Variabilitätsmechanismus zum Einsatz, und das Open-Closed-Prinzip wird berücksichtigt.

Die Berücksichtigung des Open-Closed-Prinzips ist insbesondere dort empfehlenswert, wo sich Varianten mit offener Vielfalt ergeben, d.h. dass sich im Laufe der Entwicklung dort neue Varianten ergeben. Typische Beispiele hierfür sind erfasste und verarbeitete Daten, Sensoren/Aktoren, Kommunikationskanäle, Bedienschnittstellen, externe Schnittstellen zu Fremdsystemen.

Eine letzte Empfehlung im Rahmen dieses Beitrags bezieht sich auf die Trennung von gemeinsamen und variablen Bestandteilen. Achten Sie darauf, dass diese klar getrennt sind und sich diese Trennung für Mensch und Maschine einfach nachvollziehen lässt. So lassen sich zum Beispiel durch einfache Strukturierungs- und Namenskonventionen verschiedene Modultypen oder Präprozessor-Konstrukte einfach identifizieren und werkzeuggestützt analysieren [4]. Damit lässt sich die Evolution der Produktstruktur deutlich einfacher beherrschen. Auch hier gilt also: Gut strukturiert ist halb gewonnen.

Literatur- und Quellenverzeichnis

[1]   A. da Cunha Reis, L. F. Scavarda, and B. M. 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,  "Lehrbuch der Softwaretechnik: Basiskonzepte und 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).

 

Beitrag als PDF downloaden


Software Engineering Management - unsere Trainings & Coachings

Wollen Sie sich auf den aktuellen Stand der Technik bringen?

Dann informieren Sie sich hier zu Schulungen/ Seminaren/ Trainings/ Workshops und individuellen Coachings von MircoConsult zum Thema Software Engineering Management /Prozess-, Projekt- und Produktmanagement.

Training & Coaching zu den weiteren Themen unseren Portfolios finden Sie hier.


Software Engineering Management - Fachwissen

Wertvolles Fachwissen zum Thema Software Engineering Management /Prozess-, Projekt- und Produktmanagement steht hier für Sie zum kostenfreien Download bereit.

Zu den Fachinformationen


Fachwissen zu weiteren Themen unseren Portfolios finden Sie hier.