It´s a wrap: Zusammenfassung (5C Design, Teil 7)

By 30. Oktober 2019 November 4th, 2019 Allgemein, Inhaltliches
  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

Die 5C Designprinzipien zielen auf einen nachhaltigen Entwurf hin ab. Nachhaltigkeit in der Softwarearchitektur bedeutet, dass auch zu einem späteren Zeitpunkt Änderungen und Erweiterungen mit hoher Produktivität durchführbar sein werden. Dies wird erreicht indem die Gesamtkomplexität in Einzelteile – die Module – zerlegt wird. Die einzelnen Module lassen sich dann getrennt voneinander…

  • … ändern. Änderungen sollten sich nur in Ausnahmefällen auch auf andere Module auswirken.
  • … ersetzen. Bei Problemen kann ein Modul durch ein anderes ersetzt werden.
  • … dokumentieren und verstehen. Entwickler können sich bei der Einarbeitung und auch der späteren Arbeit geistig auf nur den einen Teil des gesamten Systems konzentrieren.
  • … testen: An den ein- und ausgehenden Schnittstellen können die Module getestet werden.

Beim 5C Design geht es also in erster Linie um die Wartbarkeit der Software. Teilweise wirken sich effiziente Strukturen allerdings auch auf die Betreibbarkeit und die Zuverlässigkeit eines Systems aus. Einzelteile sind dadurch isoliert voneinander zu überwachen bzw. können auch isoliert voneinander ausfallen. Je nachdem wie gut sie im Schritt 4 – CONNECT voneinander unabhängig gehalten wurden.

SOA vs. Microservices

Im ersten Artikel dieser Serie hatte ich ja angekündigt, dass das 5C-Designmodell in der Lage sein wird, die Antipattern der klassischen SOA (Service-Orientierte Architektur) als solche zu entlarven. Seit 2008 heißt es, dass SOA tot sei, ohne dass dies jemals näher begründet wurde. Die heute wesentlich populäreren Microservices setzen tendenziell auf eine modulare Architektur. Ein Beispiel für eine Microservice Architektur hatten wir bereits in Abb. 3 im 2. Artikel der Serie gesehen. Zur Gegenüberstellung hier ein Bild einer klassischen SOA und einer Tabelle zur Abgrenzung zum Microservice-Architekturstil:

AspektSOAMicroservices
KapselungSOA versucht möglichst kleinteilige Services zu machen, die nicht unbedingt einen fachlichen Aspekt, sondern teilweise auch technische Aspekte (wie Persistenz) kapseln. Eine Beispiel wäre eine Service wie “Speichere Adressdaten”.Microservices versuchen eher fachliche Aspekte in Services zu verpacken. Persistenz ist dann ein Teilaspekt eines fachlichen Service. Daten und Logik versucht man möglichst nahe zueinander zu bringen und Schnittstellen möglichst schmal zu definieren.
IntegrationSOA setzt meist auf die Integration über einen zentralen Enterprise-Service-Bus (ESB), der auch Routinglogik beinhaltet, zur Weiterleitung einzelner Nachrichten.Microservices setzen auf das “Dump-Pipes and Smart-Endpoints Prinzip” und versuchen Logik in der Kommunikations-Infrastruktur zu vermeiden. Einzelne Teile länger laufender Prozesse sind ebenfalls Teil eines Microservice wie jede andere Logik.
SchnittstellenSOA versucht Daten- und Schnittstellenmodell unternehmensweit zu vereinheitlichen. Dies ist alleine schon deswegen nötig, damit die Logik am zentralen ESB die Daten, die dort weitertransportiert werden, interpretieren kann.Microservices lassen sich vom strategischen Teil des Domain-Driven-Design (DDD) inspirieren und trennen Gültigkeitsbereiche der Modelle bewusst in getrennten Kontexten voneinander ab.
FokusDas Ziel einer SOA ist, die einmal geschriebenen Services später möglichst vielfältig einsetzen zu können. Man maximiert daher den möglichen Reuse einzelner Services.Microservices haben erkannt, dass die größte Gefahr für eine Systemlandschaft Dinge sind, die man später nicht mehr los wird. Daher maximieren diese Services eher ihre eigene Ersetzbarkeit als Wiederverwendbarkeit.

SOA versucht demnach, ganz im Gegensatz zu den 5C-Designprinzipien, Flexibilität ohne Änderbarkeit zu erreichen. Ein einmal geschriebenes Service soll durch Wiederverwendung in anderen Funktionalitäten ebenfalls genutzt werden können. Eine Änderung an so einem Service wird später aber schwierig, da es dann bereits sehr oft wiederverwendet wurde, was die Auswirkungen einer Änderung maximiert. Die Handlungsmaximen die zu so etwas führten sind Trugschlüsse, die in der Community der Softwarearchitekten schon längst als überholt gelten. Flexibilität erreicht man am besten durch Kapselung, die die Auswirkungen von Änderungen eingrenzt, während eine Maximierung des Reuse Änderungen ausgesprochen schwierig und teuer macht.

Modularisierung von JAVA Code

Während eine Kapselung als unabhängige Deployment-Einheit, genannt Service, eine Möglichkeit zur Modularisierung darstellt, gibt es natürlich auch andere Möglichkeiten Code selbst in einzelne Module zu zerteilen. Java bietet dazu bereits Klassen, Packages und das JPMS. Unabhängig davon können Sie auch auf statische Codeanalyse setzen, um die Einhaltung der modularen Strukturen im Code zu überwachen. Neben vielen kommerziellen Tools gibt es mit ArchUnit auch eine lizenzfreie Alternative. Der folgende Unit-Test prüft die Einhaltung einer Schichtenarchitektur und ist, wie ich hoffe, selbsterklärend:


public class AppTest {
    private final ClassFileImporter importer = new ClassFileImporter();
    private JavaClasses classes;


    @Before
    public void importClasses() {
       classes = importer.importClasspath();
    }


    @org.junit.Test
    public void testApp() {
       

      com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses().that()
          .resideInAPackage("de.embarc.bottom").should()
          .accessClassesThat().resideInAPackage("de.embarc.middle")
          .andShould().accessClassesThat()
          .resideInAPackage("de.embarc.top").check(classes);
       

      com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses().that()       
          .resideInAPackage("de.embarc.middle").should() 
          .accessClassesThat().resideInAPackage("de.embarc.top")
          .check(classes);
   }
 }

Fazit

Die klassische SOA ist während der Wirtschaftskrise 2008 völlig zurecht verstorben. Ein immenser Aufwand wurde davor betrieben um diese Architekturen zu bauen, ohne dass ein Rezept vorhanden war, um die darin enthaltenen Features später noch produktiv anpassen zu können. Ein damals natürlich nicht vorhersehbarer (?!) Umbruch in der Wirtschaft, wie die aktuell stattfindende Digitalisierung, verlangt allerdings heute nach massiven Änderungen in der Wirtschaft, und somit auch nach Änderungen in den Software-Systemen. Unternehmen die Unsummen für eine SOA ausgegeben haben, sind für diesen Umbau heute nicht gewappnet. Ein konsequentes Verfolgen der 5C-Designprinzipien wird Sie vor so etwas in Zukunft bewahren. Vorgestellt wurde 5C-Design übrigens erstmals im Architektur-Spicker „Nachhaltiges Software-Design“ im Februar 2019.

Leave a Reply