Category

Inhaltliches

Wie sehen iSAQB CPSA-Advanced Prüfungsaufgaben eigentlich aus?

By | Allgemein, Inhaltliches | One Comment

diploma-3Der iSAQB-Einstiegslevel Foundation der Certified Professional for Software Architecture-Zertifierung (kurz: CPSA-F) sieht einen Multiple Choice Test als Prüfung vor. Bei der zweiten Stufe, dem Advanced Level (kurz: CPSA-A), bearbeitet der Prüfling hingegen eine Hausarbeit. Seine Lösung verteidigt er (bzw. sie) dann im Rahmen eines Interviews vor zwei Prüfern, die diese vorher durchgesehen und gegen Kriterien gehalten haben.

Bei einem Multiple Choice Test (also bei CPSA-F) ist relativ klar, was auf den Prüfling zukommt. Auch wenn einzelne Lernziele mit Ankreuzfragen nur schwer überprüfbar sind, und man sich konkrete Fragen dazu vielleicht nicht direkt vorstellen kann, gilt das zumindest für die Form der Prüfung. Zum Advanced-Level höre ich in Workshops oder per Mail dagegen immer wieder die Frage: Wie sieht eine solche Prüfungsaufgabe inhaltlich aus? Das ist nicht unmittelbar offensichtlich.

Nun sind die Prüfungsaufgaben selbst natürlich vertraulich (genau wie die Prüfungsfragen im Foundation Level). Vorlagen und Checklisten zur Erstellung von Aufgaben sind jedoch frei zugänglich (auf der Webseite des iSAQB). Sie sind nicht unbedingt leicht verdaulich — falsche Zielgruppe: sie sind für Leute gedacht, die sich neue Aufgaben ausdenken. Ich beschreibe daher im Folgenden mal, wie Aufgaben aufgebaut sind – für Leute, die demnächst ein solche Aufgabe lösen müssen. Was Sie als Advanced-Prüfling also grob erwartet…

Wie sieht eine Aufgabe grundsätzlich aus?
Das Fallbeispiel
Ihre Aufgabe
Ein Beispiel
Häufige Fragen zu Prüfungsaufgaben
Weitere Informationen
Überblick Prüfungsaufgabe

Wie sieht eine Aufgabe grundsätzlich aus?

Die Aufgabenstellung einer Prüfungsaufgabe für CPSA-Advanced umfasst mindestens 10 Seiten und höchstens 25 (siehe Abbildung rechte, die Seitenzahlen sind Beispielwerte).

Jede Aufgabe ist einer Systemart zugeordnet. Aktuell sind das

  • Informationssystem
  • Embedded System
  • Websystem

Ein Kandidat gibt bei der Anmeldung zur Prüfung die gewünschte Systemart an und erhält dann eine Aufgabe aus diesem Bereich. Damit soll verhindert werden, dass ein Prüfling mit einem Umfeld konfrontiert wird, das ihm völlig fremd ist. Auf Wunsch erhält der Prüfling kurze Abstracts (2-3 Sätze) von zwei verschiedenen Aufgabenstellungen und entscheidet sich dann für eine davon.

Jede Aufgabe selbst zerfällt dann in zwei grobe Blöcke: Ein Fallbeispiel in Form inhaltlicher Inputs, und die Aufgabenstellung selbst. Letztere ist in Teilaufgaben gegliedert. Die konkreten Prüfungsaufgaben variieren dabei in der Zusammenstellung der inhaltlichen Inputs und den Teilaufgaben erheblich.

Das Fallbeispiel

Prüfungsaufgaben: FallbeispielBeim Fallbeispiel handelt es sich um ein fiktives Projekt, eine Produktentwicklung, eine Migration oder ähnliches. Nach einem kurzen Überblick liegen konkrete Informationen dazu in Form inhaltlicher Inputs vor. Im Wesentlichen sind das Anforderungen, die der Prüfling in den späteren Teilaufgaben berücksichtigen muss. Denkbar sind etwa folgende Inhalte:

  • Funktionale Anforderungen (z.B. wichtige Use Cases, User Stories, …)
  • Qualitätsziele, ggf. verfeinert in Szenerien
  • Stakeholder (z.B. Liste, Personas)
  • Interviews mit Stakeholdern
  • Technische und/oder organisatorische Rahmenbedingungen
  • Fachlicher Kontext, Benutzer und Fremdsysteme
  • Normen und Konventionen
  • Risiken

Nicht jede Aufgabenstellung enthält dabei alle diese Inhalte. Weiterhin kann es sein, dass bestimmte Anforderungen explizit genannt sind, andere jedoch im Rahmen der Aufgabe erarbeitet werden müssen. Beispielsweise liegen mitunter Interviews mit Stakeholdern vor und die Rahmenbedingungen oder Qualitätsziele muss der Prüfling dann im Rahmen einer Teilaufgabe herausarbeiten und ggf. priorisieren.

Ihre Aufgabe

Prüfungsaufgaben: TeilaufgabenGanz ähnlich wie das Fallbeispiel mit seinen inhaltlichen Inputs, ist auch die Aufgabe unterteilt — in mindestens 5 und maximal 10 Teilaufgaben, die unterschiedliche Aspekte der Architekturarbeit abdecken. In Summe soll die Bearbeitung zeigen, dass der Prüfling in der Lage ist, aus Anforderungen methodisch eine Architektur zu entwerfen und festzuhalten, sie zu reflektieren und zu kommunizieren. Analog zu den denkbaren Inputs oben beim Fallbeispiel hier mögliche Teilaufgaben:

  • Kontext abgrenzen
  • Qualitätsziele identifizieren, Qualitätsbaum und -szenarien erarbeiten
  • Offene Fragen an Stakeholder formulieren
  • Lösungsstrategie/Architekturvision anfertigen
  • Architekturentscheidungen treffen
  • Technische Fragestellung inkl. Alternativen und Begründung bearbeiten
  • System strukturieren, fachlich zerlegen, Verantwortlichkeiten festlegen
  • Schnittstellen entwerfen
  • Technische und/oder übergreifende Aspekte bearbeiten
  • Lösung qualitativ bewerten
  • Risiken identifizieren und adressieren

Es gibt dabei Überschneidungen in inhaltlichen Inputs und Teilaufgaben: Der Systemkontext könnte etwa mit dem Fallbeispiel gegeben sein (als inhaltlicher Input) oder muss alternativ als Teilaufgabe erarbeitet werden.

Ein Beispiel

Das iSAQB stellt eine Beispielaufgabe bereit: „BigSpender“. Es handelt sich um eine echte Aufgabe, die früher gestellt, mittlerweile aber aus dem Pool genommen wurde, nachdem sie einige Prüflinge bearbeiten durften. Sie können die Prüfungsaufgabe hier als PDF herunterladen.

Inhaltlich geht es in der Aufgabe um Spesenabrechnungen. Das Fallbeispiel enthält dabei folgende Inhalte:

  • Input 1 – Überblick (1 Seite, Text)
  • Input 2 – Fachlicher Kontext (Diagramm und kurze Beschreibung der Akteure)
  • Input 3 – Fachklassenmodell (Diagramm) und Glossar (als Tabelle)
  • Input 4 – Stakeholder (knapp gehaltene Liste)
  • Input 5 – Interview mit dem Auftraggeber (recht umfangreich, ca. 3 Seiten)
  • Input 6 – Exemplarische User Stories (10 Stück)
  • Input 7 – Verfügbarkeit des Systems (Anforderung, als Szenario)
  • Input 8 – Technische Randbedingungen (als kurzer Text)
  • Input 9 – Mengengerüst (Tabelle, Aussagen zu Benutzern, Standorten, Vorgängen …)

Die eigentliche Aufgabe besteht dann aus 6 Teilen.

  • Teilaufgabe 1 – Qualitätsanforderungen herausarbeiten, in Form von Qualitätszielen und -szenarien
  • Teilaufgabe 2 – Lösungsstrategie entwickeln, Umfang ca. eine Seite
  • Teilaufgabe 3 – Technischen Kontext abgrenzen, Diagramm und Beschreibung zu Akteueren und Kommunikation
  • Teilaufgabe 4 – Fachliche Strukturierung erarbeiten (Bausteinsicht)
  • Teilaufgabe 5 – Technologie-Entscheidungen treffen
  • Teilaufgabe 6 – Bewertung der Lösung vornehmen, anhand der Qualitätsszenarien aus Teilaufgabe 1

Details entnehmen Sie dem PDF. Und beachten Sie, dass sich die Prüfungsaufgaben wie geschildert stark unterscheiden und es sich bei „BigSpender“ um ein Beispiel handelt – wenn auch um ein echtes.

Prüfungsaufgaben: FAQ

Häufige Fragen zu Prüfungsaufgaben

Wie wird sichergestellt, dass die Aufgabe zu den von mir besuchten Schulungen passt?

Eigentlich gar nicht. Durch die Angabe der Systemart (z.B. Web, Embedded) wird lediglich abgesichert, dass es technologisch grob passt. Ansonsten sind die Aufgaben nicht an bestimmte Module gebunden. Die Teilaufgaben (+ Interview) decken lediglich die drei Kompetenzbereiche („Säulen“) des Advanced-Levels ab (methodisch, technisch und kommunikativ).

Welchen Umfang hat meine Lösung?

Sie halten Ihre Lösung auf maximal 40 DIN A4-Seiten (inklusive Abbildungen) fest. Dazu haben Sie maximal 3 Monate Zeit (Details siehe Prüfungsordnung). Vom Aufwand sind die Teilaufgaben so bemessen, dass ein Prüfling sie in 40 Stunden erledigen kann.

Was wenn Technologien oder Methoden gefordert sind, die ich nicht beherrsche?

Die Aufgabenstellungen lassen Ihnen angemessenen Spielraum bezüglich Technologien, Werkzeugen, Notation und Ähnlichem. Wenn etwas explizit gefordert ist, so ist sichergestellt, dass Informationen dazu frei zugänglich sind. Entweder es liegt der Aufgabe bereits in den inhaltlichen Inputs oder in einem Anhang bei, oder es wird darauf verwiesen. Es kann natürlich vorkommen, dass Sie sich zur Lösung der Aufgabe noch Wissen aneignen müssen.

Was wenn mir die gegebenen Anforderungen zur Lösung nicht ausreichen?

Wie im richtigen Leben kann es sein, dass Ihnen zur Lösung der Aufgabe Informationen fehlen. Im Einzelfall scheinen sich Anforderungen sogar zu widersprechen (beispielsweise Aussagen in Interviews von Stakeholdern mit unterschiedlichen Prioritäten). Normalerweise klären Sie das im Projekt mit den Beteiligten, finden Kompromisse, etc.. Da Ihnen die Leute im Rahmen Ihrer Hausaufgabe nicht zur Verfügung stehen, treffen Sie Annahmen. Diese kennzeichnen Sie in Ihrer Lösung explizit als solche. Achten Sie darauf, dass diese sinnvoll und konsistent untereinander und zur Aufgabenstellung sind.

Soll ich meine Lösung nach arc42 strukturieren?

Die Antwort ist hier ein klares nein. arc42 ist ein verbreiteter Gliederungsvorschlag für Architekturbeschreibungen, daher wäre die Idee naheliegend. Für Ihre Lösung ist aber ganz klar die Vorgabe, dass Sie diese den Teilaufgaben entsprechend strukturieren. Also pro Teilaufgabe ein Abschnitt. Sie ermöglichen den Prüfern auf diese Weise die einfache Durchsicht and den Abgleich mit Kriterien.

Weitere Informationen

Ich hoffe, ich konnte einen Eindruck vermitteln, wie die Prüfungsaufgaben im CPSA-Advanced-Level grundsätzlich aussehen. Wenn Sie Fragen zu dem Thema haben, kommen Sie gerne auf mich zu. Ansonsten: Auf der iSAQB-Seite finden Sie vieles rund um den Advanced-Level. Hier noch ein paar weiterführende Links …

Eine erste Fassung dieses Beitrags erschien im Juni 2016. Sie wurde regelmäßig aktualisiert, zuletzt im April 2020.

Seminare bei embarc

Ein Steckbrief für das Erarbeiten von Fitness-Functions

By | Inhaltliches | No Comments

Evolutionäre Architektur ist als Trend schon lange im Gespräch. Konkret finden wir sie zum Beispiel auf dem Technology Radar bei Thoughtworks bereits 2010. Im entsprechenden O’Reilly-Buch von 2017 findet sich diese Definition:

„Eine evolutionäre Architektur unterstützt geleitete, inkrementelle Veränderungen über mehrere Dimensionen hinweg“. (N. Ford, R. Parsons, P. Kua, Patrick: Building Evolutionary Architectures)

Evolutionäre Architektur denkt einige Dinge anders als „klassische“ Softwarearchitektur. So werden dort Architekturentscheidungen nicht als schwer änderbar hingenommen. Stattdessen sind Änderungen in der Architektur aufgrund von Überraschungen willkommen und normal.

Ein Konzept, das eng mit Evolutionärer Architektur verknüpft ist, sind Fitness-Functions. Eine Fitness-Function misst objektiv, wie gut eine Lösung die an sie gesetzten Ziele erreicht. Fitness-Functions unterstützen genau die geleiteten Veränderungen, von denen in der Definition von Evolutionären Architektur die Rede ist. Sind wir mit unserer Lösung (noch) auf dem richtigen Weg? Halten neue Ideen, was sie versprechen? Wie bewerten wir Experimente, zum Beispiel mit neuen Technologien?

SteckbriefIm Rahmen unserer Coaching-Einsätze haben wir einen kleinen Steckbrief (oder „Canvas“) entwickelt, der uns und unsere Kunden bei der Entwicklung von Fitness-Functions unterstützt.

Teilnehmer des Workshops „Die Wirksamkeit Eurer Architektur automatisiert testen“ von Sandra Parsick und mir beim Software Architecture Summit in München dieses Jahr konnten diesen Steckbrief im Rahmen der Übungen für ihre eignen Projekte ausprobieren. Ich möchte dem Wunsch folgen, ihn hier zum Download bereit zu stellen … (Druckvorlage für 3 Steckbriefe inkl. Leitfragen zur Umsetzung).

Wie arbeitet Ihr mit dem Steckbrief? Tatsächlich steht das Erarbeiten und Umsetzen der Fitness Funktion nicht am Anfang. Im Workshop haben wir unser Vorgehen in 6 Schritten skizziert (Details in den Folien, insbesondere auch zu den Kategorien) – zu Beginn stehen die Architekturziele, verfeinert durch Beispielszenarien.

  1. Identifikation der Architekturziele
  2. Ausarbeitung von Beispielszenarien
  3. Auswahl für die Überprüfung
  4. Formulierung der Test-Idee
  5. Umsetzung und Automatisierung der Auswertung
  6. Sichtbarmachen der Resultate

Die Steckbriefe sammeln die Ergebnisse aus den Schritten 1, 2 und 4 im Vorgehen zusammen, und geben Input für 5 und 6. Pro Szenario gibt es dann eine Fitness-Funktion und dafür jeweils einen eigenen Steckbrief. Ausgefüllt sieht das Ganze z.B. so aus:

Fitness-Function Steckbrief, ausgefülltLassen wir uns ein kleines Beispiel durchspielen! Nehmen wir an, Eurer Team entwickelt eine Software, die lange leben soll. Ihr setzt dabei verschiedene Fremdbibliotheken ein. Oft werden diese Abhängigkeiten in Build-Skripten mit einer Version eingepflegt, diese dann aber nie aktualisiert. Was, wenn Ihr auf eine neue Version umsteigen müsst (z.B. weil dort ein Security-Problem gefixt wurde, das für Euch relevant ist …

Wir formulieren daher als Architekturziel zur Kompatibilität:

„Unsere Software läuft mit den aktuellen Versionen der eingesetzten Fremdbibliotheken.“

Das ganze verfeinern wir durch ein Beispielszenario (Über Qualitätsszenarien könnt Ihr z.B. in unserem arc42-Starschnitt nachlesen):

„Ein Open Source Projekt veröffentlicht eine neue Version einer von uns verwendeten Fremdbibliothek. Unsere Software lässt sich ohne Änderungen mit der neuen Version bauen und funktioniert damit einwandfrei.“

Zu diesem Szenario lässt sich eine Fitness Function formulieren, die absichert, dass bei Austausch einer verwendeten Fremdbibliothek x in Version n durch eine neuere Version n+1 die Software weiterhin baut und alle Tests besteht.

Umsetzen und automatisiert Auswerten lässt sich eine entsprechende Test-Idee durch

  1. Online-Überprüfung, ob zu einer Bibliothek eine neue Version verfügbar ist (Scannen der Repos),
  2. gezieltes Update der Bibliothek im Build-File in einem separaten Branch und
  3. Bauen des Branches und Durchlaufen der vorhandenen Tests.

Wenn Bauen und/oder Testen fehlschlagen weiß das Team frühzeitig, dass seine Software mit der neueren Version der Bibliothek nicht ohne Anpassungen funktioniert.

Dependabot bietet die beschriebene Funktion “von Hause aus” an. Wenn Schritt 1 eine neue Version für eine verwendete Abhängigkeit liefert (was Dependabot anhand des Build-Skripts prüft) legt das Werkzeug in GitHub einen eigenen Branch dafür an, modifiziert das Build-Skript, baut und meldet das Ergebnis. Im Erfolgsfall erzeugt es passende Pull-Requests zum Mergen:

Dependabot BeispielDas Team entscheidet, wie es mit dieser Erkenntnis umgeht. Mitunter kann es veraltete Funktionalität (Stichwort “deprecated”) der Fremdbibliothek durch neuere ersetzen, und den Test bestehen, ohne tatsächlich schon ein Update durchzuführen. Oder es stellt das Update als Aktivität unter “technische Schulden beheben” ein.

Bei kontinuierlichem Aktualisieren (oder dem Experimentieren damit) schlummern bei größeren Umbauten (z.B. neue Java-Version) keine unbekannten Risiken, die automatisierte Überprüfung mit Werkzeugen wie Dependabot nimmt dem Team hier Arbeit ab, die sich im Projektgeschäft manuell keiner macht.

Der Steckbrief hilft durch eine Kategorisierung im rechten oberen Bereich, Eure Test-Idee zu schärfen, und zur Umsetzung zu bringen. Die Kategorien sind in den Folien zum Workshop erklärt. Darüber hinaus haben wir ein paar „Leitfragen“ definiert, die Euch bei der Implementierung der Fitness-Funktion helfen. Sie sind auch in der Druckvorlage enthalten.

  • Wann, wie und wo führen wir die Testfunktion aus?
  • Wie kommen wir an die benötigten Daten?
  • Wie werten wir die Daten aus?
  • Was passiert, wenn die Ergebniskontrolle einen Fehler anzeigt?
  • Was passiert, wenn der Test selbst fehlschlägt?
  • Wie kommunizieren wir das Ergebnis ? Wie oft? Und an wen?

Die folgende Abbildung gibt einen Überblick über den Steckbrief und stellt die Bereiche in den Bezug zu den Schritten des Vorgehens oben.

Ausfüllen erklärt

Interview – Kim Nena Duggen über Organisationsentwicklung und Mitarbeiterführung

By | Inhaltliches, Publikationen | No Comments

Interview – Kim Nena Duggen über Organisationsentwicklung und Mitarbeiterführung

Kim Nena Duggen im Gespräch mit New Work Heroes in Berlin
Kim Nena Duggen und Jörn Hendrik Ast
Podcast über Selbstorganisation, Mitarbeiterführung, Erfahrungswerte und mehr..
veröffentlicht am 15. Januar 2020
New Work Heroes (podcasts)

Wie kann die Idee gelingen, eine Organisation dahin zu verändern, dass Mitarbeiter freier agieren?

Kim spricht in dem Interview darüber, was Selbstorganisation und New Work für sie bedeuten und welche Erfahrungen sie in ihren Jobstationen gemacht hat. Sie gibt spannende Einblicke und Tipps, wie Du Teams motivierst, neue Organisationsformen zu lernen und aufzubauen.

Wo lauern Hürden und wie kannst Du damit umgehen? Wie kann jeder Einzelne die Organisationsentwicklung und den Change aktiv gestalten? Warum kann es beispielsweise förderlich sein, als Führungskraft die eigene Unsicherheit zu zeigen? Wo ist der Unterschied zwischen Konsens und Konsent in der Führung? Was sind Sprechdenker und warum ist Teamwork für sie essentiell?

 

 

Zum Interview

Interview zum Modul Soft Skills auf dem Architecture Gathering 2019

By | Inhaltliches, Video | No Comments
Interview mit Kim Nena Duggen – Software Architecture Gathering Oktober 2019

Mirko Hillert im Gespräch mit Kim Nena Duggen
online auf YouTube
veröffentlicht am 29. November 2019

Seminar SOFT – Konfliktlösung:
Als Softwarearchitekt konstruktiv mit Konflikten umgehen

embarc Session auf dem Architecture Gathering in München:
Einführung in Machine Learning (Oliver Zeigermann)

Kim Nena Duggen betreut als Kuratorin inhaltlich das Advanced Level-Modul SOFT im iSAQB e.V.. Im Rahmen des TAG 2019 (The Architecture Gathering) hat sie mit Mirko Hillert vom iSAQB gesprochen. In dem Interview zeigte Kim auf, wie Soft Skills Softwarearchitekten in ihrer Arbeit unterstützen können und welche Schwerpunkte das Advanced Modul setzt: Wie gehen Softwarearchitekten mit den unterschiedlichen Erwartungshaltungen in ihrem Projektalltag um? Wo liegen Fallstricke in der Kommunikation? Wie können Sie Konflikte konstruktiv lösen?

 

Artikel iX Developer von Oliver Zeigermann – TensorFlow 2 und Machine Learning

By | Artikel, Inhaltliches | No Comments
„TensorFlow 2 & Machine Learning im Browser“

Artikel: TensorFlow 2 und Machine Learning im Browser
Autor: Oliver Zeigermann
iX Developer, ab S. 140,  erschienen am 5. Dezember 2019
iX Developer online bestellen

Für unseren Artikel im aktuellen iX Developer Sonderheft haben wir uns ein etwas exotisches Thema ausgesucht: Machine Learning mit TensorFlow.js im Browser. Warum das Sinn machen kann und wie Machine Learning im Browser funktioniert beschreibt unser Artikel auf Seite 140.

Mehr über die Grundidee und die Anwendungen von Machine Learning gibt es in dem Vortrag von Oliver Zeigermann auf der OOP in Februar 2020 in München: „Was macht Machine Learning anders?“

 

 

Zum iX Developer Heft

 

 

 

 

 

 

 

 

follow us on Twitter – @embarced

W-JAX 2019: Oliver Zeigermann – Neuronale Netzwerke mit TensorFlow 2 (Videoaufzeichnung)

By | Inhaltliches, Video | No Comments

WJAX_Logo

Neuronale Netzwerke mit TensorFlow 2: von unten nach oben
Sprecher: Oliver Zeigermann
Vortrag auf der W-JAX 2019
Donnerstag, 07. November 2019, 11.45-12.45 Uhr
The Westin Grand in München
@jaxcon
Vortragsaufzeichnung auf Youtube

TensorFlow ist Googles Framework für Neuronale Netzwerke und auch über die Grenzen von Google hinaus ein Standard. In Version 2 hat sich vor allem das Low-Level-API stark verbessert. Damit werden wir beginnen, um Neuronale Netze von Null auf zu verstehen, ohne eine Zeile Mathematik zu benötigen. Danach sehen wir uns dasselbe mit der High-Level-Keras-API an, die das gleiche tut, aber von den (von uns) vorher gemachten Schritten abstrahiert.

Als Teilnehmer oder Zuschauer des Vortrages lernst Du:

  • dass Matrixmultiplikationen die Basis für Neuronale Netzwerke sind
  • was Loss Functions sind
  • wie man von einer Loss Function zu einem trainierten Neuronalen Netzwerk kommt

CONSTRUCT: Aufbauen (5C Design, Teil 6)

By | Allgemein, Inhaltliches | No Comments

Eine Bausteinstruktur kann auf einer Ebene selbst wieder unübersichtlich werden. Baue Systeme höherer Komplexität durch Zusammenfassen von Bausteinen einer Ebene zu einem neuen Baustein einer nächsthöheren Ebene. Dabei sind weiterhin dieselben Handlungsmaximen anzuwenden.

  1. Software-Entwurf: Ein Blick zurück und nach vorn
  2. CUT: Richtig schneiden
  3. CONCEAL: Verbergen
  4. CONTRACT: Schnittstelle festlegen
  5. CONNECT: Verbinden
  6. CONSTRUCT: Aufbauen
  7. Its a Wrap: Zusammenfassung

In den bisherigen Artikeln ging es darum, wie man ein System auf einer Ebene effizient in einzelne Module zerlegt. Bei entsprechend großem Umfang der Lösung kann dabei nach wie vor Folgendes passieren: Die schiere Anzahl der Module wächst Ihnen über den Kopf und das gesamte System ist im Endeffekt wieder unübersichtlich. Was kann man in so einem Fall tun? Eine schlechte Idee wäre, mehr Logik in die einzelnen Module zu geben, sodass die Gesamtzahl an Modulen wieder überschaubar wird. Dadurch würde nur Komplexität in die Module hinein verlagert. Die Alternative ist Strukturen auf der nächst höheren Abstraktionsebene zu bilden. Wir zoomen aus unserer Architektur heraus und bauen dann modulare Strukturen nach denselben Regeln, nach denen wir schon die Module auf der unteren Abstraktionsebene entworfen hatten. Während dies den Vorgang eher bottom-up beschreibt, so ist dasselbe Ergebnis natürlich auch top-down zu erreichen. 

Whole-Part Pattern

Ein fast schon in Vergessenheit geratenes Muster, das dabei hilfreich sein kann, ist das Whole-Part Pattern. Vorgestellt wurde es in einem zeitlosen Klassiker der Software-Architektur namens “Pattern-Oriented Software Architecture” aus dem Jahr 1996. Als Beispiel dient uns der Motor eines Autos. Er besteht aus vielen Einzelteilen, wie dem Kolben, der Kurbelwelle und den Zündkerzen. Der Motor selbst ist aber wiederum nur ein Teil des Autos, das außerdem noch aus Dingen wie dem Lenkrad, der Karosserie, den Rädern und dem Auspuff besteht. Vor dem Fahrer wird diese Komplexität weitestgehend verborgen. Er dreht den Schlüssel um, beschleunigt mit dem Gaspedal und beeinflusst mit dem Lenkrad die Fahrtrichtung. Einmal im Jahr kommt das Auto in die Werkstätte zur Wartung. Dass dort der Filter der Klimaanlage genauso gewechselt wird wie das Motoröl kann dem Fahrer egal sein. Die Abstraktion “Auto” verbirgt all diese Komplexität vor seinem Nutzer so gut es geht.

Das Beispiel mit dem Auto könnte man sogar noch weiterdenken. Ein Robotertaxi-Service könnte eine weitere Abstraktionsebene darstellen. Eine Serversoftware weiß wo sich die einzelnen selbstfahrenden Taxis gerade befinden. Wenn ein Kunde per App eines der Taxis anfordert wird die Software des nächstbesten Robotertaxis dieses zum Kunden bewegen und ihn in weiterer Folge an sein gewünschtes Ziel bringen. Das Auto, die Software darin, die Software am Server und die App am Handy des Kunden bilden dann in Summe eine weitere Abstraktionsebene, die die Mobilität für den Kunden noch weiter vereinfacht.

In einer komplexen Enterprise Architektur können Sie sich dieses Prinzip wie folgt zu Nutze machen: Die Unternehmensarchitekten legen fest, wie sich die Systemlandschaft in einzelne Subsysteme zerlegt. Sie kümmern sich außerdem um Themen, die über die einzelnen Subsysteme hinaus gehen, wie die Wahl der Technologie zur Integration der einzelnen Systeme. Für die Implementierung der einzelnen Subsysteme selbst wird aber nur der grobe Rahmen definiert. Die Verantwortung für die korrekte Umsetzung wird in den einzelnen Teams belassen. Zu klären, wie sich ein konkretes Subsystem selbst dann weiter in Module zerlegt, ist also wiederum Aufgabe eines der Teams. Die Unternehmensarchitekten kümmern sich in einem solchen Modell um die strategischen Themen und überlassen die Taktik den einzelnen Teams.

Self-Contained Systems

Da die Gedanken bisher eher abstrakt waren, möchte ich noch einen konkreten Architekturstil vorstellen, mit dem man das Prinzip der hierarchischen Zerlegung prima umsetzen kann, nämlich Self-Contained Systems (oder kurz: SCS). Diese setzen explizit auf eine sehr lose Kopplung zwischen den einzelnen Teilsystemen. Bevorzugt wird eine Integration über das User-Interface. Ansonsten ist zeitliche Abhängigkeit zwischen den Systemen durch synchrone Kommunikation (wie über SOAP-RPC) eher verpönt und man sollte stattdessen auf asynchrone Integration (wie über Messaging) und Datenreplikation setzen.

Damit das klappt muss anfangs strategisch festgelegt werden, an welchen Grenzen sich das System gut in solch lose gekoppelte Subsysteme zerlegen lässt. Wenn das allerdings klappt, können die einzelnen Teams relativ isoliert voneinander an ihrem jeweiligen Subsystem arbeiten. Die Art der Umsetzung der einzelnen Teilsysteme kann sich dabei auch stark voneinander unterscheiden. So kann es sich bei einem der Subsysteme um einen Legacy-Deployment-Monolithen handeln, während ein anderes auf einer Microservice-Architektur aufbaut.

Im nächsten und bereits letzten Beitrag dieser Artikelserie fass ich das Thema noch einmal kurz zusammen. Außerdem zeige ich Möglichkeiten, wie man eine Architektur nach 5C umsetzt.

CONNECT: Verbinden (5C Design, Teil 5)

By | Allgemein, Inhaltliches | No Comments

Durch Verwendung einer Schnittstelle eines anderen Bausteins kommt es immer zu Abhängigkeiten. Plane explizit zwischen welchen Bausteinen es welche Art von Abhängigkeit geben soll.

  1. Software-Entwurf: Ein Blick zurück und nach vorn
  2. CUT: Richtig schneiden
  3. CONCEAL: Verbergen
  4. CONTRACT: Schnittstelle festlegen
  5. CONNECT: Verbinden
  6. CONSTRUCT: Aufbauen
  7. Its a Wrap: Zusammenfassung

Damit ein System, das in seine Einzelteile zerlegt wurde, in Summe das gewünschte große Ganze ergibt, müssen seine Einzelteile miteinander interagieren. Diese Interaktionen erzeugen Verknüpfungen, die wiederum die einzelnen Teile in Abhängigkeiten zueinander bringen. Vereinfacht gesagt sind bei Änderungen, die nach außen wirksam sind, die angebundenen Module immer zu berücksichtigen. Diesen Aspekt gilt es möglichst klein zu halten. Die Abhängigkeiten können unterschiedliche Bereiche betreffen:

  • Daten und Formate: Ein Consumer muss das Format des Providers einer Schnittstelle verstehen. Bei Änderungen daran ist der Consumer ebenfalls betroffen.
  • Zeit: Wenn der Consumer seine Arbeit nur abschließen kann, wenn der Provider im selben Moment auch gerade verfügbar ist, so ist seine Verfügbarkeit auf Zeiten limitiert, in denen der Provider ebenfalls verfügbar ist. In dem Fall kommt es zu einer zeitlichen Abhängigkeit zwischen den Modulen.
  • Technologie: Ist der Consumer in der technologischen Auswahl seiner Implementierung auf irgendeine Weise eingeschränkt? Ein Netzwerkprotokoll wie Java RMI wirkt beispielsweise einschränkender als eine REST-Integration auf Basis des HTTP-Protokolls.
  • Ausführungsort: Ist es zur Interaktion nötig, dass die Module auf derselben (virtuellen) Maschine laufen, so sind sie was den Ausführungsort angeht eingeschränkt. Bei Kommunikation innerhalb der Grenzen des eigenen Prozesses ist dies beispielsweise so.

Diese technischen Abhängigkeiten ziehen in weiterer Folge Abhängigkeiten auf der organisatorischen Ebene nach sich. Ein Unternehmen, das zur Weiterentwicklung seiner Software überdurchschnittlich viele Meetings benötigt wäre ein Beispiel, wo sich diese Auswirkungen zeigen. Das und ein gezwungenermaßen hohes Maß an Bürokratie sind Indizien dafür, dass man die Abhängigkeiten innerhalb der Software nicht mehr im Griff hat.

Zur Vermeidung von Missverständnissen: Wenn Interaktion nötig ist, ist es nicht möglich, Abhängigkeiten völlig zu vermeiden. Und: Interaktion wird nötig sein. Es gilt die negativen Auswirkungen von Abhängigkeiten durch geschickten Architekturentwurf im Zaum zu halten. Ein bekanntes Entwurfsprinzip, dessen Befolgung dabei hilft, ist das Prinzip der azyklischen Abhängigkeiten. In einem Entwurf wo Module zyklisch voneinander abhängig sind, sind diese Module von jedem anderen in diesem Zyklus direkt oder indirekt abhängig. Diese Situation birgt hohe Risiken von unerwünschten Seiteneffekten bei Änderungen. Daher der Grundsatz Strukturzyklen möglichst zu vermeiden.

Kaskadierende Abhängigkeiten

Ebenfalls problematisch sind sogenannte Kaskadierende Abhängigkeiten. Dabei pflanzt sich ein und dieselbe Abhängigkeit, über die jeweiligen Modulgrenzen hinaus über weitere Abhängigkeiten zu weiteren Modulen fort. Mit anderen Worten: Was auch immer diese Abhängigkeit betrifft, sei es ein Datenformat oder eine Technologie, man wird sie nur ändern oder entfernen können indem man Änderungen am gesamten System vornimmt. Die folgende Grafik illustriert das:

Das Schnittstellenformat, das Baustein A anbietet, wird von den Bausteinen B und C selber wiederum intern benützt. Weiters kommen einzelne Aspekte dieser Schnittstelle in den externen Schnittstellen der Bausteine B und C wieder vor, wodurch sie sich auf deren Consumer (in diesem Fall D, E, F und G) ausbreiten. Eine Änderung der Schnittstelle des Bausteins A zieht dann eine Kaskade an Änderungen nach sich, die schließlich das gesamte System betreffen. Um so etwas zu verhindern bietet sich die Anwendung des Integrationgsmusters Anti-Corruption Layer aus dem Domain-Driven-Design an, das in der folgenden Grafik dargestellt ist. Dabei kommuniziert ein Consumer nur über einen solchen Layer mit seinem Provider, der das Modell des Providers in sein eigenes Format konvertiert.

Wenn Sie den Empfehlungen dieser Blog-Serie beim Entwurf Ihres Systems bis hierhin gefolgt sind kann es sein, dass Ihr Entwurf bereits aus einer sehr großen Zahl an Modulen besteht. Eine hohe Anzahl an Modulen kann, auch wenn diese jeweils wunderbar gekapselt sind, wiederum unübersichtlich werden. Sie tun dann gut daran, wiederum dieselben Regeln anzuwenden, allerdings eine Abstraktionsebene höher. Dies bringt uns zum nächsten Beitrag dieser Reihe: „CONSTRUCT: Aufbauen“.

CONTRACT: Schnittstelle festlegen (5C Design, Teil 4)

By | Allgemein, Inhaltliches | No Comments

Entwerfe Schnittstellen so, dass eine möglichst reibungslose Interaktion zwischen dem Baustein und seinen Consumern möglich ist.

  1. Software-Entwurf: Ein Blick zurück und nach vorn
  2. CUT: Richtig schneiden
  3. CONCEAL: Verbergen
  4. CONTRACT: Schnittstelle festlegen
  5. CONNECT: Verbinden
  6. CONSTRUCT: Aufbauen
  7. Its a Wrap: Zusammenfassung

Wie legt man eine Schnittstelle fest, die eine möglichst reibungslose Interaktion ermöglicht? Tatsächlich ist das Thema bereits in den SOLID Prinzipien sehr prominent vertreten. So steht das L darin für das Liskovsche Substitutionsprinzip von Barbara Liskov (nähere Infos hier). Noch interessanter finde ich aber das I aus SOLID, das für das Interface-Segregation Prinzip steht. Dies ist die erste von 3 Techniken für sauberes Schnittstellendesign, die ich ihnen hier vorstelle. Es besagt, dass die Schnittstelle eines Moduls immer nach ihren einzelnen Verantwortlichkeiten aufgeteilt sein sollte. Es darf demnach nicht eine einzige generische Schnittstelle geben, sondern für jeden Anwendungsfall der Benutzung einer Komponente jeweils eine eigene. Ich möchte das anhand eines Beispiels erläutern.

Interface Segregation und REST-APIs

Die Web Service Description Language (oder kurz WSDL) ist eine Beschreibungssprache für Schnittstellen und ein offizieller Standard des W3C Konsortiums. Sie wird meist in Kombination mit dem Simple Object Access Protocol (oder kurz SOAP) verwendet. Bei meinem Grundlagen-Seminaren zum Thema Software-Architektur geht es u.a. immer auch um das Interface-Segregation Prinzip. Ich frage die Teilnehmer dann gerne, ob jemand unter ihnen schon mal eine WSDL-Datei bekommen hat, die mehrere Megabyte groß war, und von der er (oder sie) sich zunächst einmal wie erschlagen fühlte. Eigentlich ist immer jemand dabei, der so eine Situation schon mal erlebt hatte. Solch komplexe Schnittstellen haben 2 potentielle Probleme:

  • Der Einarbeitungsaufwand für den Entwickler, der diese Schnittstelle verwenden möchte, ist ausgesprochen hoch. In der WSDL Spezifikation ist nicht vorgesehen, die Schnittstelle zu strukturieren.
  • Es besteht die Gefahr, dass der Code, der die Schnittstelle konsumiert, Abhängigkeiten zu Teilen der Schnittstelle entwickelt, die von diesem gar nicht benötigt werden. Sobald das Modell zur Schnittstelle vom Client generiert wurde ist es möglich, auch zu nicht relevanten Teilen einer nur teilweise verwendeten Schnittstelle Abhängigkeiten zu entwickeln.

Als Standard für Schnittstellen im Web hat sich inzwischen der Representational State Transfer als Alternative etabliert. Dabei wird eine komplexe Schnittstelle in ihre einzelnen „Subjekte“ bzw. Ressourcen aufgeteilt. Dieser Schritt entspricht einer Umsetzung des Interface-Segregation-Prinzips. REST hat also das I aus SOLID quasi „mit eingebaut“.

Die Kommunikation mit diesen einzelnen Ressourcen erfolgt mit den „Verben“ des HTTP-Protokolls, also beispielsweise mittels GET, PUT, POST und DELETE. Dabei gibt es auch Weiterleitungen von einer Ressource zur nächsten, die damit in Verbindung steht. Diese Weiterleitung (genannt Hypermedia As the Engine of Application State oder kurz: HATEOAS) bietet eine gewisse Flexibilität was die Änderung der einzelnen Endpoints angeht. Außerdem ist sie noch eine Form der Selbstdokumentation für Nutzer der Schnittstelle. Das Gefühl der Frustration, weil man so etwas wie eine monströse WSDL erhalten hat, sollte es bei REST-APIs also gar nicht erst geben.

Das Schnittstellen-Problem des Mars-Climate Orbiter

Neben der Schnittstellentrennung gibt es weitere Techniken für eine reibungslose Interaktion. Im konkreten Beispiel hätte ihre Anwendung einen Millionenschaden vermieden. Vielleicht hatten Sie es 1999 in den Nachrichten mitbekommen: Die NASA Sonde Mars-Climate Orbiter war abgestürzt. Sie hätte in einen Orbit um den Planeten Mars eintreten sollen, ist aber stattdessen auf dessen Oberfläche zerschellt (für nähere Infos dazu klicken Sie bitte hier). Passiert war Folgendes: Die Software wurde in Teilen von der NASA und teilweise von Lockheed-Martin entwickelt. An einer Stelle gab es eine Schnittstelle zur Weitergabe des gemessenen Impulses an die Steuerungseinheit. Während das eine Team davon ausging, dass dieser auf dem metrischen System basiert ging das andere Team von einer Abbildung basierend auf dem imperialen System aus. Das Ergebnis war der oben erwähnte Verlust der Raumsonde und ein entsprechender Millionenschaden. Ich könnte mir vorstellen, dass diese Schnittstelle nicht viel spezifischer definiert war als in folgendem Listing:


public double getSpeed ();

Eine solche Definition lässt einfach zu vieles offen. Um welche Einheit handelt es sich bei der Geschwindigkeit? Außerdem ist nicht klar ob auch negative Werte möglich sind, oder nur positive Werte als Rückgabewerte in Frage kommen. Diese Art von Problem kann durch eine spezifischere Definition des Schnittstellenkontraktes behoben werden. Viel besser ist die folgende Definition, wo wir uns des JSR305 bedienen und mit der entsprechenden Annotation beschreiben, dass diese Methode keine negativen Werte zurückliefert. Außerdem wird durch die Methodensignatur klar, dass es sich um die SI Einheit für Geschwindigkeit handelt:


public @Nonnegative double getSpeedInMetersPerSecond();

Achtung, Gefahr!

Besonders problematisch sind Schnittstellen, die einem jeden Consumer die Möglichkeit bieten, den Provider selbst in Probleme zu bringen. Dies zu vermeiden wäre mein 3. Tipp zum Thema. Wo man dies häufig antrifft ist, wenn sich mehrere Services oder Subsysteme den Zugriff auf ein und dieselbe Datenbank mit demselben Datenmodell teilen. So wie dies in der folgenden Grafik dargestellt ist:

Die Schnittstelle, die eine solche geteilte Datenbank ihren Consumern bereitstellt ist nämlich das Datenmodell selbst, und im Falle einer relationalen Datenbank die Abfragesprache SQL. Das beinhaltet die Möglichkeit einzelne Tabelleneinträge zu sperren, oder auch die Datenbank mit umfangreichen Query-Abfragen inkl. Joins über viele Tabellen zu lähmen. Eine dermaßen missbräuchliche Verwendung wird die anderen Consumer der Datenbank ebenfalls in Probleme bringen. Genau das sollte aber über eine Schnittstelle gar nicht erst möglich sein. Ich rede dabei wohlgemerkt nicht von Denial-of-Service Attacken, sondern von Dingen, welche früher oder später im Zuge der üblichen Wartungstätigkeit passieren.

Wird eine Schnittstelle zwar angeboten, aber von niemandem benutzt, ist natürlich noch keine Interaktion passiert. Im nächsten Beitrag (“CONNECT: Verbinden”) betrachten wir die Folgen, welche es zwangsläufig haben wird, wenn Bausteine über Schnittstellen miteinander interagieren.