Clean ist ein zentraler Begriff in der Software-Entwicklung. Clean soll der Code sein, um damit die Verständlichkeit von Methoden und Klassen zu verbessern. Auch mit der Clean-Architecture steht der Mensch im Mittelpunkt: Der Maschine ist unsere Architektur egal – wir schreiben Programme, damit der Mensch sie versteht! Der Name Clean-Architecture verspricht eine einfach zu verstehende Architektur. Auch wenn Clean-Architektur als Screaming Architecture [3] bezeichnet wird, ist es mir gelungen, diesen Schrei über Monate zu überhören – ein guter Grund für eine Kurzeinführung zur Clean-Architecture am Beispiel eines simplen REST-Services [1]. Sie werden feststellen, dass bei dem Wust von Interfaces und Klassen eine Anleitung hilfreich ist, um die Clean-Architecture zu lesen.
Am Anfang war der Use-Case
Spätestens dann, wenn eine Software gewartet werden soll, stellt der/die Entwickler:in die Frage nach den Funktionen der Software: Was macht die Software eigentlich? Wozu sind die ganzen Pakete da? Fragen, die im klassischen Software-Engineering durch die Dokumentation von Use-Cases und die Beschreibung der Software-Architektur beantwortet werden – nur wer schreibt in der agilen Entwicklungs-Realität solche Dokumentationen? In der Clean-Architecture finden Sie die Use-Case-Beschreibung in Code gegossen.
Für die Beschreibung der Funktionalität sind die Pakete Port.In und Domain-Service wichtig (s. Abbildung 1). Wenn Sie also wissen wollen, was die Anwendung tut, finden Sie in Port.In einen ersten Einblick: Diese Interfaces beschreiben, wie die Use-Cases der Anwendung aufgerufen werden. Das könnte ein erster Schritt in der Entwicklung sein: Sie schreiben in den Interfaces die Use-Cases auf, die die Anwendung umsetzen soll. Sicher dokumentieren Sie in diesen Interfaces auch das Verhalten – oder verweisen auf entsprechende Dokumentationen😊. Schreiend wird die Architektur auch dadurch, dass Sie entsprechende Namen für die Interfaces verwenden: CreateSeminarUseCase oder CreateTrainerUseCase legen nahe, dass diese Anwendung Seminare und Trainer erzeugen kann.
Über das Paket Port.In erfahren Sie, was die Anwendung tun soll. Bei der Wartung ist die nächste Frage, wie werden die Use-Cases umgesetzt? Die Antwort zu dieser Frage finden Sie im Paket Domain-Service in Form der Klassen CreateSeminarService und CreateTrainerService. Die Aufgabe dieser Klassen ist es, den Use-Case so zu implementieren, dass daraus die Fachlichkeit direkt ablesbar wird.
Listing 1: CreateSeminarService – Service Klasse als Use-Case-Beschreibung
Die Klasse CreateSeminarService (Listing 1) ist leicht verständlich: Der Use-Case erstellt ein Seminar-Objekt und speichert es. Technische Details kommen in der Implementierung nicht vor. Für die technische Umsetzung sorgen die Implementierungen der Port.Out-Interfaces.
Es werden die Adapter
Die einfache Verständlichkeit der Service-Klassen des Pakets Domain-Service wird dadurch möglich, dass die Service-Klassen die technische Implementierung delegieren: Dazu nutzen sie Interfaces, die als Port bezeichnet werden. In dem Beispiel (Listing 1) wird die Funktionalität des Abspeicherns über das Interface StoreSeminarPort des Pakets Port.Out ausgeführt. Die Implementierungen der Port.Out-Interfaces übernehmen die Klassen des Pakets Adapter.Out (s. Abbildung 2).
Oben in Abbildung 2 ist das Paket Adapter.In zu sehen: Dieses Paket implementiert technische Schnittstellen, die die Use-Cases aufrufen. In dem Beispiel ist die technische Eingangsschnittstelle ein REST-Service: Die Anwendung bietet REST-Services an, um Seminare oder Trainer anzulegen.
Fazit
Sie wissen nun, wie Sie eine Clean-Architecture lesen. Sie finden in dem Port.In-Paket eine Auflistung der Use-Cases der Anwendung. Das Paket Domain-Service erzählt Ihnen, wie die Use-Cases umgesetzt werden. Die Adapter geben Auskunft über die technischen Details der Anwendung.
Kommen wir zum Kleingedruckten der Clean-Architecture. Die Paket-Namen für Port.In und Port.Out erkennen Sie leicht. Sie heißen dann port.in oder port.out. Domain-Services finden Sie beispielsweise unter domain.services oder aber unter application.services. In den Paketen Port.In und Port.Out finden Sie auch Data-Transfer-Objekte wie Seminar und Trainer. Solche Domain-Objekte können Sie aber auch in einem Paket domain.model zusammenfassen.
Eine Schritt-für-Schritt-Anleitung zur Implementierung einer Spring-Boot-Anwendung in einer Clean-Architecture finden Sie in Quelle [1]. Hintergrundwissen finden Sie in der Bibel zur Clean-Architecture [2]. Let us do it clean!
Quellen
[1]: Source-Code in GitLab:https://gitlab.com/sk_at_ordix/cleanarchitecture – Entwicklungsschritte sind als Branches abgelegt.
[2]: Get Your Hands Dirty on Clean Architecture: Build 'clean' applications with code examples in Java, 2nd Edition, Tom Hombergs
[3]: Robert C. Martin: Clean Architecture: A Craftsman's Guide to Software Structure and Design, 2017
Entdecken Sie unser Seminarangebot
ZUM SEMINARSHOP
Mehr erfahren