2 Bewertungen

Embedded-Software Redesign: Ein Guide Software Redesign: Wann und wie sollte Code überarbeitet werden?

MicroConsult Microelectronics Consulting & Training GmbH

Software sollte reibungslos funktionieren, doch gerade bei lange implementierten Lösungen ergeben sich Defizite. Wann lohnt sich also ein komplettes Re-Design?

Bild: iStock, BOTCookie
07.03.2024

Manchmal ist es nicht mehr damit getan, alten Code zu erweitern: Eine Rundumerneuerung muss her. Dieser Beitrag beschreibt das Vorgehen rund um das Embedded Software Redesign und erläutert dabei die Begriffe Reverse Engineering, Refactoring und Reengineering.

Wann ist es nötig, alten Code komplett zu überarbeiten? Im Wesentlichen gibt es drei Kriterien, durch die sich einschätzen lässt, ob ein Redesign sinnvoll ist. Ihre Qualität sichert zusätzlich die dafür verantwortlichen Rollen im Entwicklungsvorgehen:

Die Prozessqualität beschreibt die Reife der Prozesse rund um die Produktentwicklung und wird vom Prozessverantwortlichen überwacht. Die äußere Produktqualität definiert die Qualität des Produktes, die der Benutzer/Anwender oder die Maschine wahrnimmt. Dafür verantwortlich sind gleich mehrere Rollen, vom Produktmanager bis hin zum Vorstand. Die innere Produktqualität ist nur der Entwicklung selbst bekannt und wird vom Entwicklungsleiter verantwortet.

Defizite bei gewachsener und aktueller Embedded-Software

In den meisten Unternehmen ist Embedded-Software heute über viele Jahre oder sogar Jahrzehnte durch unterschiedliche Entwickler und teilweise über mehrere Entwickler-Generationen gewachsen. Nicht selten haben Entwickler Unternehmen verlassen und das dort nicht konservierte Wissen mitgenommen. Erschwerend kommt hinzu, dass in der Vergangenheit die meisten Embedded-Softwareentwickler ausgebildete Elektrotechniker und keine (technischen) Informatiker waren.

Daraus ergibt sich eine Reihe von Defiziten aktueller und gewachsener Embedded-Software. So fehlen Anforderungen, Architektur, Design und Dokumentation der Software oft gänzlich oder teilweise, ebenso wie Software-(Regressions-)Tests. Auch das Verständnis bei Mitarbeitern über Software-Funktionalitäten ist in vielen Fällen nicht vorhanden. Erschwerend hinzu kommen beliebig viele individuelle Coding-Styles in unterschiedlichen Programmiersprachen im Code. Software-Änderungen führen so zu unerwünschten Nebeneffekten.

Eine der Ursachen für diese Defizite liegt in der Unternehmens- und in der generellen Marktkultur. Ein kurzfristig erfolgreiches unternehmerisches Vorgehen arbeitet schnell und kostenoptimiert, hat jedoch kaum gleichzeitig die Zukunft im Blick. Wird die Projektleitung durch Erfolgsprämien für kurzfristige Ziele wie Einhaltung von Zeit und Kosten belohnt, entspricht das einer „Bestrafung” der Entwicklung durch hohen Projektdruck und macht das Erreichen langfristiger Ziele, wie zum Beispiel die Etablierung von Qualität, so gut wie unmöglich.

Die Gründe dafür liegen meist im mangelnden Software-Verständnis des Managements. Insbesondere trifft das auf Unternehmen zu, die mechatronische Systeme entwickeln, da dort das Management meist aus dem Konstruktionsbereich stammt. Nicht selten fehlt in diesen Unternehmen auch ein generelles Fachwissen in der Softwareentwicklung. Entwicklungsvorgehen, Tools, Anforderungen, Architektur, Design, Codierung und Tests sind den Verantwortlichen fremd.

Mit wachsender Software-Komplexität sowie einer steigenden Anzahl der Embedded-Softwareentwickler (zum Beispiel durch Unternehmenszusammenschlüsse) fallen diese Defizite nochmal ins Gewicht. Wird die Softwareentwicklung unternehmensintern verteilt oder durch Outsourcing ausgelagert, lassen sich die Qualitätsebenen kaum noch so sichern, wie es die Software verlangt, um dem Unternehmen langfristig Vorteile zu bringen.

Auslöser für Embedded-Software-Änderungen

Es gibt eine Reihe von Anlässen, die dazu führen, dass Embedded-Software überarbeitet und verändert werden muss. Neben der klassischen Fehlerbehebung und der Einarbeitung neuer Features, neuer notwendiger Softwarekomponenten oder Änderungen bei bereits eingebundenen Softwarekomponenten können auch technologische Marktanpassungen wichtige Impulse für die Weiterentwicklung geben; Stichwort „Internetanbindung”, „Künstliche Intelligenz” und „Industrie 4.0”.

Stellt sich im Laufe der Zeit heraus, dass die Hardware-Rechenleistung unzureichend ist, kommt eine Softwareverteilung beziehungsweise eine Migration nach Multithreaded, Multicore oder Manycore in Frage. Kosteneinsparungen oder Abkündigungen können ebenfalls zu Änderungen von Hardwarekomponenten führen; neue Regularien erfordern eine Notwendigkeit der Produktzertifizierung.

Nichts bleibt so wie es mal war. Mitarbeiter wechseln und bringen neue Softwareparadigmen (zum Beispiel objektorientiert statt prozedural) oder eine neue Programmiersprache (zum Beispiel C++ statt C) mit ins Team. Auch kann die Entwicklung oder Teile davon plötzlich an externe Zulieferer und Funktionalitäten in Zukaufprodukte ausgelagert werden.

Um langfristig die äußere Produktqualität zu erhalten, braucht es einerseits die Verbesserung der inneren Softwarequalität, um die Software tragfähig für die Zukunft auszulegen, sowie andererseits die Verbesserung der Prozessqualität, um idealerweise schneller, kostengünstiger und qualitätssteigernder zu arbeiten.

Die oben aufgeführten Impulse für eine Änderung der Embedded-Software sind gleichzeitig Trigger für ein Embedded-Software-Redesign. Software-Redesign ist der Überbegriff für Redesign, Refactoring und Redesign und meint den Ansatz der Veränderung von Software und deren Entwicklungsvorgehen.

Daran erkennen Sie die Notwendigkeit eines Redesigns

Kundenunzufriedenheit sollte heute in jedem Unternehmen ein wichtiger Antrieb für Innovation sein. Bemerkt schon der Kunde Defizite bei der inneren Softwarequalität beziehungsweise Prozessqualität, dann ist es kurz nach zwölf!

„Never change a running system“? Sind Änderungen und Erweiterungen der aktuellen Software ohne Seiteneffekte sehr zeitintensiv oder nicht mehr möglich, ist dies ebenfalls ein klares Signal für ein Embedded-Software-Redesign. Das kann sich auch bei der Wiederverwendung in neuen Projekten zeigen, die sich als zu aufwendig oder als nicht mehr möglich herausstellt.

Ist die Software-Komplexität nicht mehr beherrschbar oder steigen die Fehler-Behebungszeiten, lohnt sich erst recht ein genauer Blick auf die innere Softwarequalität. Meist kommen einem jedoch unzufriedene Entwickler zuvor, denen die Produkt- und Prozessqualität der Embedded-Software immer wieder Schwierigkeiten bereitet. Augenscheinlich wird dies bei der Einarbeitung neuer Mitarbeiter, wenn diese die Software-Funktionalitäten schwer oder gar nicht verstehen. So kann ein unstetiger Mitarbeiterstamm bereits viel über die Softwarequalität aussagen.

Das Vorhaben eines Embedded-Software-Redesigns ist ein eigenes Projekt mit Zielen, Zeiten, Kosten und Qualitäten, das als Ganzes die volle Aufmerksamkeit des Entwicklerteams benötigt und nicht neben dem Tagesgeschäft erledigt werden sollte. Für ein erfolgreiches Software-Redesign schafft man am besten im Vorfeld die richtigen Voraussetzungen.

Idealerweise existieren zur aktuellen Embedded-Software die Anforderungen mit den dazugehörigen Abnahmekriterien und die Dokumentation zu Architektur, Design und Programmcode. Auch besteht im Idealfall eine durchgängige Konsistenz von Anforderungen über Programmcode bis hin zu den Tests. Alle Softwaretests sollten sich automatisch und nachvollziehbar mit dem Ergebnis „PASS” ausführen lassen.

Liegen diese zur Embedded-Software passenden Artefakte nicht vor, ist es ratsam, diese mittels eines Software Reverse Engineerings zu erstellen. Das meint meist eine ausführliche Dokumentation basierend auf Programmcode-Anforderungen, Abnahmekriterien, Architektur, Design, Programmcode und Test.

Im Vorfeld ist es wichtig, die Notation der Software-Dokumentation zu entscheiden. Hierzu eignet sich UML (Unified Modeling Language) hervorragend, die sowohl für C als auch für C++ Code mit prozeduralem oder objektorientiertem Programmieransatz anwendbar ist. Basierend auf dem Programmcode entsteht die Dokumentation in Form eines Softwaremodells. Praxisbewährte UML-Tools, wie beispielsweise der Enterprise Architect der Firma Sparx Systems, erlauben es uns, Software zu modellieren und auch ein Reverse Engineering durchzuführen.

Beim Reverse Engineering liest das Tool bestehende Programmcode-Verzeichnisse ein und erstellt darauf basierend erste Strukturmodelle. Daraus erkennt man den Modul- beziehungsweise Klassenaufbau und die Include-Pfade. Manchmal ist das Spinnennetz der Include-Pfade dominierend, sodass Module/Klassen nur noch schwer erkennbar sind. Je dichter das Spinnennetz ist, umso höher das Optimierungspotential in Architektur und Design. Hier sollte man manuell „entflechten“. Ablaufdiagramme (zum Beispiel Zustandsfolge- oder Aktivitätsdiagrammen) müssen jedoch weiterhin manuell erstellt werden.

Wichtig: In vielen Fällen lässt sich erst während oder nach der Erstellung der Software-Dokumentation bewerten und entscheiden, ob die Software tatsächlich noch sinnvoll redesigned werden kann oder es nicht erfolgversprechender ist, die Software neu zu entwickeln.

Software-Anforderungen und deren Abnahmekriterien

Veranstaltungsformen wie Workshops eignen sich ideal, um mit den passenden Wissensträgern die Anforderungen zu erfassen und zu dokumentieren. Um Anforderungen aus dem Programmcode abzuleiten, existieren keine Tools am Markt. Hier ist manuelle Arbeit gefragt. Erfahrungsgemäß ist es nicht möglich, 100 Prozent aller in der Software implementierten Anforderungen zu erfassen.

Zu den erfassten Anforderungen werden nun die zugehörigen Abnahmekriterien entwickelt und dokumentiert. Neben manchen UML-Tools eignen sich ALM- (Application Lifecycle Management) beziehungsweise PLM- (Product Lifecycle Management) Tools wie zum Beispiel DOORS von IBM zur Dokumentation der Anforderungen und Abnahmekriterien.

Idealerweise lässt sich auf Basis der Abnahmekriterien ein automatisierter und nachvollziehbarer Softwaretest durchführen, um das nach außen beobachtbare Verhalten der Software zu überprüfen. Während des Software-Redesigns darf sich dieses Verhalten genauso wenig ändern wie die Anforderungen und Abnahmekriterien. Als Kompromiss beschränkt sich das Reverse Engineering in der Praxis häufig „nur“ auf die Erstellung der Software-Dokumentation.

Sind die Voraussetzungen für ein erfolgreiches Embedded Software Redesign geschaffen, können Sie mit dem Software Refactoring beginnen. Software Refactoring verbessert die interne Softwarestruktur und Codierung der fertigen Software, ohne dabei das von außen beobachtbare Verhalten zu verändern.

Man unterscheidet zwischen „kleinem” und „großem” Refactoring. Ein kleines Refactoring bezeichnet Änderungen in der Sourcecode-/ Designebene, das große ist für Änderungen in der Architekturebene zuständig. Die Konsequenz eines großen Refactorings sind automatisch mehrere kleine Refactorings

Wie bereits erwähnt, darf sich die Embedded-Software nach einem Refactoring nach außen hin nicht anders als zuvor verhalten. Dies sollte durch erneutes Ausführen der unveränderten Softwaretests nach jedem Refactoring überprüft werden. Ergänzen Sie bitte erst nach einem erfolgreichem Refactoring neue Features. Das Vorgehen im Embedded Software Refactoring kann wie folgt aussehen.

Unter Berücksichtigung der Zieldefinition identifizieren Sie Refactoring-Potenziale, sogenannte „Smells“, in der Embedded-Software.

In vorgefertigten Refactoring-Katalogen finden Sie einzelne Refactorings in Kategorien unterteilt. Dort wählen Sie das für Ihr Problem passende Refactoring aus und implementieren es. Gerade in der Embedded-Software ist der Refactoring-Bedarf häufig sehr speziell, sodass Sie Ihre eigenen Refactorings und Kategorien selbst entwickeln müssen.

Moderne Programmcode-Editor, z.B Eclipse, oder dazu passende Plug-Ins unterstützen bei der Refactoring-Implementierung. Dazu müssen Sie den zu refaktorierenden Programmcode selektieren; eine Menüauswahl bietet Ihnen dazu passende Refactorings an und setzt diese direkt bei der Auswahl um.

Große Refactorings setzen wir manuell in kleinen und geplanten Schritten um. Nehmen Sie Änderungen in der Software-Codeebene vor, müssen Sie meist auch die Unit-Tests adaptieren.

Wichtig: In vielen Fällen lässt sich erst während des Refactorings der Software bewerten und entscheiden, ob sie tatsächlich noch sinnvoll refaktoriert werden kann oder es nicht erfolgversprechender ist, die Software neu zu entwickeln.

Zusammenfassend unterteilt sich das Software-Redesign in ein optionales Reverse-Engineering, falls eines der dafür benötigten Artefakte fehlt. Anschließend führen Sie so lange Refactorings durch, bis Sie Ihr Ziel erreicht haben.

Als weiterführende Quelle zum Thema Refactoring möchte ich Martin Fowler nennen. Neben seinem Buch “Refactoring” ist auch sein Refactoring Online Portal empfehlenswert.

Sind alle Refactorings umgesetzt und die Embedded-Software verhält sich wie zuvor (Nachweis über Softwaretests), dann müssen Sie spätestens jetzt die Software-Dokumentation anpassen. Nur so bleibt die Konsistenz der Embedded-Software-Artefakte erhalten.

Profi-Tipp: Übertragen Sie die durchgeführten Refactorings in Richtlinien, damit sich die gleichen Fehler nicht nochmals einschleichen. Abhängig vom Refactoring ergänzen Sie damit zusätzlich Ihre Architektur-, Design-, Modellier- oder / und Codier-Richtlinien.

Manchmal reicht ein Software Redesing im Sinne von Reverse Engineering und Refactoring nicht aus. Ein noch nicht ausgereiftes Entwicklungsvorgehen verursacht teilweise auch die Defizite der inneren Softwarequalität. In diesem Fall müssen Sie das Entwicklungsvorgehen optimieren, was wir als Embedded Software Reengineering bezeichnen. Ein generischer Ansatz, dies zu tun, kann wie folgt dargestellt aussehen.

Die Optimierungsziele ergeben sich aus den aktuellen Herausforderungen, die im Entwicklungsvorgehen nicht gelöst sind. Unternehmensabhängig ist das Entwicklungsvorgehen nicht dokumentiert. Oder es ist dokumentiert, wird aber durch die Mitarbeiter nicht oder unterschiedlich gelebt. Insbesondere in diesen Fällen sollten wir uns das tatsächliche Entwicklungsvorgehen bewusst machen.

Danach hat jeder Beteiligte die gleiche Sicht auf das Entwicklungsvorgehen, und die zielbezogene Analyse ist durchführbar. Hierbei gilt es, die Ursachen für die Defizite zu finden. Um die Ursachen zu eliminieren, optimieren wir zielbezogen das Entwicklungsvorgehen.

Checkliste: Wie lässt sich ein nötiges Redesign vermeiden?

  • Hohe Qualifikation der Mitarbeiter

  • Bewusstsein der Wichtigkeit von Anforderungen, Architektur und Design im Team wecken

  • Embedded-Software mit der UML (Unified Modelling Language) modellieren und gleichzeitig dokumentieren

  • Eigene Architektur-, Design-, Modellier- und Codier-Richtlinien erstellen

  • Auf allen Ebenen (Management, Projektleitung und Entwicklung) zukunftsorientiert denken und handeln

  • Entwicklungsteams bestehend aus Elektrotechnikern und (Technischen-) Informatikern bilden

  • Entwicklungsvorgehen kontinuierlich anpassen und optimieren

  • Der Clean Code Developer Initiative folgen

  • Software-Erosion dauerhaft automatisiert durch Tooleinsatz vermeiden, zum Beispiel Bauhaus Suite von Axivion

Verwandte Artikel