Ports and Adapters ‚Äď die hexagonale Zwiebelarchitektur. Teil 1: Einf√ľhrung

Soft¬≠warearchitek¬≠tur ver¬≠fol¬≠gt im wesentlichen zwei Ziele: die innere Struk¬≠turierung von Soft¬≠waresys¬≠te¬≠men und die Min¬≠imierung von Abh√§ngigkeit¬≠en zwis¬≠chen den Struk¬≠turkom¬≠po¬≠nen¬≠ten, den soge¬≠nan¬≠nten Bausteinen. Sp√§testens seit den Neun¬≠ziger¬≠jahren war das Mul¬≠ti-Tier-Pat¬≠tern, die klas¬≠sis¬≠che Schicht¬≠e¬≠nar¬≠chitek¬≠tur, der Stand der Kun¬≠st. Seit eini¬≠gen Jahren wird dieses Grund¬≠muster zunehmend durch einen neuen De-fac¬≠to-Stan¬≠dard abgel√∂st, der als Hexag¬≠o¬≠nale Architek¬≠tur bekan¬≠nt gewor¬≠den ist. Was hat es mit diesem mys¬≠tis¬≠chem Begriff auf sich, und welche Vorteile bringt dieser Architek¬≠turstil f√ľr die Soft¬≠wa¬≠reen¬≠twick¬≠lung?

Im ersten Teil dieser Artikelserie geht es darum, die Begriffe zu klären und den prinzip­iellen Auf­bau ein­er Hexag­o­nalen Architek­tur zu ver­ste­hen. Doch zunächst machen wir einen kleinen Aus­flug in die Entste­hungs­geschichte und die Ein­flussfak­toren dieses pop­ulären Mikroar­chitek­tur­musters.

Historische Entwicklung

Alistair Cockburn, 2005

Der Begriff der Hexag¬≠o¬≠nalen Architek¬≠tur wurde im Jahre 2005 von Alis¬≠tair Cock¬≠burn gepr√§gt, einem der Mitze¬≠ich¬≠n¬≠er des Agilen Man¬≠i¬≠fests. Das Wort ‚Äěhexag¬≠o¬≠nal‚Äú beschreibt dabei lediglich die von Cock¬≠burn gew√§hlte grafis¬≠che Darstel¬≠lung der von ihm vorgeschla¬≠ge¬≠nen Mikroar¬≠chitek¬≠tur:

Quelle: alistair.cockburn.us

Cock¬≠burns Ansatz sieht die strik¬≠te Tren¬≠nung von innerem Code und √§u√üerem Code vor, wobei innen den Anwen¬≠dungskern meint, also den Teil des Codes, der die Gesch√§ft¬≠slogik enth√§lt. Um diesen Kern herum, also au√üen, sind die tech¬≠nis¬≠chen Code¬≠teile ange¬≠ord¬≠net, welche den Gesch√§ftskern mit der √§u√üeren Welt verbinden. Die Au√üen¬≠welt, das sind beispiel¬≠sweise Brows¬≠er-UIs, Mobile-Apps, Mail-Clients, Daten¬≠banken, Mes¬≠sage-Bro¬≠ker usw., wor√ľber die Anwen¬≠dung mit Benutzern oder anderen Sys¬≠te¬≠men Dat¬≠en aus¬≠tauscht.

Jeffrey Palermo, 2008

Kurze Zeit später veröf­fentlichte Jef­frey Paler­mo seinen Vorschlag zur Struk­turierung von Soft­waresys­te­men, den er Onion Archi­tec­ture nan­nte. Zur grafis­chen Darstel­lung wählte er konzen­trische Kreise, ähn­lich den Schicht­en ein­er Zwiebel:

Quelle: jeffreypalermo.com

Paler­mo tren­nt eben­falls tech­nis­chen von fach­lichem Code, wobei der App­lika­tionskern expliz­it weit­er unterteilt wird: das Object Mod­el fungiert als Zen­trum, um das herum sich Object Ser­vices und Appli­ca­tion Ser­vices anord­nen. Die Object-Ser­vice-Schicht definiert dabei die tech­nis­chen Inter­faces, die vom äußeren Infra­struc­ture-Lay­er imple­men­tiert wer­den. Hier begeg­net uns das Depen­den­cy Inver­sion Prin­ci­ple (DIP).

Mike Evans, 2004

Viele Grund­la­gen der mod­er­nen Soft­wa­reen­twick­lung wur­den bere­its 2004 von Eric Evans dargelegt bzw. bestätigt. Sein Buch Domain Dri­ven Design beschreibt eine an fach­lichen Gesicht­punk­ten aus­gerichtete Meth­ode, die einen gewis­sen inneren Auf­bau der entwick­el­ten Kom­po­nen­ten impliziert. Das Ziel ist auch hier, fach­lichen von tech­nis­chem Code zu tren­nen.

Quelle: www.ajlopez.com

Evans schlägt eine Aufteilung nach Schicht­en mit strik­ten Ver­ant­wortlichkeit­en und definierten Abhängigkeit­en vor, wobei der Domain-Lay­er die zen­trale Geschäft­skom­po­nente darstellt. Dieser Domain Core hat selb­st keine direk­ten Abhängigkeit­en zu anderen Kom­po­nen­ten. Auch hier wieder DIP: der Domain Core definiert die Inter­faces, die vom Infra­struc­ture-Lay­er imple­men­tiert wer­den.

Die Ans√§tze aller drei Autoren ‚ÄĒ und es gibt einige weit¬≠ere, die hier aus Gr√ľn¬≠den der √úber¬≠schaubarkeit geflissentlich unter¬≠schla¬≠gen wer¬≠den ‚ÄĒ √§hneln sich in ihrem Wesen. Zusam¬≠mengenom¬≠men definieren sie eine mod¬≠erne Mikroar¬≠chitek¬≠tur, die sowohl f√ľr den ‚Äěaltherge¬≠bracht¬≠en‚Äú Mono¬≠lithen als auch bei mod¬≠er¬≠nen Microser¬≠vices anwend¬≠bar ist.

Begriffsverwirrung ‚ÄĒ Hexagonal? Domain Driven? Onion?

Die Namen Hexag¬≠o¬≠nale Architek¬≠tur, Zwiebel-Architek¬≠tur und Domain Dri¬≠ven Design (kurz DDD) wer¬≠den im All¬≠t¬≠ags¬≠ge¬≠brauch oft syn¬≠onym ver¬≠wen¬≠det. Die Beze¬≠ich¬≠nung Hexag¬≠o¬≠nal hat sich jedoch durchge¬≠set¬≠zt, um dieses Architek¬≠tur¬≠muster zu beschreiben. Zum einen ver¬≠mut¬≠lich, weil es so sch√∂n eso¬≠ter¬≠isch klingt, ohne jedoch K√ľchenas¬≠sozi¬≠a¬≠tio¬≠nen zu weck¬≠en. Zum anderen ist DDD in sein¬≠er Gesamtheit mehr als Methodik zu ver¬≠ste¬≠hen, ist daher viel bre¬≠it¬≠er gefasst und geht √ľber die reine Struk¬≠turierung von Soft¬≠ware-Bausteinen hin¬≠aus.

Hexagonale Architektur: Definition der Begriffe

Ports

Ein Port definiert logisch zusam¬≠menge¬≠h√∂rige Use Cas¬≠es und daf√ľr ben√∂tigten Schnittstellen.

In der fol¬≠gen¬≠den Abbil¬≠dung sind beispiel¬≠sweise diese Schnittstellen definiert (Beispiele √ľber¬≠nom¬≠men von Cock¬≠burn, s.o.):

  1. Daten­ver­ar­beitung
  2. Admin­is­tra­tion
  3. Events/Notifications (nach außen)
  4. Daten­bank­abfra­gen.
Abb.: Ports definieren die Schnittstellen zur Außen­welt

Auf der linken Seite des Hexa­gons sehen wir die aktiv­en Ports 1. und 2., während 3. und 4. auf der recht­en Seite als pas­sive Ports ange­ord­net sind. Aktive und pas­sive Ports bilden zusam­men den Infra­struc­ture Lay­er, also den Teil der Anwen­dung, der mit der Außen­welt kom­mu­niziert.

Aktive und passive Ports

√úber die aktiv¬≠en Ports, die nach au√üen sicht¬≠bar sind, wer¬≠den √Ąnderun¬≠gen in der App¬≠lika¬≠tion angesto√üen. Men¬≠schliche Benutzer oder tech¬≠nis¬≠che Clients greifen √ľber die √∂ffentlichen Schnittstellen aktiv in den Zus¬≠tand der Anwen¬≠dung ein. Aktive Ports wer¬≠den auch als Prim√§r¬≠ports oder Inbound Ports beze¬≠ich¬≠net.

Dahinge­gen sind die pas­siv­en Ports nicht von außer­halb der Anwen­dung zugänglich. Über sie kann nur die Anwen­dung selb­st auf andere Sys­teme lesend oder schreibend zugreifen und die erhal­te­nen Antworten inner­halb ihrer eige­nen Geschäft­sprozesse ver­ar­beit­en. Die Ver­wen­dung dieser Ports erfol­gt somit pas­siv. Über die pas­siv­en Ports kann keine direk­te Inter­ak­tion mit der Anwen­dung erfol­gen. Pas­sive Ports sind auch als Sekundär­ports oder Out­bound Ports bekan­nt.

Port = Schnittstelle + Datentransport

Die Ports ein­er Soft­ware­an­wen­dung beste­hen aus ein­er Schnittstel­len­spez­i­fika­tion und den benötigten DTOs, mit deren Hil­fe Daten­struk­turen in die Anwen­dung hinein und hin­aus trans­portiert wer­den.

ISP ‚Äď Interface Segregation Principle

Pas¬≠sive Ports bilden nicht die kom¬≠plette Schnittstelle des exter¬≠nen Sys¬≠tems ab, son¬≠dern nur genau den Teil, der von der App¬≠lika¬≠tion ger¬≠ade ben√∂tigt wird. So w√ľrde der Noti¬≠fi¬≠ca¬≠tion-Port (Nr. 3 in der obi¬≠gen Abbil¬≠dung) lediglich den Teil der Mailserv¬≠er-API nutzen, der zum Versenden von E‚ÄĎMails ben√∂tigt wird. Das zuge¬≠h√∂rige DTO enth√§lt dann auch nur die Attribute, die tat¬≠s√§ch¬≠lich f√ľr den Mail¬≠ver¬≠sand rel¬≠e¬≠vant sind. Wer¬≠den beispiel¬≠sweise die Felder CC und BCC nicht ben√∂tigt, wird das DTO sie nicht enthal¬≠ten.

Adapters

Adapter fungieren als Ver­mit­tler zwis­chen Sys­te­men mit unter­schiedlichen Schnittstellen.

In der abstrak¬≠ten Welt der Soft¬≠waretech¬≠nik dienen Adapter dazu, Daten¬≠struk¬≠turen aus Fremdsys¬≠te¬≠men in das eigene Sys¬≠tem zu √ľber¬≠f√ľhren, zu adap¬≠tieren, und zwis¬≠chen bei¬≠den Dom√§¬≠nen hin- und her zu trans¬≠formieren.

Primäre und sekundäre Adapter

Zu einem Port gibt es einen oder mehrere Adapter. Aktive Ports enthal¬≠ten prim√§re Adapter, das sind die Con¬≠troller der Anwen¬≠dung. √úber sie gelan¬≠gen Anweisun¬≠gen und Dat¬≠en von au√üen zum Anwen¬≠dungskern, um dort die Gesch√§ft¬≠slogik auszuf√ľhren und Antworten zu erhal¬≠ten.

Die sekund√§ren Adapter der pas¬≠siv¬≠en Ports wer¬≠den vom Anwen¬≠dungskern genutzt, um externe Sys¬≠teme einzu¬≠binden. Beispiel¬≠sweise andere Microser¬≠vices, Mes¬≠sag¬≠ing- oder Stor¬≠agesys¬≠teme, wie die fol¬≠gen¬≠den Grafik ver¬≠an¬≠schaulicht. Sekund√§radapter imple¬≠men¬≠tieren immer genau den Teil der exter¬≠nen Schnittstelle, der vom Anwen¬≠dungskern ben√∂tigt wird ‚Äď auch hier wieder ISP.

Abb.: Primäre und sekundäre Adapter

Zu beacht­en ist hier­bei die Rich­tung der Abhängigkeit­en: Primäre Adapter rufen den Anwen­dungskern, dieser ken­nt jedoch die primären Adapter nicht. Sekundäre Adapter wer­den vom Anwen­dungskern benutzt, ken­nen diesen jedoch selb­st nicht. Die Aufrufhier­ar­chie im Hexa­gon geht also von links nach rechts, wie fol­gen­des Bild ver­an­schaulicht:

Abb.: Die Aufrufhier­ar­chie im Hexa­gon

Application

Der Appli­ca­tion-Ring im Hexa­gon markiert die Verbindungss­chicht zwis­chen der Infra­struk­tur und dem Domainkern. Hier resi­diert die App­lika­tion­slogik. Das ist der Teil der Logik, der nicht die Geschäft­sregeln bein­hal­tet, wohl aber die Use Cas­es anstößt und koor­diniert. Außer­dem sind hier die tech­nis­chen Belange der App­lika­tion abge­bildet, beispiel­sweise Secu­ri­ty, Log­ging, Daten­bank­transak­tio­nen oder Ses­sion­han­dling. Bei der vielz­i­tierten Tren­nung von Tech­nik und Fach­lichkeit kommt dem Appli­ca­tion­lay­er eine entschei­dende Bedeu­tung zu. Es sind in erster Lin­ie die Appli­ca­tion Ser­vices, die seine Sub­stanz bilden.

Application Service

Appli¬≠ca¬≠tion Ser¬≠vices definieren die Ein¬≠stiegspunk¬≠te f√ľr Use Cas¬≠es und koor¬≠dinieren deren Abl√§ufe.

Abb.: Der Appli­ca­tion Lay­er mit seinen Appli­ca­tion Ser­vices

Ein Appli¬≠ca¬≠tion Ser¬≠vice wird von einem Prim√§radapter, also einem Con¬≠troller aufgerufen. Der Appli¬≠ca¬≠tion Ser¬≠vice gibt den Aufruf an den Domain Core weit¬≠er und st√∂√üt dadurch den zuge¬≠h√∂ri¬≠gen Use Case an. Zusam¬≠men¬≠h√§n¬≠gende Use Cas¬≠es wer¬≠den vom Appli¬≠ca¬≠tion Ser¬≠vice koor¬≠diniert, einzelne Ergeb¬≠nisse wer¬≠den zu Antworten aggregiert und erforder¬≠liche Events, z.B. Mail¬≠ver¬≠sand oder Noti¬≠fi¬≠ca¬≠tions f√ľr andere Ser¬≠vices, wer¬≠den angetrig¬≠gert. Wo n√∂tig, kom¬≠mu¬≠niziert der Appli¬≠ca¬≠tion Ser¬≠vice mit den Sekund√§radaptern der pas¬≠siv¬≠en Ports, um beispiel¬≠sweise Eni¬≠tys aus einem Daten¬≠bankrepos¬≠i¬≠to¬≠ry oder von ein¬≠er ent¬≠fer¬≠n¬≠ten REST-API zu laden, die f√ľr den Ablauf des Use Cas¬≠es ben√∂tigt wer¬≠den. Wie bere¬≠its erw√§h¬≠nt ‚Äď man kann es nicht oft genug wieder¬≠holen ‚Äď enth√§lt der Appli¬≠ca¬≠tion Ser¬≠vice selb¬≠st keine Gesch√§ft¬≠slogik.

Domain Core

Der Domain Core ist der fach¬≠liche Kern der App¬≠lika¬≠tion. Er enth√§lt die fach¬≠liche Imple¬≠men¬≠tierung der Use Cas¬≠es mit der auszuf√ľhren¬≠den Gesch√§ft¬≠slogik. Au√üer¬≠dem die Imple¬≠men¬≠tierung der Fachk¬≠lassen, das soge¬≠nan¬≠nte Domain Mod¬≠el.

Abb. Der Domain Core im Hexa­gon mit Domain Mod­el und Domain Ser­cvices

Domain Model

Das Domain Mod¬≠el bein¬≠hal¬≠tet im Wesentlichen die in dem fach¬≠lichen Kon¬≠text ‚Äď Bound¬≠ed Con¬≠text im DDD-Jar¬≠gon ‚Äď iden¬≠ti¬≠fizierten Entit√§ten. Diese bilden den eigentlichen Kern der App¬≠lika¬≠tion. Hier ist das Wis¬≠sen der Fach¬≠dom√§ne enthal¬≠ten, soweit es zur Durch¬≠f√ľhrung der abzu¬≠bilden¬≠den Use Cas¬≠es erforder¬≠lich ist. Im Domain Dri¬≠ven Design ist das Domain Mod¬≠el das Herzst√ľck der Soft¬≠ware. Appli¬≠ca¬≠tion- und Infra¬≠struc¬≠ture¬≠lay¬≠er wer¬≠den um den Domainkern herum ange¬≠ord¬≠net und sind vom diesem abh√§ngig, nicht umgekehrt. Die Darstel¬≠lung als konzen¬≠trisches Hexa¬≠gon ist dazu geeignet, dieses wichtige Grund¬≠prinzip eing√§ngig zu visu¬≠al¬≠isieren. Gesch√§ft¬≠slogik ist im Rich Domain Mod¬≠el in den Meth¬≠o¬≠d¬≠en der Fachk¬≠lassen imple¬≠men¬≠tiert. Solche Teile der Logik, die kein¬≠er Fachk¬≠lasse direkt zuge¬≠ord¬≠net wer¬≠den k√∂n¬≠nen, wer¬≠den in Domain Ser¬≠vices aus¬≠ge¬≠lagert.

Domain Services

Die Domain Ser¬≠vices enthal¬≠ten √ľber¬≠greifende Gesch√§ft¬≠slogik, die nicht eins-zu-eins auf Fachk¬≠lassen abge¬≠bildet wer¬≠den kann. Domain Ser¬≠vices wer¬≠den vom Appli¬≠ca¬≠tion-Lay¬≠er, genauer von den dor¬≠ti¬≠gen Appli¬≠ca¬≠tion Ser¬≠vices aufgerufen. Ein Domain Ser¬≠vice darf direk¬≠ten Zugriff auf die Infra¬≠struc¬≠ture haben und deren pas¬≠sive Adapter benutzen. Hier¬≠bei ist allerd¬≠ings abzuw√§¬≠gen, ob dies wirk¬≠lich notwendig ist, oder ob der Aufruf bess¬≠er in den Appli¬≠ca¬≠tion Lay¬≠er zu ver¬≠lagern w√§re.

Im ersten Fall kann der Domain Lay¬≠er ein DIP-Inter¬≠face bere¬≠it¬≠stellen, um den Adapter von der Domain zu entkop¬≠peln. Fern¬≠er ist darauf zu acht¬≠en, dass keine Infra¬≠struc¬≠ture-Depen¬≠den¬≠cys in die Domain hineinge¬≠zo¬≠gen wer¬≠den, beispiel¬≠sweise √ľber R√ľck¬≠gabe¬≠w¬≠erte des Adapters.

Im zweit¬≠en Fall w√ľrde der Appli¬≠ca¬≠tion Ser¬≠vice mit der Infra¬≠struc¬≠ture kom¬≠mu¬≠nizieren und das Ergeb¬≠nis des Aufrufs in ad√§quater Form an die Domain √ľbergeben. Diese Vari¬≠ante sollte bevorzugt einge¬≠set¬≠zt wer¬≠den, es sei denn, prag¬≠ma¬≠tis¬≠che Gr√ľnde sprechen f√ľr den anderen Weg.

Abhängigkeiten und Aufrufhierarchien

Das Hexa¬≠gon beste¬≠ht aus zwei logis¬≠chen H√§lften, der linken aktiv¬≠en Seite und der pas¬≠siv¬≠en recht¬≠en. In der Abbil¬≠dung ist zu erken¬≠nen, dass Aufrufe nur in eine Rich¬≠tung gehen, und zwar von links nach rechts. Niemals w√ľrde ein pas¬≠siv¬≠er Adapter einen Appli¬≠ca¬≠tion Ser¬≠vice aufrufen, oder dieser einen aktiv¬≠en Adapter. Solche Calls sind strikt ver¬≠boten.

Die Abhängigkeit­en der Schicht­en gehen immer von außen nach innen. Allerd­ings gibt es keine Depen­den­cy von dem pas­siv­en Teil des Infra­struc­ture Lay­ers zum Appli­ca­tion Lay­er.

Abb.: Aufrufhier­ar­chien und Abhängigkeit­en zwis­chen den Grund­bausteinen des Hexa­gons

Somit lässt sich zusam­men­fassen:

  • Jed¬≠er Baustein kann eine Depen¬≠den¬≠cy zum Domain Mod¬≠el haben.
  • Die Benutzung der Gesch√§ft¬≠slogik bleibt jedoch den Appli¬≠ca¬≠tion Ser¬≠vices vor¬≠be¬≠hal¬≠ten.
  • Appli¬≠ca¬≠tion Ser¬≠vices k√∂n¬≠nen sowohl die Sekund√§radapter der pas¬≠siv¬≠en Ports als auch die Domain Ser¬≠vices benutzen.
  • Domain Ser¬≠vices k√∂n¬≠nen Sekund√§radapter benutzen, wenn dies aus prag¬≠ma¬≠tis¬≠chen Gr√ľn¬≠den sin¬≠nvoll erscheint.
  • Das Domain Mod¬≠el hat kein¬≠er¬≠lei Abh√§ngigkeit¬≠en zu anderen Bausteinen.

Ausblick

Im n√§ch¬≠sten Teil tauchen wir tiefer in die einzel¬≠nen Ringe hinein und definieren deren Inhalte im Detail. Weit¬≠er¬≠hin m√ľssen wir eini¬≠gen Fra¬≠gen nachge¬≠hen, die bei der Umset¬≠zung eines Architek¬≠tur¬≠musters immer wieder gestellt wer¬≠den. Zum Beispiel, was ist Busi¬≠ness¬≠logik, was ist Anwen¬≠dungslogik, und worin unter¬≠schei¬≠den sie sich? In welchem Teil des Hexa¬≠gons wer¬≠den Domain¬≠ob¬≠jek¬≠te erzeugt, die sich aus Dat¬≠en von mehreren Drittsys¬≠tem zusam¬≠menset¬≠zen? Wo wer¬≠den Quer¬≠schnitts¬≠the¬≠men wie Daten¬≠va¬≠li¬≠dierung, Excep¬≠tion¬≠han¬≠dling, Log¬≠ging usw. imple¬≠men¬≠tiert? Und was zur H√∂lle ist im recht¬≠en Teil des Appli¬≠ca¬≠tion-Rings?

Es bleibt also span¬≠nend. Bis dahin, hap¬≠py engi¬≠neer¬≠ing ūüôā

‚ÄěPat¬≠terns are use¬≠ful because it gives soft¬≠ware pro¬≠fes¬≠sion¬≠als a com¬≠mon vocab¬≠u¬≠lary with which to com¬≠mu¬≠ni¬≠cate. ‚Äú

Jef­frey Paler­mo

Stille Killer pt.#1: Technische Schulden

Im Soft¬≠wa¬≠reen¬≠twick¬≠lung¬≠sprozess k√∂n¬≠nen Zust√§nde entste¬≠hen, die den Pro¬≠jek¬≠ter¬≠folg verz√∂gern, gef√§hrden oder g√§n¬≠zlich unm√∂glich machen. Schon manch¬≠es Pro¬≠jekt musste wegen man¬≠gel¬≠nden Bewusst¬≠seins √ľber solche Risiken wieder¬≠holt neu aufge¬≠set¬≠zt oder g√§n¬≠zlich begraben wer¬≠den. Selb¬≠st dann jedoch bleiben die Ursachen h√§u¬≠fig im Ver¬≠bor¬≠ge¬≠nen. Ich nenne sie daher stille Killer ‚Äď die unerkan¬≠nte, zuweilen auch nur unter¬≠sch√§tzte Gefahr.

Der Begriff der Tech¬≠nis¬≠chen Schulden ist heute den meis¬≠ten, die in irgen¬≠dein¬≠er Weise mit Soft¬≠wa¬≠reen¬≠twick¬≠lung zu tun haben, gel√§u¬≠fig. In agilen Entwick¬≠lerteams wird er f√ľr gew√∂hn¬≠lich regelm√§√üig the¬≠ma¬≠tisiert. Unter dem K√ľrzel TD f√ľr Englisch Tech¬≠ni¬≠cal Debt wird die Tech¬≠nis¬≠che Schuld gerne bem√ľht, um Verz√∂gerun¬≠gen oder Fehler¬≠rat¬≠en zu begr√ľn¬≠den. Und obwohl das Konzept der Tech¬≠nis¬≠chen Schuld in den let¬≠zten Jahren zunehmend pop¬≠ul√§r gewor¬≠den ist, gibt es einen Umstand, der allzu leicht √ľberse¬≠hen wird: die Entste¬≠hung von Tech¬≠nis¬≠ch¬≠er Schuld ist unver¬≠mei¬≠d¬≠bar.

Technische Schuld ist ein Naturgesetz

Wir sind nicht hellsichtig, und Zeit ist ein knappes Gut (glauben wir)

Soviel wir uns auch bem√ľhen, wir k√∂n¬≠nen nicht jedes Detail vorausah¬≠nen. Auch k√∂n¬≠nen wir uns nicht beliebig viel Zeit nehmen, immer die ide¬≠ale L√∂sung zu entwer¬≠fen. So manche weitre¬≠ichende Entschei¬≠dung tre¬≠f¬≠fen wir inner¬≠halb von Sekun¬≠den. Manch¬≠mal bemerken wir zu sp√§t, dass uns zur opti¬≠malen Umset¬≠zung schlicht Wis¬≠sen fehlte.

Architektur erodiert

Und dann ist da noch etwas, das Dr. Car¬≠o¬≠la Lilien¬≠thal als Architek¬≠turero¬≠sion beze¬≠ich¬≠net. Damit ist gemeint, dass selb¬≠st ein ide¬≠al¬≠er Entwurf mit der Zeit seine G√ľltigkeit ver¬≠liert, und aus ein¬≠er ehe¬≠mals guten mit der Zeit eine weniger gute, vielle¬≠icht sog¬≠ar schlechte Imple¬≠men¬≠tierung wird. Eine Architek¬≠tur, die gestern noch per¬≠fekt war, ist heute falsch, da die Umst√§nde sich ver√§n¬≠dert haben. Geset¬≠zliche Vor¬≠gaben oder neue Ver¬≠fahren im Zahlungsverkehr sind gute Beispiele daf√ľr. Davon abge¬≠se¬≠hen entste¬≠ht Ero¬≠sion h√§u¬≠fig auch dadurch, dass ver¬≠schiedene Entwick¬≠ler mit unter¬≠schiedlichem Hin¬≠ter¬≠grund und Sachver¬≠stand den Code mit der Zeit in ein Sta¬≠di¬≠um zunehmender Unord¬≠nung √ľber¬≠f√ľhren. Kurz gesagt: der Code wird mit der Zeit immer schlechter. F√ľr viele Soft¬≠ware¬≠pro¬≠jek¬≠ten ist das eine fest¬≠ste¬≠hende Tat¬≠sache.

frei nach C. Lilien¬≠thal: der ‚ÄěKor¬≠ri¬≠dor geringer Tech¬≠nis¬≠ch¬≠er Schuld‚Äú

Es ist also schw¬≠er, TDs in Soft¬≠waresys¬≠te¬≠men ganz zu ver¬≠mei¬≠den. Wohl aber gibt es M√∂glichkeit¬≠en, die Sch√§¬≠den zu min¬≠imieren, indem wir ihr Aus¬≠ma√ü inner¬≠halb eines ‚ÄěKor¬≠ri¬≠dors geringer tech¬≠nis¬≠ch¬≠er Schulden‚Äú (Lilien¬≠thal) hal¬≠ten. Doch zun√§chst wollen wir ver¬≠suchen zu umrei√üen, was Tech¬≠nis¬≠che Schuld f√ľr uns bedeutet.

Definition

Tat¬≠s√§ch¬≠lich gibt es zur Def¬≠i¬≠n¬≠i¬≠tion von TD unter¬≠schiedliche Betra¬≠ch¬≠tungsweisen. Die ein¬≠fach¬≠ste ist, jed¬≠wede unsachgem√§√üe Pro¬≠gram¬≠mierung als TD zu beze¬≠ich¬≠nen. Unsachgem√§√ü bedeutet hier: den Stand der Kun¬≠st mis¬≠sach¬≠t¬≠end oder ein¬≠fach sch√§big pro¬≠gram¬≠miert.

Eine andere Auf¬≠fas¬≠sung besagt, dass es immer eine bewusste Entschei¬≠dung sein sollte, Tech¬≠nis¬≠che Schulden aufzunehmen ‚Äď schlechte Pro¬≠gram¬≠mierung oder man¬≠gel¬≠hafte Architek¬≠tur fie¬≠len dann also nicht darunter. Hier w√ľr¬≠den wir kurzfristig und bewusst ein TD akzep¬≠tieren, um ein anderes Ziel, beispiel¬≠sweise einen bevorste¬≠hen¬≠den Releaseter¬≠min, schneller zu erre¬≠ichen.

Als Ver­all­ge­meinerung bei­der Sicht­en ließe sich definieren, dass Tech­nis­che Schuld poten­ziell jed­er Zus­tand ein­er Soft­ware ist, der eine naht­lose Weit­er­en­twick­lung ver­hin­dert.

Gr√ľnde und Auswirkungen

Aufgeschobene Refactorings

Sobald durch eine anste¬≠hende Erweiterung die Umstruk¬≠turierung beste¬≠hen¬≠der Teile der Soft¬≠ware erforder¬≠lich wird, dro¬≠ht ein Schulden¬≠loch. Ob es sich auf¬≠tut und wir hine¬≠in¬≠fall¬≠en h√§ngt davon ab, ob das Refac¬≠tor¬≠ing durchge¬≠f√ľhrt wird oder nicht. Wenn ja, ist alles gut ‚Äď keine TD aufge¬≠baut. Wenn wir es nicht tun, haben wir von dem Moment an eine TD, die mit jedem kom¬≠menden Change Request ihre Zin¬≠sen ein¬≠fordern wird. Der Zins¬≠eszin¬≠sef¬≠fekt ist bekan¬≠ntlich ein expo¬≠nen¬≠tielles Ph√§nomen. Das gilt auch in der Soft¬≠wa¬≠reen¬≠twick¬≠lung.

H√§u¬≠fig wird mit der Umset¬≠zung von Erweiterun¬≠gen begonnen, ohne vorher zu pr√ľfen, ob die beste¬≠hende Architek¬≠tur den neuen Anforderun¬≠gen stand¬≠h√§lt. N√∂tige Refac¬≠tor¬≠ings wer¬≠den so erst sp√§t erkan¬≠nt, wenn √ľber¬≠haupt. Nach zwei oder drei Erweiterungszyklen ist das Dilem¬≠ma oft¬≠mals bere¬≠its so weit fort¬≠geschrit¬≠ten, dass Ma√ü¬≠nah¬≠men zur Behe¬≠bung sehr deut¬≠lich zu Buche schla¬≠gen w√ľr¬≠den. Die L√∂sung hei√üt dann allzu oft ‚ÄěAugen zu und durch‚Äú ‚Äď und so man√∂vri¬≠ert sich das Pro¬≠jekt selb¬≠st immer tiefer in den Schulden¬≠berg. In dieser Phase begin¬≠nen die Schmerzen gro√ü genug zu wer¬≠den, um die Aufmerk¬≠samkeit des Man¬≠age¬≠ments oder des Kun¬≠den zu gewin¬≠nen. Die Frage lautet dann, warum selb¬≠st kleine Fea¬≠ture-Erweiterun¬≠gen ‚Äěso lange‚Äú dauern.

Featuritis

Es ist eine Bin¬≠sen¬≠weisheit, dass viele Soft¬≠ware¬≠pro¬≠jek¬≠te mit Bazil¬≠lus Fea¬≠tu¬≠ri¬≠tis infiziert sind. Das giftige Stof¬≠fwech¬≠sel¬≠pro¬≠dukt dieses Erregers ist TD. Eine der Schwierigkeit¬≠en bei der Diag¬≠nose von TD ist die lange Inku¬≠ba¬≠tion¬≠szeit. W√§hrend funk¬≠tionale Soft¬≠warefehler meist fr√ľhzeit¬≠ig zutage treten, wirken sich TDs eine Zeit lang eher unter¬≠schwellig aus. Wenn ihre unsch√∂¬≠nen Symp¬≠tome wie erschw¬≠erte Wart¬≠barkeit und steigende Defect-Rat¬≠en endlich zutage treten, ist das Soft¬≠ware¬≠pro¬≠dukt bere¬≠its der¬≠art herun¬≠tergewirtschaftet, dass ein Gegen¬≠s¬≠teuern nicht mehr ohne deut¬≠lichen Mehraufwand zu bew¬≠erk¬≠stel¬≠li¬≠gen ist. Das liegt daran, dass TD ein Aspekt der inneren Soft¬≠ware¬≠qual¬≠it√§t ist, beziehungsweise ein Man¬≠gel der¬≠sel¬≠ben. Die innere Qual¬≠it√§t eines Pro¬≠duk¬≠ts ist von au√üen nicht direkt sicht¬≠bar. Sie wird nur dann wahrgenom¬≠men, wenn sie so d√ľrftig ist, dass sie zu Fehlfunk¬≠tio¬≠nen oder steigen¬≠den Aufw√§n¬≠den f√ľhrt.

Das Gesetz von Conway

Nach dem vielz¬≠i¬≠tierten Gesetz von Con¬≠way, englisch Conway‚Äės Law, entsprechen die Struk¬≠turen eines Soft¬≠waresys¬≠tems zwangsl√§u¬≠fig denen der Organ¬≠i¬≠sa¬≠tion, die es her¬≠vorge¬≠bracht hat. Ver¬≠schiedene Stu¬≠di¬≠en haben dieses Pos¬≠tu¬≠lat aus den achtziger Jahren best√§tigt. Das bedeutet am konkreten Beispiel, ein zen¬≠tral¬≠is¬≠tisch organ¬≠isiertes Unternehmen wird sich mit Microser¬≠vice-Architek¬≠turen, wo Dezen¬≠tral¬≠isierung, Ereignis¬≠s¬≠teuerung, Infor¬≠ma¬≠tion¬≠saus¬≠tausch und Entkop¬≠plung eine gro√üe Rolle spie¬≠len, ver¬≠mut¬≠lich schw¬≠er¬≠tun. Tech¬≠nis¬≠chen Schulden fall¬≠en in dieselbe Kat¬≠e¬≠gorie. Steile Hier¬≠ar¬≠chien, F√ľhrung in Form von Kom¬≠man¬≠dostruk¬≠turen anstatt Ser¬≠vant Lead¬≠er¬≠ship sowie fach¬≠liche und soziale Inkom¬≠pe¬≠tenz beg√ľn¬≠sti¬≠gen den N√§hrbo¬≠den f√ľr das Wach¬≠s¬≠tum von TD.

Wege aus der Schuldenfalle

Schuldeingeständnis

Ist ein Pro¬≠jekt ein¬≠mal in einen Zus¬≠tand tech¬≠nis¬≠ch¬≠er √úber¬≠schul¬≠dung einge¬≠treten, gibt es den¬≠noch Wege hin¬≠aus. Sie erfordern im ersten Schritt ein Schuldeingest√§nd¬≠nis der Beteiligten: Prod¬≠uct-Own¬≠er, Devel¬≠op¬≠ment-Team und Pro¬≠jek¬≠tleitung m√ľssen sich √ľber ihre jew¬≠eili¬≠gen Anteile im Klaren sein und gemein¬≠sam eine L√∂sung erar¬≠beit¬≠en. Ein Coach kann dabei hil¬≠fre¬≠ich sein. Vielle¬≠icht gibt es einen f√§hi¬≠gen Scrum Mas¬≠ter, der die Parteien dabei unter¬≠st√ľtzt, einen gang¬≠baren Weg zu find¬≠en.

Schadenanalyse

Sind sich PO, PL/Kunde und Dev-Team einig, kann der neg¬≠a¬≠tive Effekt von TD zumin¬≠d¬≠est abgemildert, manch¬≠mal sog¬≠ar beseit¬≠igt wer¬≠den. Jeden¬≠falls gilt es nun, beherzt zu han¬≠deln. Zun√§chst muss das Aus¬≠ma√ü der Tech¬≠nis¬≠chen Schulden umris¬≠sen wer¬≠den, damit die Aufw√§nde zu ihrer Behe¬≠bung einge¬≠plant wer¬≠den k√∂n¬≠nen. Nicht sel¬≠ten gibt es hier¬≠bei uner¬≠wartete Ergeb¬≠nisse: mehrere Wochen bis Monate an Kon¬≠so¬≠li¬≠dierungsar¬≠beit¬≠en sind f√ľr ein Pro¬≠jekt schw¬≠er zu verkraften. Mut, eine der f√ľnf agilen Tugen¬≠den, ist hier beson¬≠ders gefragt. In ein¬≠er solchen Lage m√ľssen wir uns fol¬≠gen¬≠des immer vor Augen hal¬≠ten: erstens haben wir diesen Zus¬≠tand selb¬≠st verur¬≠sacht, und zwar kollek¬≠tiv auf allen Ebe¬≠nen. Zweit¬≠ens, wenn wir den Mut jet¬≠zt nicht auf¬≠brin¬≠gen, den Zus¬≠tand zu verbessern, wird es sp√§ter noch h√§rter.

Coaching

Eben¬≠falls schwierig wird es, wenn die oben genan¬≠nten Con¬≠way-Gr√ľnde vor¬≠liegen. Dann haben wir es mit einem echt¬≠en H√§rte¬≠fall zu tun. Unter solchen Umst√§n¬≠den ist es beina¬≠he uner¬≠l√§sslich, einen Coach hinzuzuziehen, der F√ľhrung und Entwick¬≠lung miteinan¬≠der in Ein¬≠klang brin¬≠gen hil¬≠ft.

Vorsicht ist besser als Nachsicht: Technische Schulden einplanen

Um die Entste¬≠hung von TD m√∂glichst von vorn¬≠here¬≠in zu ver¬≠hin¬≠dern, gilt es, die dro¬≠hen¬≠den Schulden¬≠l√∂ch¬≠er rechtzeit¬≠ig zu erken¬≠nen. Ide¬≠al¬≠er¬≠weise pr√ľfen wir die beste¬≠hende Imple¬≠men¬≠tierung, bevor wir mit der Weit¬≠er¬≠en¬≠twick¬≠lung begin¬≠nen. Das schlie√üt auch die Makroar¬≠chitek¬≠tur mit der Kom¬≠mu¬≠nika¬≠tion zwis¬≠chen beteiligten Sys¬≠te¬≠men mit ein. In diesem Fall k√∂n¬≠nten die Refac¬≠tor¬≠ing-Aufw√§nde bere¬≠its in der Pla¬≠nung ber√ľck¬≠sichtigt wer¬≠den.

Ver¬≠s√§u¬≠men wir, eine Vor¬≠analyse durchzuf√ľhren oder ist es nicht m√∂glich, k√∂n¬≠nen wir immer noch w√§hrend der Entwick¬≠lung TDs iden¬≠ti¬≠fizieren. Nun ist zu pr√ľfen, wie wir damit umge¬≠hen wollen.

Die edel¬≠ste Option w√§re, die TDs sofort zu beheben und zu akzep¬≠tieren, dass sich der Pla¬≠nung¬≠shor¬≠i¬≠zont entsprechend nach hin¬≠ten ver¬≠schiebt. Das kann eine agile Pro¬≠jek¬≠tor¬≠gan¬≠i¬≠sa¬≠tion leicht verkraften. Im klas¬≠sis¬≠chen Man¬≠age¬≠men¬≠tum¬≠feld kann es jedoch passieren, dass wir damit aller¬≠gis¬≠che Reak¬≠tio¬≠nen aus¬≠l√∂sen. Hier w√§re ein Kom¬≠pro¬≠miss, die TD zun√§chst zu akzep¬≠tieren, um das Fea¬≠ture ‚Äď not¬≠falls mit Workarounds um die TD herum ‚Äď plan¬≠m√§√üig funk¬≠tion¬≠al fer¬≠tigzustellen. Nun m√ľssen wir sofort ein Tick¬≠et erstellen, um die TD anschlie√üend so schnell wie m√∂glich ein¬≠pla¬≠nen und aufl√∂sen zu k√∂n¬≠nen. Eine gute Release¬≠pla¬≠nung sollte diesen Fall auch in einem klas¬≠sis¬≠chen Umfeld abfed¬≠ern k√∂n¬≠nen.

Organisatorische Maßnahmen

Qualität mit einplanen

Organ¬≠isatorische Ma√ü¬≠nah¬≠men betr¬≠e¬≠f¬≠fen alle Ebe¬≠nen der Pro¬≠jek¬≠tor¬≠gan¬≠i¬≠sa¬≠tion. Am Ende jedoch l√§uft es darauf hin¬≠aus, dass die Pro¬≠jek¬≠tleitung f√ľr das Gelin¬≠gen oder Scheit¬≠ern Sorge tra¬≠gen muss. Die PL bes¬≠timmt ma√üge¬≠blich die Pro¬≠jek¬≠tkul¬≠tur, und damit auch, wie mit Her¬≠aus¬≠forderun¬≠gen umge¬≠gan¬≠gen wird, ger¬≠ade wenn sie Geld kosten. Nicht zulet¬≠zt bes¬≠timmt sie, welche Qual¬≠it√§ts¬≠ma√üst√§be anzule¬≠gen sind und wie die Sicherung der Soft¬≠ware¬≠qual¬≠it√§t erfol¬≠gen soll.

Project Staffing

Zun√§chst ein¬≠mal sollte unser Pro¬≠jekt mit f√§hi¬≠gen Men¬≠schen aus¬≠ges¬≠tat¬≠tet sein: wir ben√∂ti¬≠gen beispiel¬≠sweise ein Prod¬≠uct-Man¬≠age¬≠ment-Team und einen F√ľhrungsstab, die wis¬≠sen, wie Soft¬≠wa¬≠reen¬≠twick¬≠lung¬≠sprozesse funk¬≠tion¬≠ieren. Wir brauchen ein Devel¬≠op¬≠ment-Team, das auf dem Stand der Tech¬≠nik und bere¬≠it ist, sich stetig weit¬≠erzuen¬≠twick¬≠eln. Und wir soll¬≠ten einen Pro¬≠jek¬≠t¬≠coach engagieren, beispiel¬≠sweise einen Scrum Mas¬≠ter, der daf√ľr Sorge tr√§gt, dass die Organ¬≠i¬≠sa¬≠tion der Zusam¬≠me¬≠nar¬≠beit im Pro¬≠jekt rund l√§uft.

Wenn die Qual­ität­sziele gesteckt sind und das Pro­jekt gut gestafft ist, sind die Grund­la­gen geset­zt. Nun gibt es eine Rei­he von Tools, um die innere Qual­ität des Soft­ware­pro­duk­ts zu gewährleis­ten.

Architekturwissen vom Elfenbeinturm ins Entwicklerteam

Eines der wichtig­sten Werkzeuge ist die Fähigkeit des Entwick­lerteams, die Soft­ware mit Hil­fe ein­er zweck­mäßi­gen Makro- und Mikroar­chitek­tur gut zu struk­turi­eren. Dadurch wird die langfristige Wart­barkeit gewährleis­tet, und Tech­nis­che Schulden kön­nen leichter ver­mieden oder behoben wer­den.

Eine beliebte Falle ist hier¬≠bei, die Soft¬≠ware-Architek¬≠tur als eine eigene, von der Pro¬≠gram¬≠mier¬≠ar¬≠beit getren¬≠nte Diszi¬≠plin zu betra¬≠cht¬≠en. Es emp¬≠fiehlt sich jedoch vielmehr, daf√ľr zu sor¬≠gen, dass die Entwick¬≠ler √ľber pro¬≠fun¬≠des Architek¬≠tur¬≠wis¬≠sen ver¬≠f√ľ¬≠gen und dieses in ihrer t√§glichen Arbeit stetig anwen¬≠den. Mit der dazuge¬≠h√∂ri¬≠gen Diszi¬≠plin l√§sst sich dann die Architek¬≠turero¬≠sion in Gren¬≠zen hal¬≠ten.

Poka-Yoke-Entwicklungsprozess ‚Äď Fehler besser vorher vermeiden statt sp√§ter beheben

Um durch Unacht¬≠samkeit oder Toll¬≠patschigkeit entste¬≠hende Tech¬≠nis¬≠che Schuld von vorn¬≠here¬≠in zu ber√ľck¬≠sichti¬≠gen, emp¬≠fiehlt es sich, den Entwick¬≠lung¬≠sprozess so zu gestal¬≠ten, dass alleine dadurch die Entste¬≠hung von TD bere¬≠its eingeschr√§nkt wird. Dieses Vorge¬≠hen ist als Poka Yoke bekan¬≠nt. Beispiel¬≠sweise imple¬≠men¬≠tieren wir Domain Dri¬≠ven Design als fes¬≠ten Bestandteil des Prozess¬≠es. Dadurch wird sichergestellt, dass √Ąnderun¬≠gen in der Fach¬≠dom√§ne ad√§quat in der Soft¬≠ware abge¬≠bildet wer¬≠den. Als n√§ch¬≠stes sollte Clean Code gelebt wer¬≠den. Dadurch min¬≠imiert sich das Aufnehmen von Tech¬≠nis¬≠chen Schulden von selb¬≠st. F√ľr den pas¬≠sion¬≠ierten Clean Coder geh√∂rt kon¬≠tinuier¬≠lich¬≠es Refac¬≠tor¬≠ing zu den Stan¬≠dard¬≠mit¬≠teln, um ger¬≠ade auch die Tech¬≠nis¬≠chen Schulden klein zu hal¬≠ten. Eben¬≠so sind effek¬≠tiv durchge¬≠f√ľhrte Codere¬≠views ein fes¬≠ter Bestandteil der Clean-Code-Prax¬≠is.

SonarQube f√ľr statische Codeanalyse nach der SQALE-Methode

Als tech­nis­ches Tool hat sich in vie­len Pro­jek­ten Sonar­Qube etabliert, das in die Build-Pipeline inte­gri­ert wer­den kann, um mit Hil­fe von sta­tis­ch­er Code­analyse unter anderem das Aus­maß an TD zu bemessen. Dabei wird der Grad der Tech­nis­chen Schuld in Man­nta­gen bez­if­fert.

Allerd¬≠ings d√ľr¬≠fen wir uns nicht dar√ľber hin¬≠wegt√§uschen lassen, dass Sonar¬≠Qube seman¬≠tis¬≠che Kri¬≠te¬≠rien wie Les¬≠barkeit und Ver¬≠st√§ndlichkeit des Source¬≠codes nicht messen kann. Wichtige Design¬≠prinzip¬≠i¬≠en wie das Sin¬≠gle Respon¬≠si¬≠bil¬≠i¬≠ty Prin¬≠ci¬≠ple sind eben¬≠falls schw¬≠er automa¬≠tisiert zu pr√ľfen. Daher ist Sonar¬≠Qube zwar eine gute Unter¬≠st√ľtzung, sollte jedoch keines¬≠falls als alleinige Quelle der Wahrheit dienen.

Fazit

Fassen wir zusam­men:

  • Tech¬≠nis¬≠che Schuld entste¬≠ht laufend w√§hrend der Entwick¬≠lung. Das ist nat√ľr¬≠lich und ganz nor¬≠mal.
  • Obwohl TD als Buzz¬≠word in der Soft¬≠wareszene hin¬≠l√§nglich bekan¬≠nt ist, find¬≠en ihre Ursachen und Auswirkun¬≠gen wenig Beach¬≠tung. Allzu oft wird sie ignori¬≠ert.
  • Die besten Pro¬≠gram¬≠mier¬≠er und Architek¬≠ten k√∂n¬≠nen Tech¬≠nis¬≠che Schulden nicht abwen¬≠den, wenn der Entwick¬≠lung¬≠sprozess und/oder die Unternehmen¬≠skul¬≠tur wirk¬≠same Ma√ü¬≠nah¬≠men kon¬≠terkari¬≠eren.
  • Ein gro√üer Anteil an TD l√§sst sich bere¬≠its durch rein organ¬≠isatorische Ma√ü¬≠nah¬≠men unterbinden. Neben ein¬≠er f√§hi¬≠gen Pro¬≠jek¬≠t¬≠mannschaft m√ľssen somit auch kul¬≠turelle und prozes¬≠suale Voraus¬≠set¬≠zun¬≠gen geschaf¬≠fen wer¬≠den.
  • Soft¬≠ware¬≠pro¬≠jek¬≠t¬≠coach¬≠ing ist ein pro¬≠bates Mit¬≠tel, um die Ver¬≠schul¬≠dung von Anfang an klein zu hal¬≠ten, oder ein Soft¬≠ware¬≠pro¬≠jekt aus der TD-Sack¬≠gasse her¬≠auszuf√ľhren.

In diesem Sinne, hap¬≠py engi¬≠neer¬≠ing ūüôā

Wikipedia: Tech­nis­che Schulden