Kapitel 2. Die Architektur von Zend-Framework-Anwendungen

Inhaltsverzeichnis

2.1. Einleitung
2.2. Das Model-View-Controller-Prinzip
2.2.1. Die View
2.2.2. Der Controller
2.2.3. Das Model
2.3. Im Rückblick
2.4. Fazit

2.1. Einleitung

Ich habe im Laufe der Jahre mit vielen Entwicklern gesprochen: ihre größte Sorge beim Einsatz eines (neuen) Web-Application-Frameworks ist, ob sie die Architektur dieser Frameworks verstehen (werden). Nahezu alle Web-Application-Frameworks haben eine Architektur übernommen, die erstmals 1979 von Trygve Reenskaug beschrieben wurde und als Model-View-Controller (MVC) bekannt ist. Das Konzept mag alt sein, aber wie man sieht, erlebt es als Ansatz für Webanwendungen seinen zweiten Frühling und scheint hier besser zu passen, als als es bei Desktopanwendungen je der Fall war.

In der PHP-Community gibt es rund um MVC viele Missverständnisse. Viele Entwickler sehen es als übermäßig komplex, schwer zu verstehen und den Aufwand nicht wert an. Dieselben Menschen bezeichnen Frameworks, die MVC verwenden, häufig als zeitraubend, performance-lastig und mit unnötigen Funktionen und unnötigem Quelltext aufgebläht. Ich verstehe diese Meinung, aber sie ist nicht so ganz korrekt, denn MVC ist eigentlich ein ziemlich simples Konzept. Tatsächlich wird es inzwischen als einer der Eckpfeiler für das angesehen, was Web-Application-Frameworks so populär gemacht hat.

Da es nahezu unmöglich ist, das Zend Framework ohne ein korrekte Auffassung von MVC verstehen zu können, muss dieses Konzept vorab erklärt werden. Dieses Kapitel sollten Sie nicht überspringen! Der erste wichtige Punkt ist, dass MVC keine spezifische Implementierung ist, sondern ein eher locker definiertes Verhaltensmuster, dessen Implementierung entsprechend den Zielen des Frameworks, der Anwendung und der verwendeten Programmiersprache variiert. Dieses Konzept, eine allgemeine Lösung für ein programmiertechnisches Problem mit einem Namen zu versehen und die Implementierung nicht konkret, sondern mit allgemeinen Begriffen zu beschreiben, wird als Entwurfsmuster ("design pattern") bezeichnet. In späteren Kapiteln werden wir auf weitere Beispiele stoßen, wie Entwurfsmuster das Verstehen von Framework-Architekturen erleichtern.

Um die Hintergründe besser zu verstehen, rufen wir uns in Erinnerung, wie PHP früher zum Erstellen von Websites verwendet wurde. Der typische Ansatz wird oft als "Page Controller" bezeichnet (es gibt auch den Begriff "Transaction Script", aber totales Chaos lässt sich eben nicht eindeutig erklären!). Beim Page-Controller handelt es sich um ein weiteres Entwurfsmuster, das Martin Fowler in seinem berühmten Buch "Patterns of Enterprise Application Architecture" (in der Community liebevoll als POEAA abgekürzt) beschrieben hat. Es definiert einen Ansatz, in dem jede HTML-Seite der Anwendung ihre eigene PHP-Datei hat. Oft werden letztendlich doch viele HTML-Seiten mittels einer PHP-Datei generiert, aber dies geschieht nur, weil die Seiten einander so ähnlich sind, dass diese Verbindung hergestellt werden muss, um den Code innerhalb der Datei wiederverwenden zu können und ihn nicht zu duplizieren (Formulare und ihre Verarbeitung sind da ein typischer Fall). Häufig fügen diese Seiten dieselben Dateien am Beginn des Codes ein, um Bibliotheken oder Konstanten zu importieren. Zum Beispiel könnte es sein, dass alle Seiten Smarty oder eine Datenbankverbindung benötigen.

Dieses Szenario ist allerdings nur schwer handhabbar, wenn das Projekt wächst und Änderungen unterworfen ist. Jedes neue Feature oder jeder Bugfix benötigt zusätzlichen Code. An welche Stelle dieser Code geschrieben wird, bestimmt zu einem großen Grad die Wartbarkeit Ihrer Anwendung. Eine kleine Änderung erfordert möglicherweise mehrere Änderungen an vielen Stellen, da sich die Geschäftslogik mit der Zeit über ein Dutzend Dateien oder mehr verteilt hat, wodurch man Codeteile duplizieren muss. Vielleicht stellen Sie auch fest, dass sich SQL-Abfragen in einem weiteren Dutzend Dateien auf eine Tabelle beziehen, deren Name geändert werden muss. Sie können sich vorstellen, dass die Menge solch kleiner Änderungen über eine Vielzahl von Dateien geradezu exponentiell zunimmt, bis Sie begreifen, dass schon alleine die Wartung dieser Unmenge an Code viel Zeit und Ressourcen verschlingt. An diesem Punkt stagnieren viele Projekte, obwohl hinter ihnen enthusiastische Entwickler stehen. Ich bin selbst in diese Falle geraten, und diese Erfahrung aus erster Hand hat mich dazu animiert, einen besseren Ansatz aufzuspüren.

Über die Jahre hat der Entwicklungsprozess von PHP-Anwendungen einige wichtige Entwicklungen durchgemacht. Die wichtigste Entwicklung war, dass die objektorientierte Programmierung (OOP) verbreitet Einzug gehalten hat. Eine zweite Entwicklung war die langsame, aber beständige Übernahme OOP-bedingter "Best Practices" wie Unit-Testing. Die dritte Innovation war der explosive Anstieg der Verwendung des Model-View-Controller-Architektur-Designpatterns und sein Einfluss auf die aktuelle Generation der Webanwendungs-Frameworks wie das Zend Framework.

2.2. Das Model-View-Controller-Prinzip

Die Model-View-Controller-Architektur (üblicherweise mit MVC abgekürzt) stellt einen allgemeinen Lösungsansatz bzw. ein Anwendungs-Designpattern dar, um auf stark strukturierte Weise die Zuständigkeitsbereiche einer Anwendung zu trennen. Im Grunde genommen wird damit totales Chaos vermieden!

Das Ziel von MVC ist zu verhindern, dass Code aus verschiedenen Bereichen vermischt wird. Dabei wird betont, dass drei Typen von Komponenten existieren, die voneinander getrennt sind und die über Schnittstellen zusammenarbeiten sollten. Das klingt entsetzlich kompliziert (keine Bange!), doch es schützt den Quelltext davor, unter seinem eigenen Gewicht zusammenzubrechen und zum berüchtigten "Spaghetti-Code" zu werden, wie es bei vielen desorganisierten PHP-Anwendungen der Fall ist.

Der Name dieser Architektur enthält alle drei zu unterscheidenden Komponenten: Model, View und Controller. MVC mag wie eines dieser esoterischen Programmierkonzepte wirken, aber das Konzept ist eigentlich ziemlich simpel.

Sie greifen sich einen Brocken Funktionalität heraus, bestimmen seinen Zweck und weisen ihn einer der drei Komponenten sowie schließlich einer bestimmten Klasse innerhalb dieser Schicht zu. Sobald alles korrekt aufgeteilt ist, haben Sie eine Anwendung vor sich, die aus kleineren Stücken zusammengesetzt ist, welche wiederverwendbar, vereinheitlicht und leicht zugänglich sind. Sie passen zusammen wie Bausteine und bieten eine abstrakte API, über das sie miteinander verbunden werden können - die abstrakten APIs erleichtern inkrementelle Änderungen ungemein (falls es richtig gemacht wird, natürlich!). Wenn alles ordentlich in Objekte mit klar abgegrenzten Verantwortlichkeiten aufgeteilt ist, werden die Kosten für Änderungen normalerweise signifikant reduziert, worum es ja eigentlich bei der ganzen Sache geht - wir wollen, dass wir Änderungen günstig, einfach und ohne Sorgen durchführen können.

Verständlicherweise decke ich hier nicht das komplette Feld der objektorientierten Programmierung ab. Die Botschaft ist aber hoffentlich klar. MVC verstärkt alle Vorteile, welche aus korrekt angewandten OOP-Praktiken enstehen sollen. Der Code befolgt Prinzipien wie "Don't Repeat Yourself" (DRY) und "Keep It Simple Stupid" (KISS), welche von chaotischer Codeduplizierung abraten und Wiederverwendbarkeit und Wartbarkeit fördern.

Eine Sache, die viele Entwickler verwirrt ist, dass durch MVC scheinbar mehr Code erzeugt wird, als dies ohne MVC der Fall wäre. Das ist kein Anzeichen dafür, dass MVC schlecht ist, sondern ein normaler Effekt der objektorientierten Programmierung und somit ein wohlbekanntes Ergebnis der stärkeren Strukturierung. Wenn Sie ein Web-Application-Framework verwenden, ist das aber nicht Ihr Problem. Sie schreiben das Framework doch nicht von Grund auf neu, oder? Ein anderer Grund für die größere Menge an Code ist ziemlich offensichtlich - Frameworks bieten viel mehr Funktionen, als es eine simple MVC-Implementierung tun würde.

Wie auch immer: da OOP eine Menge an Klassen erzeugt, sollten Sie verstehen, warum das gut ist. Ein gewaltiges prozedurales Skript bestünde aus weniger Code und wäre daher auch wesentlich leichtfüßiger unterwegs, doch dabei handelt es sich nicht um eine dauerhafte Lösung. OOP-Code ist darauf ausgelegt, die Kosten für Wartung, Tests, Anpassungen und Wiederverwendung drastisch zu senken. Diese Ersparnisse übersteigen die Vorkosten der Entwicklung normalerweise bei weitem! Denken Sie daran, Sie werden mit diesem irrsinnigen Code jahrelang leben müssen. Write once, use forever. Die gleichen Probleme immer wieder aufs Neue zu lösen ist keine zukunftsfähige Entwicklungsmethode, denn anstatt mit einmaligen und unmittelbaren versunkenen Kosten werden Sie mit ständig steigenden Kosten konfrontiert, die mit jeder Neuerfindung desselben alten Rads in unterschiedlicher Gestalt auftauchen. Das Umschreiben und Neuerfinden ist teuer und auch riskant.

Das Zend Framework als "glue framework" bietet MVC in komponentenbasierter Form an. Das heißt, dass die MVC-Architektur des Frameworks in mehrere scheinbar unabhängige Komponenten aufgeteilt ist. Zu diesen zählen unter anderem (aber nicht ausschließlich) Zend_Controller, Zend_Db (falls es Teil eines Models ist), Zend_View und Zend_Layout. Jede dieser Komponenten deckt einen Aufgabenbereich innerhalb der MVC-Architektur ab und bewahrt sich zugleich alle Eigenschaften einer unabhängigen Komponente, die Sie außerhalb einer MVC-basierten Anwendung verwenden können.

Natürlich resultiert daraus ein Überfluss an fokussierten Klassen bis hin zu dem Punkt, an dem es schwer werden kann zu überblicken, wie all die Teile zusammen arbeiten. Eigentlich brauchen Sie aber nur die nach außen hin sichtbare API jeder Komponente und können den Rest ignorieren, solange Sie etwas nicht wirklich, wirklich anpassen möchten. Für jede häufig verwendete Klassenmethode existieren wahrscheinlich fünf andere, für die sich nur eine Minderheit der Entwickler interessieren wird. Das unterstreicht die Anpassbarkeit des Zend Framework - die zusätzlichen Methoden existieren, damit Sie das Framework anpassen können, falls es notwendig wird (und das wird fast immer der Fall sein, außer Sie lassen sich gerne stark einschränken).

Lassen Sie es mich mit Nachdruck sagen, um alle Zweifel zu beseitigen: MVC ist überall. Nahezu jedes moderne Web-Application-Framework verwendet MVC. Es wird verwendet im Zend Framework, Symfony, Django für Python, Spring, Ruby On Rails und Merb. Greifen Sie sich ein beliebiges Framework heraus und die Chancen stehen gut, dass es sich als MVC-Framework bezeichnet!

Nun wollen wir die MVC-Komponenten kennenlernen!

2.2.1. Die View

Die View ist dafür verantwortlich, die Benutzeroberfläche Ihrer Anwendung zu generieren. In PHP wird sie oft recht knapp definiert als der Teil, in den Sie Ihren HTML-Code ablegen. Das ist zwar richtig, doch Sie können hier genauso ein System aus dynamisch generiertem HTML,RSS, XML und JSON erschaffen, ja tatsächlich aus allem, was an eine Client-Anwendung geschickt werden kann, egal ob es sich dabei um einen Browser oder einen Web-Service handelt. Üblicherweise braucht man eines oder mehrere Models als Quelle für die dynamischen Daten, für deren Darstellung die View generiert wird. Wir sollten dabei aber nicht allzu sehr auf Models fixiert sein, denn die View kann auch einfache Daten wie Skalare und Arrays übernehmen - verpacken Sie also nicht jedes Stückchen Data in ein Model, wenn es nicht notwendig ist.

Die View wird gewöhnlicherweise in Template-Dateien organisiert, doch sie kann auch direkt vom Controller ausgegeben oder von diesem vor der Ausgabe manipuliert werden. Es ist dabei wesentlich zu beachten, dass es sich bei der View nicht einfach um ein Dateiformat handelt - sie umfasst alle PHP-Codeteile oder geparste Tags, die dazu da sind, um die von einem oder mehreren Models bezogenen Daten zu organisieren, zu filtern, zu dekorieren oder ihr Format zu manipulieren (oder, wie es oft das Fall ist: der Controller übergibt die Daten vom Model an die View).

Ein zweiter Aspekt der View ist, dass es - da alle Inhalte dynamisch von PHP generiert werden - sehr sinnvoll ist, eigene Plugins zu entwickeln, in denen häufig anstehende Aufgaben erledigt werden. Zum Beispiel ist es zum Umwandeln der Überschrift eines Blog-Posts in ein URL-freundliches Format notwendig, einige Satzzeichen zu entfernen und Nicht-ASCII-Zeichen durch ihre ASCII-Äquivalente zu ersetzen. Diese Aufgabe könnte leicht in ein View-Plugin verpackt werden, das auf die Überschrift des Eintrags angewandt wird, wenn URLs zu Ihren Templates hinzugefügt werden. Wir wissen, dass solche Plugins zur View gehören, da sie zur Darstellungslogik gehören - Logik, deren einziger Zweck es ist, die Präsentation der Daten zu beeinflussen.

Nebenbei bemerkt verlangt dieses Buch nicht den Einsatz von Smarty oder einer anderen Standalone-Bibliothek, um Templates zu interpretieren. Smarty hat in der PHP-Gemeinde einen respektablen Ruf, aber es hat grobe Mängel, sobald man von der View als Puzzle mit möglicherweise dutzenden wiederverwendbaren Teilen zu denken beginnt, welche zu einem einzelnen allumfassenden Layout zusammengesetzt werden. In Wirklichkeit ist diese Art der Handhabung der View dem Konzept OOP so stark verhaftet, dass es fast unausweichlich wird, PHP selbst als Templatesprache zu verwenden. Das ist nicht immer problemlos, da nicht alle Webdesigner PHP beherrschen, aber das Zend Framework ermöglicht Ihnen, jede Template-Engine einzubinden, die Ihnen gefällt.

2.2.2. Der Controller

Controller sind im Vergleich zur View und zum Model geradezu verdächtig simpel. Ihre Hauptfunktion ist es, zu kontrollieren und zu delegieren. Bei einer typischen Anfrage in einer MVC-Web-Architektur empfängt der Controller Benutzereingaben, übersetzt sie in Aktionen eines oder mehrerer Models und liefert eine Ausgabe zurück, die von der View auf Basis der Ergebnisse der Model-Aktionen erzeugt wird.

Dabei möchte ich gleich darauf hinweisen, dass dieser Ablauf einen wichtigen Punkt bei Controllern verdeutlicht. Controller delegieren so viel wie möglich, denn wenn Sie sie mit Aufgaben überladen, werden sie schnell überlastet und mühsam zu warten. Viel mehr noch, sie werden anfangen, dem alten Page-Controller gefährlich ähnlich zu werden - und das ist SCHLECHT (TM). Anwendungslogik sollte so oft als möglich an Models delegiert werden. Wir werden Models gleich kennen lernen und uns mit dem Konzept des Models in Kapitel 3 näher beschäftigen.

Der Controller ist auch insofern gegenüber anderen Formen von PHP-Architekturen einzigartig, als er nur einen einzigen Einstiegspunkt in die Anwendung benötigt - dieser wird beinahe unausweichlich index.php genannt. Dass nur ein Weg in die Anwendung existiert, macht bestimmte Aufgaben viel einfacher. Zum Beispiel können Sie eine Reihe von Request-Filtern einrichten, die auf alle Anfragen angewandt werden. Zugriffskontrolllisten ("Access Control Lists", ACL) sind ein sehr gutes Beispiel für einen häufig gebrauchten Filter. Das Einbinden einer Anwendungsfirewall oder eines Honey Pot (Sicherheitsschichten) sind weitere. Tatsächlich werden wir in einem späteren Kapitel ein wenig bekanntes Projekt kennen lernen, dass das PHP-Intrusion Detection System (PHPIDS) genannt wird.

2.2.3. Das Model

Das Model kann auf mehrere Arten erklärt weden. Man kann sogar ganze Bücher über das Model schreeben, und das haben auch viele Menschen gemacht! Kapitel 3 wird sich mit diesem Thema noch viel eingehender befassen, aber lassen Sie es uns hier schon einmal schnell behandeln.

Das Model hat üblicherweise zwei weit gefasste Rollen:

1. Das Model ist dafür verantwortlich, den Zustand (der Website) zwischen HTTP-Anfragen zu erhalten.

Im Prinzip müssen alle Daten - egal, ob in einer Datenbank, in einer Datei, gespeichert in einer Session oder mittels APC gecacht - zwischen Anfragen konserviert werden und stellen daher einen Teil des Anwendungsstatus zu dem Zeitpunkt dar, an dem die letzte Anfrage abgeschlossen wurde. Denken Sie also daran: das Model ist nicht nur die Datenbank. Auch die Daten, die Sie von Web-Services beziehen, können als Model formuliert werden! Ja, sogar Atom-Feeds! Frameworks, die Einführungen zum Model herunterleiern, erklären das fast nie vorab, was Missverständnisse nur verschlimmert.

Zend_Feed_Reader, das ich mit Jurriën Stutterheim entwickelt habe, ist zum Beispiel eigentlich ein Model. Es liest Feeds, manipuliert sie, interpretiert Daten, fügt Beschränkungen und Regelungen hinzu und erzeugt üblicherweise eine verwendbare Repräsentation der darunterliegenden Daten. Ohne diese Komponente haben Sie Zend_Feed (den aktuellen Platzhirsch, wenn es um das Lesen von Feeds geht), das viel zusätzliche Arbeit erfordert, um zu einem brauchbaren Model zu werden. Mit anderen Worten: während Zend_Feed_Reader zum Teil ein Model darstellt, entspricht Zend_Feed dem puren Datenzugriff.

2. Das Model vereinigt alle Regeln, Beschränkungen und Verhaltensweisen, welche diese Informationen verwalten und verwenden.

Angenommen, Sie schreiben die Geschäftslogik für ein Bestellungs-Model in einem Warenwirtschaftssystem, dann könnten unternehmensinterne Richtlinien vorgeben, dass für einzelne Aufträge ein Limit von €500 existiert. Aufträge über €500 würden von Ihrem Bestellungs-Model als illegale Aktionen angesehen werden (wahrscheinlich ausgenommen der Fall, dass sie von jemandem mit höheren Befugnissen genehmigt werden). Das Model sollte die Fähigkeit besitzen, solche Bedingungen zu berücksichtigen.

Das macht sehr viel Sinn, wenn Sie sich die Bedeutung des Wortes "Model" (beziehungsweise "Modell") vor Augen führen. Zum Beispiel haben wir in der Klimatologie klimatische Modelle, welche Daten definieren, Prozesse ablaufen lassen, von bestimmtem Verhalten ausgehen und daraus wahrscheinliche Ergebnisse berechnen. Es gibt einen Grund, warum das M in MVC Model genannt wird: das Model repräsentiert nicht einfach nur bloße Daten, es repräsentiert das gesamte System, für welches diese Daten sinnvoll sind. Selbstverständlich kann jedes System komplex genug sein, so dass man mehrere miteinander agierende Modelle benötigt, aber Sie verstehen, worauf ich hinaus will.

Wenn Sie diese zwei Punkte lesen, stellen Sie eventuell etwas Verblüffendes fest. Mit Ausnahme der Benutzeroberfläche kann der größte Teil der Anwendung mit Models ausgedrückt werden. Das Model konzentriert sich auf die gesamten Daten und das den Daten zugrundeliegende Verhalten - manchmal sogar darauf, wie die Daten dargestellt werden müssen. Das Model kann die Daten verstehen, interpretieren, repräsentieren und sie mit sinnstiftendem Nutzen versehen. Es handelt sich auch um einen sinnvollen Ort, um Validierungsregeln und Beschränkungen zu speichern - warum sollte man sie nicht bei den Daten behalten, auf die sie angewendet werden?

Diese Betrachtung macht offensichtlich, dass das Model der Teil des Dreigestirns MVC ist, den Sie nahezu von Grund auf entwickeln müssen. Das Zend Framework kann Komponenten zum Datenzugriff bereit stellen, aber es kann nicht vorhersagen, was Ihre Anwendung tun wird! Models gehen weit über den Datenzugriff hinaus, sie müssen Sie entwickeln und ausgiebig testen, bevor Sie ein brauchbares Model erhalten. Es ist nicht immer so leicht, dass man einfach nur Zend_Db_Table erweitern muss.

Wir werden das Model in Kapitel 3 genauer behandeln, da es eine Fülle an Informationen bezüglich der Fragen zu berücksichtigen gibt, was es repräsentiert und wohin es im Gesamtbild MVC passt.

2.3. Im Rückblick

Die Model-View-Controller-Architektur ist eine weitgehend anerkannte Lösung für Webanwendungen geworden und erwiesenermaßen in der Mehrzahl der aktuellen Frameworks in den meisten Programmiersprachen zu finden.

In Zend Framework wird diese Dreiteilung repräsentiert durch die Komponenten Zend_Db, Zend_View, Zend_Layout und Zend_Controller. In den folgenden Kapiteln werden Sie eine Menge über diese vier Komponenten und die Klassen, aus denen sie bestehen, hören! Sie formen zusammen das Rückgrat der MVC-Architektur des Zend Framework und untermauen eine Menge seiner "best practices".

MVC wurde ursprünglich verwendet, um die Trennung der Zuständigkeiten in Desktop-GUI-Anwendungen zu fördern. Indem jeder Bereich in eine unabhängige Schicht der Anwendung ausgelagert wurde, wurden Kopplungen und Abhängigkeiten zwischen den Komponenten vermindert, was es wiederum einfacher macht, Anwendungen zu entwerfen, zu schreiben, zu testen und zu warten. GUI-Anwendungen haben sich in den letzten Jahren von MVC abgewendet, aber für Webanwendungen hat es sich als höchst effektiv erwiesen.

Die Struktur des Frameworks wird so wesentlich berechenbarer, da jedes Segment von MVC für jede der unterstützten Anfragearten in eine eigene Gruppe von Dateien aufgespaltet wird. Der Controller wird repräsentiert durch Subklassen von Zend_Controller_Front und Zend_Controller_Action, das Model durch Domain-Klassen oder eine andere Gruppe von Klassen, die sich z.B. zwecks des Speicherns in einer Datenbank auf Zend_Db_Table und Zend_Db_Table_Row stützen, und die View durch .phtml-Template-Dateien und View-Helfer. Das Zend Framework verwaltet, wie sie alle zusammen wirken und gibt einem damit die Möglichkeit, sich auf diese Gruppen zu konzentrieren, ohne sich darum sorgen zu müssen, wie sich der Code zu einer geschlossenen Einheit zusammenfügt.

In gewisser Hinsicht ist es so, als ob man ein Haus baut, bei dem das Fundament, die Mauern, die Innenverkabelung und die Klempnerarbeit bereits erledigt sind und nur noch die Innenausstattung und das Dach fehlen. Es dauert vielleicht einige Zeit, bis man gelernt hat, wie man die vorbereiteten Teile dekoriert und das Dach errichtet, aber sobald man das gelernt hat, kann man alle weiteren Häuser viel schneller fertig stellen!

2.4. Fazit

Das war ein kurzer Überblick über das Konzept der Model-View-Controller-Architektur (MVC). Trotz ihrer Länge handelt es sich nicht um eine erschöpfende Betrachtung, doch sie deckt genug ab, so dass später vorgestellte Konzepte nicht völlig ohne Kontext dastehen. Außerhalb dieses Buches gibt es eine Flut an Artikeln, die sich in aller Ausführlichkeit dem MVC im Internet und sonst wo widmen. Ich muntere Sie dazu auf, sich damit zu beschäftigen, denn diese Zeit ist sicher nicht verschwendet. Jedes Stückchen, das zum Verständnis beiträgt, ist die Zeit wert, die man braucht, um es zu finden.

Im nächsten Kapitel dieser Reise werden wir einige Zeit damit verbringen, das Model näher kennen zu lernen. Es wird gesondert behandelt, da das Model als Konzept viele Schwierigkeiten aufwerfen kann und der Einsatzbereich groß ist.