Sustainable Service Design

Nachhaltige Softwareservices – Teil 1: Grundlagen

Wolfgang Pleus

© Shutterstock/Juliann

Nachhaltigkeit ist ein wichtiges Thema in vielen Bereichen unseres täglichen Lebens. In der durch ständige Innovationen getriebenen Softwarebranche wird Nachhaltigkeit bisher jedoch wenig Beachtung geschenkt. Diese Artikelreihe beschreibt einen Ansatz für das Design und die Implementierung nachhaltiger Softwareservices. Während sich der erste Teil mit den Grundlagen beschäftigt, widmet sich der zweite Teil der konkreten Implementierung nachhaltiger Services.

Warum Nachhaltigkeit? Nachhaltigkeit ist ein wichtiges Thema in vielen Bereichen unseres täglichen Lebens. In der durch ständige Innovationen getriebenen Softwarebranche wird Nachhaltigkeit jedoch wenig Beachtung geschenkt. Die Folgen sind oft Verschwendung und Ineffizienz. Für Entwickler hat das Thema nachhaltiger Software eine eher untergeordnete Bedeutung, da ihre Ziele primär darin bestehen, die unmittelbaren Anforderungen mit dem gegebenen Technologiestack zu realisieren und produktiv bereitzustellen. Für den Geschäftsführer eines Unternehmens hat das Thema dagegen eine hohe Relevanz, da es im Interesse eines jeden Unternehmens liegt, effizient zu wirtschaften und Investitionen so zu tätigen, dass sie möglichst langfristigen Nutzen generieren. Da Softwareentwicklung einerseits den Unternehmenserfolg positiv beeinflussen kann und andererseits auch von ihm abhängig ist, empfiehlt es sich, Software so zu gestalten, dass sie sich an den längerfristigen Unternehmenszielen orientiert – so kann geschäftsnahe Softwareentwicklung funktionieren. Als Entwickler sollten wir uns also folgende Frage stellen: Wie können wir auch dann stabile und evolvierbare Software ermöglichen, wenn sich unsere aktuelle technische Umgebung ändert?

Was bedeutet Nachhaltigkeit?

Unter Nachhaltigkeit (Sustainability) versteht man Handlungsprinzipien, die gelten, um bestehende Ressourcen zu wahren und weiterzuentwickeln. Stabilität und Evolvierbarkeit stehen dabei im Vordergrund. So können wir beispielsweise zwischen günstig hergestellten „Wegwerfprodukten“ und hochwertigen Qualitätsprodukten wählen. Wir können uns dafür entscheiden, alle paar Jahre einen trendigen neuen Tisch bei einem schwedischen Möbelhaus zu kaufen. Alternativ könnten wir einen individuellen Massivholztisch beim Möbeltischler beauftragen. Der Massivholztisch hält vielleicht ein ganzes Leben lang. Er kann immer wieder geschliffen und erneuert werden. Wenn er modischen Ansprüchen nicht mehr genügt, so kann der verwendete Rohstoff in ein neues Möbelstück umgearbeitet werden. Am Ende der Lebensdauer dürfte der Massivholztisch die nachhaltigere Option gewesen sein, da sie in der Summe weniger Ressourcen wie Rohstoffe, Energie und Arbeit erforderte.

Wenn wir die Idee der Nachhaltigkeit auf die Herstellung von Software übertragen, stellen wir fest, dass dieser Aspekt in den meisten Projekten ein eher unwichtiges Ziel darstellt. Das ist eigenartig, denn schließlich haben Unternehmen doch ein großes Interesse an Effizienz und Investitionsschutz, also daran, ein maximales Ergebnis mit minimalem Einsatz zu erreichen.

Stattdessen wird das Rad immer wieder neu erfunden. Software wird oftmals nach einigen Jahren weggeworfen und neu implementiert. In solchen Fällen wird mit neuen Technologien und schlechter Wartbarkeit historisch gewachsener Software argumentiert.

Sicher ist die Feststellung richtig, dass Software sich naturgemäß oft ändert, da das Tempo technischer Innovationen hoch ist. Wenn man sich jedoch die implementierten Konzepte und Geschäftslogiken anschaut, stellt man fest, dass es hier weit weniger dynamisch zugeht. Unternehmen, wie beispielsweise Banken und Versicherungen, verwenden über lange Zeiträume spezifische Datenstrukturen und Geschäftslogik. Dynamische Aspekte sind eher in den Prozessen und Regeln zu finden. In einem solchen Kontext kann ein nachhaltiger Serviceentwicklungsansatz zu mehr Effizienz führen.

Ein Service kann dann als nachhaltig betrachtet werden, wenn er sich heute und zukünftig in möglichst vielen fachlichen und technischen Kontexten verwenden lässt. Natürlich lässt sich die Zukunft nicht voraussehen, jedoch ist es möglich, Serviceimplementierungen so anzulegen, dass sie auf Änderungen besser reagieren können. Darum geht es beim nachhaltigen Service Design oder auch Sustainable Service Design (SSD).

SOA und Wiederverwendbarkeit

Die Serviceorientierung stellt einen anerkannten Ansatz dar, um das Ziel der Wiederverwendung von Softwareartefakten zu erreichen. Allerdings werden die Begriffe „Service“ und „SOA“ oft inflationär eingesetzt. Es gibt keine verbindliche Definition dafür, was ein „Service“ ist. Insbesondere Softwareentwickler neigen dazu, Services über die eingesetzte Technologie zu definieren. Gängige Kandidaten sind beispielweise Web Services, REST-Services oder OSGi-Services. Diese Sichtweise ist der Idee eines Service als universellem Softwarebaustein nicht angemessen. Die technische Wiederverwendbarkeit wird so auf die jeweilige Implementierungstechnologie eingeschränkt. Ein solcher Service mag fachlich wiederverwendbar sein, technisch ist er es nur in der jeweiligen technischen Umgebung. Sustainable Service Design verfolgt das Ziel, die technische Wiederverwendbarkeit von Services zu erhöhen. So kann er potenziell in verschiedenen technischen Umgebungen, wie beispielsweise Java EE, OSGi oder „plain“ Java, im Kontext unterschiedlicher Geschäftsprozesse betrieben werden.

Fachliche Wiederverwendbarkeit ist in hohem Maße abhängig von der Ausgestaltung des Servicekontrakts. Insbesondere die Abstraktion ist ein wichtiges Mittel, um einen Service in unterschiedlichen fachlichen Kontexten nutzbar zu machen (Kasten: „Zehn Regeln für nachhaltige Servicekontrakte“). Sustainable Service Design folgt einem konsequenten Contract-First-Ansatz. Der Kontrakt stellt ein zentrales Artefakt dar, das sowohl in technische (Java) als auch fachliche Repräsentationen (HTML) transformiert werden kann. Somit steht es allen am Service Design Beteiligten gleichermaßen zur Verfügung und unterstützt so die Erstellung von Services mit hohem fachlichem Wiederverwendungsgrad.

Sustainable Service Design

Nachhaltiges Service Design oder auch Sustainable Service Design (SSD) ist ein Design- und Entwicklungsansatz für Softwareservices, der sich in verschiedenen geschäftskritischen Java-EE- und .NET-Projekten in den Branchen Versicherungen, Banken und öffentliche Verwaltung bewährt hat. SSD vereint viele Best Practices der Serviceorientierung in einem konkreten, praktischen Ansatz.

Entstanden ist SSD in der Praxis. Insbesondere in zeitintensiven Projekten können sich die technischen Rahmenbedingungen ändern. So wechseln Laufzeitumgebungen von OSGi nach Java EE, Frameworks von Axis nach CXF oder Protokolle von SOAP nach JSON und manchmal sogar Plattformen von .NET zu Java EE (oder anders herum). Dies kann insbesondere im Bereich der Serviceorientierung problematisch werden, da Services idealerweise eher auf langfristige Wiederverwendbarkeit ausgerichtet sind. Die Ursache liegt in der zu engen Kopplung der fachlichen Funktionalität mit den jeweiligen Technologien.

SSD strebt weitestgehend eine Entkopplung der Serviceimplementierung von den eingesetzten Technologien an und ist durch Ideen der Hexagonal Architecture von Alistair Cockburn und Service Component Architecture (SCA) inspiriert.

SSD bedarf keiner schwergewichtigen Produkte oder Laufzeitumgebungen. Es orientiert sich an robusten und offenen Standards und kann mit gängigen Plattformen wie Java EE und .NET realisiert werden. Es kann im Rahmen einer SOA und auch zur Implementierung von Microservices eingesetzt werden.

SSD und Microservices
Die zentralen Ideen von Microservices [3] sind Modularisierung und Isolation. Durch die Modularisierung kann die Komplexität einzelner Services reduziert werden. Durch die Isolation werden Seiteneffekte vermieden, wie sie durch den Betrieb mehrerer Services in einer Laufzeitumgebung auftreten können. Klare personelle Serviceverantwortlichkeiten können ebenfalls die Komplexität reduzieren. Ein Microservice kann seine eigene Laufzeitumgebung enthalten, um so möglichst autonom zu werden. Beispielsweise Spring Boot oder OSGi-Container wie Apache Karaf sind gute Beispiele. Vorstellbar sind aber auch leichtgewichtige Java-EE-Server wie JBoss WildFly. Modularisierung kann die Testbarkeit verbessern. Zu bedenken ist allerdings, dass Services immer in einem Verbund mit anderen Services und Konsumenten eingesetzt werden. Die Komplexität des gesamten Systems können auch Microservices kaum reduzieren. Ein Microservice-Ansatz kann durch SSD ergänzt werden. So können auch Microservices von einem nachhaltigen Entwicklungsansatz profitieren. Diese sollen zwar im Zweifel einfach neu implementiert werden können, was aber bei komplexen fachlichen Zusammenhängen, wie beispielsweise dem Tarifrechner einer Versicherung, sicher kaum einen praktikablen Weg darstellt. Zu den Implementierungsaufwänden kommen noch erhebliche Aufwände für den Test. Wiederverwendung und Weiterentwicklung von Services sind einer Neuentwicklung in solchen Fällen vorzuziehen. SSD kann durch technische Entkopplung, Modularität und technologeineutrale Kontrakte die Voraussetzungen dafür schaffen.

Technische Entkopplung

SSD zielt auf eine maximale technologische Unabhängigkeit einer Serviceimplementierung ab. Das klingt seltsam, da wir uns als Entwickler naturgemäß im Bereich der Technologien bewegen. Hier hilft eine Differenzierung weiter: Es gibt universelle und langfristig als stabil anzusehende Basistechnologien, wie beispielsweise die XML-Standards oder die Sprache Java. Eine nachhaltige Serviceimplementierung setzt auf diese Basistechnologien. Andere Technologien und Standards ändern sich häufiger und sind manchmal modischen Trends unterworfen. Technologien wie REST, EJB, JMS oder SOAP werden in Form modularer Bindungen realisiert und so von der zentralen Serviceimplementierung entkoppelt. Die Konsequenz daraus ist, dass eine SSD-Implementierung keine spezifische Technologie voraussetzt und, falls erforderlich, um neue Technologien erweitert werden kann. Durch die Modularisierung wird die Möglichkeit einer bedarfsgerechten Integration, Evolvierbarkeit und technischer Wiederverwendung geschaffen.

SSD-Prinzipien

Sustainable Service Design umfasst verschiedene Prinzipien, die alle das Ziel verfolgen, die technologische Abhängigkeit eines Service zu vermindern. Abbildung 1 zeigt wesentliche Aspekte in der Übersicht.

Abb. 1: Sustainable Service Design

Abb. 1: Sustainable Service Design

Prinzip 1: Technologieneutrale Servicedefinition

SSD versteht einen Service als technologieneutrales Artefakt und verwendet die folgende Definition:

Ein Service repräsentiert ein potenziell wiederverwendbares Konzept einer Anwendungsdomäne.

Bei dieser Definition fällt auf, dass sie keinerlei technischen Bezug hat. Somit ist eine Webserviceimplementierung nicht automatisch ein Service, nur weil sie mittels SOAP kommuniziert oder den Service im Namen trägt. Servicekandidaten werden vom Team im Rahmen eines Gremiums, beispielsweise einer SOA-Arbeitsgruppe, spezifisch für die Anwendungsdomäne ermittelt und beschrieben. Dies ist ein bewusster Vorgang, mit der Zielsetzung, die Konsistenz der Servicelandschaft zu gewährleisten. Erst nachdem ein Servicekandidat benannt ist, stellt sich die Frage nach einer geeigneten Implementierung.

Prinzip 2: Einheitlicher Request/Response

Services kommunizieren grundsätzlich durch den Austausch von Nachrichten. Sie erhalten eine Anfrage (Request) und senden eine Antwort (Response). Die Datenformate der Nachrichten können je nach Protokoll variieren. Beim SSD wird die Serviceimplementierung in Form eines POJOs bereitgestellt. Unterschiedliche Aufrufprotokolle werden über Bindungen hinzugefügt. Um eine einheitliche Aufrufschnittstelle über alle Bindungen zu erreichen, verwenden das POJO und alle Bindungen dieselben, einheitlichen Request-/Response-Nachrichten. Request und Response werden im Kontrakt via XML Schema (XSD) definiert und dienen als Basis für die Codegenerierung. Abbildung 2 zeigt eine grafische Darstellung eines einfachen Request-/Response-Paares aus einer XSD-Datei für die Operation Calculator.PerformSimpleCalculation.

Abb. 2: Unified Request/Response

Abb. 2: Unified Request/Response

Um das Prinzip besser verdeutlichen zu können, folgt dieser Request noch nicht allen SSD-Regeln. Der Request für die Operation PerformSimpleCalculation enthält die auszuführende Berechnung (operation), sowie die Werte value-a und value-b. Die Response enthält das Ergebnis der Berechnung (result). Selbst wenn der Service in Request oder Response nur einen Parameter erfordern sollte, wird dieser in einer Nachricht gekapselt. Es werden immer das Prä- bzw. Suffix Request und Response verwendet. Obwohl technisch nicht erforderlich entsteht dadurch eine Einheitlichkeit der Darstellung über alle Serviceschnittstellen. Die Nachrichten können auch komplexe Datentypen enthalten. XML Schema ist sehr leistungsfähig und erlaubt die Modellierung von Vererbungsbeziehungen oder Enumerationen.

Prinzip 3: Konsequent Contract First

Der Servicekontrakt stellt die Schnittstellenbeschreibung eines Service dar und bestimmt somit die Art, in der Servicekonsumenten mit dem Service interagieren. Der Kontrakt ist das wichtigste Artefakt eines Service. Durch die explizite Kodierung behält der Entwickler zu jeder Zeit die Kontrolle, auch bei einem Framework- oder Technologiewechsel. Der Kontrakt erhält die nötige Aufmerksamkeit während des Entwicklungsprozesses. Er ist autonom von der eingesetzten Entwicklungstechnologie und somit unabhängig von Technologiezyklen. Der Begriff „Contract First“ wurde im Umfeld von SOAP Web Services geprägt. Hierbei stellt die WSDL-Datei den Kontrakt dar. SSD betrachtet solche bindungsspezifischen Kontrakte als Sekundärkontrakte. Der SSD-Primärkontrakt wird in einer oder mehreren XML-Schema-Dateien (XSD) definiert und enthält alle Datenstrukturen und Nachrichten des Servicemodells. Ein XSD-basierter Kontrakt bietet viele Vorteile, denn XML Schema ist als langfristig stabil anzusehen. Als plattformunabhängiger OASIS-Standard kann daraus Quellcode für alle wichtigen Plattformen generiert werden. Somit ist XML Schema hochgradig portabel und wiederverwendbar. Dies stellt eine unabdingbare Voraussetzung zur Schaffung stabiler Branchenstandards wie beispielsweise der BiPRO-Normen in der Versicherungswirtschaft dar [7]. XML Schema kann vollständig und standardkonform dokumentiert werden. Durch eine XSLT-Transformation kann daraus lesbare Dokumentation generiert werden. So entsteht eine redundanzfreie Schnittstellendefinition, die technisch und fachlich verstanden werden kann. Durch die Integration in die Sekundärkontrakte, wie beispielsweise WSDL oder WADL, ergibt sich ein hoher Grad der Wiederverwendbarkeit. Alle einfachen und komplexen Datentypen sind automatisch portabel. XSD eignet sich hervorragend für die Beschreibung von Nachrichten und Datentypen, nicht aber für die Beschreibung von Operationen. Daher werden diese in Form eines Java-Interface beschrieben. Das Interface zu den in Abbildung 2 gezeigten Nachrichten sieht wie folgt aus:

public interface Calculator{
  public PerformSimpleCalculationResponse 
  performSimpleCalculation(PerformSimpleCalculationsRequest request);
}

Die für die Bindungen erforderlichen Java-Klassen der Nachrichten werden durch JAXB und entsprechende Maven-Plug-ins vollständig generiert. Es fehlen noch Metainformationen wie beispielsweise Ansprechpartner, Klassifizierung und Qualitätsmerkmale. Diese werden in einer proprietären XML-Datei als Teil des Service-API beschrieben. Listing 1 zeigt einen Auszug.

<?xml version="1.0" encoding="UTF-8"?>
<servicedescriptor xmlns="http://www.pleus.net/servicedescriptor/1.0" 
                   xmlns:tns="http://www.pleus.net/servicedescriptor/1.0">
  <general>	
    <id>calculator</id>
    <display-name>Calculator Service</display-name>
    <purpose>This is a simple calculator</purpose>
    <version>1.0</version>
    <status>draft</status>
    <active-since>2014-01-01</active-since>
    <active-until>9999-12-31</active-until>
    <contacts>
      <contact>
        <name>Wolfgang Pleus</name>
        <email>wolfgang.pleus@pleus.net</email>
      </contact>
    </contacts>
  </general>
  <classifications>...</classifications>
  <clients>...</clients>
  <operations>...</operations>
  <bindings stage="development">...</bindings>
  <bindings stage="test">...</bindings>
  <quality-of-service>
    <operation name-ref="PerformSimpleCalculation">
      <property name="responsetime">...</property>
      <property name="supports-transaction">...</property>
      <property name="security">...</property>
    </operation>
  </quality-of-service>
</servicedescriptor>

XSD/Java-API und Service Descriptor stellen zusammen den Primärkontrakt des Service dar. Bindungsspezifische Sekundärkontrakte wie WSDL- oder WADL-Dateien enthalten die XSD-Dateien und werden so auf ein Minimum reduziert. Abbildung 3 verdeutlicht den Zusammenhang.

Abb. 3: Contract First

Abb. 3: Contract First

Durch XSLT-Transformationen wird der Kontrakt während des Build-Prozesses automatisch in eine lesbare Dokumentation transformiert und in ein Repository überführt. Abbildung 4 zeigt diesen Vorgang beispielhaft. Durch diesen redundanzfreien Ansatz wird eine effiziente Zusammenarbeit zwischen Fach- und IT-Spezialisten gefördert und die Wiederverwendung gestärkt.

Abb. 4: Generierte Dokumentation

Abb. 4: Generierte Dokumentation

Prinzip 4: Bindungen

Bindungen bestimmen, über welche Protokolle ein Service mit seinen Konsumenten kommuniziert. Durch die Trennung der Service- und Protokollimplementierung wird die Technologieabhängigkeit auf ein Minimum reduziert. Gleichzeitig wird die technische Wiederverwendbarkeit maximiert, da ein Service durch eine Bindung in verschiedene technische Umgebungen integriert werden kann. Bindungen weisen eine hohe Technologieabhängigkeit auf und können dem Service bei Bedarf hinzugefügt werden. Eine Serviceimplementierung ist unabhängig von seinen Bindungen. Unterschiedliche Bindungen können über entgegengesetzte Qualitätsmerkmale, beispielsweise in Bezug auf Performanz oder Interoperabilität, verfügen. Durch den Bindungsansatz kann ein Service die Anforderungen unterschiedlicher Konsumenten erfüllen. Typische Bindungen sind SOAP/HTTP, JSON/HTTP, EJB/RMI-IIOP, XML/JMS, aber auch Native Java. In einer klassischen SOA übernimmt ein Enterprise Service Bus die Bereitstellung von Services über verschiedene Protokolle. Durch SSD-Bindungen kann dies ohne zusätzliche Infrastruktur erreicht werden. Allerdings ersetzt SSD nicht den ESB, der noch weitere Merkmale wie Lokationstransparenz, Routing, Transformation etc. aufweist. Die Realisierung der Bindungen reduziert sich auf ein Minimum, da sie eingehende Anfragen lediglich an die Serviceimplementierung delegieren.

Zehn Regeln für nachhaltige Servicekontrakte
Nicht selten werden Schnittstellen sehr konkret auf ein spezifisches Einsatzszenario hin entworfen. Dies verhindert eine weitgehende Wiederverwendung und führt zu einer Serviceproliferation, also vielen sehr spezifischen Services. Die Folge daraus sind Redundanzen und erschwerte Wartbarkeit. Daher stellt sich die Frage, wie eine Schnittstelle beschaffen sein muss, damit der Service möglichst gut wiederverwendet werden kann. Die folgenden Regeln können dabei helfen:

1. Konzept: Ein Service sollte ein leicht verständliches Konzept repräsentieren. Einfach zu verstehende Konzepte können leichter wiederverwendet werden, da deren Sinn und Semantik intuitiv erfassbar sind.
2. Wiederverwendbarkeit: Ein Service sollte potenziell wiederverwendbar sein. Es empfiehlt sich zu prüfen, in welchen Kontexten der Service zum Einsatz kommen kann. Nur Konzepte mit einem Potenzial zur Wiederverwendung sollten als Service betrachtet werden.
3. Abstraktion: Ein Service sollte eine angemessene Abstraktion aufweisen. Er sollte ein erhöhtes Abstraktionsniveau haben, das Wiederverwendung zulässt. Anstelle von Kundendaten könnte ein Service beispielsweise Personendaten verarbeiten und so weitere Rollen unterstützen.
4. Mengenoperationen: Ein Service sollte Mengenoperationen unterstützen. Anstatt beispielsweise die Operation ReadPerson sollte der Service die Operation ReadPersons anbieten. Der Einzelfall ist eine Ausprägung der Mengenoperation. Dadurch wird etwa ein Einsatz in Batchszenarien ermöglicht.
5. Kompensation: Ein Service sollte Kompensation unterstützen. Eine durchgeführte Aktion muss rückgängig gemacht werden können. Wenn der Service beispielsweise eine Create-Methode anbietet, sollte er auch eine Delete-Methode anbieten. Dadurch wird der Einsatz beispielsweise in BPM-Szenarien ermöglicht, in denen Kompensation der zentrale Mechanismus zur Transaktionssteuerung ist.
6. Korrelation: Ein Service sollte Korrelation unterstützen. Insbesondere bei asynchronen Serviceaufrufen muss der Aufrufer in der Lage sein, eine Response einem Request zuzuordnen. Dazu können Informationen verwendet werden, die in Request und Response enthalten und eindeutig sind. Um die Verwendung eines Service in asynchronen Szenarien zu gewährleisten, sollte der Servicekontrakt eine solche Information enthalten.
7. Auskunftsfähigkeit: Ein Service sollte auskunftsfähig bezüglich der verwalteten Daten sein. Falls ein Service beispielsweise eine Anredeliste für Personen verwendet, sollte der Service diese Liste anbieten. Idealerweise kann ein Service autonom, ohne die Verwendung weiterer Services, verwendet werden.
8. Klassifizierung: Ein Service sollte fachlich und technisch klassifiziert sein. Dabei sollte die Servicegranularität konsistent in Bezug auf die Klassifizierung sein. Eine Klassifizierung dient der Auffindbarkeit und somit der Wiederverwendbarkeit. Typische Klassifizierung sind Applikation, Prozess, Domain oder branchenspezifische Klassifizierungen wie BIAN (Banken) oder VAA (Versicherungen).
9. Dokumentation: Ein Service sollte einen vollständig dokumentierten Kontrakt aufweisen. Die Sprache der Dokumentation sollte dem Zielkontext entsprechen. Eine englische Dokumentation erhöht die Reichweite, kann aber die Verständlichkeit in nicht englischsprachigen Kontexten beeinträchtigen.
10. Metainformationen: Ein Service sollte vollständige Metainformationen bereitstellen. Dazu gehören WSDL- und WADL-Dateien für SOAP- und REST-Bindungen, aber auch nicht unmittelbar technische Informationen wie Ansprechpartner oder Qualitätsmerkmale.

Fazit

Nachhaltige Serviceentwicklung kann dabei helfen, die Lebensdauer von Serviceimplementierungen zu verlängern und so die Wirtschaftlichkeit zu erhöhen.

Sustainable Service Design stellt einen praxiserprobten Design- und Implementierungsansatz für die Erstellung nachhaltiger Softwareservices dar. Als solcher erfordert er keine spezifische Laufzeitumgebung. Der erste Teil dieser Reihe beschreibt die Grundsätze und Prinzipien eines nachhaltigen Service Designs. Der zweite Teil widmet sich der konkreten, exemplarischen Implementierung mit Java EE.

Aufmacherbild: Tree shaped like the world map von Shutterstock / Urheberrecht: Juliann

Geschrieben von
Wolfgang Pleus
Wolfgang Pleus
Wolfgang Pleus arbeitet als freier Technologieberater, Autor und Trainer im Bereich moderner Softwarearchitekturen. Seit zwanzig Jahren unterstützt er internationale Unternehmen bei der Realisierung komplexer Geschäftslösungen auf der Basis von Java EE und .NET. Seine Schwerpunkte liegen in den Bereichen SOA, BPM und Agile.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: