Wie der Titel dem geneigten Leser andeutet möchte ich in diesem Beitrag das Standardwerk
Patterns of Enterprise Application Architecture, kurz EAP, von Martin Fowler zitieren. Im Gegensatz zu den
GoF-Patterns aus meinem ersten Beitrag zu Patterns sind die EAP-Patterns recht spezifisch mit einer Anwendung verbunden. Im folgenden werde ich eine Auswahl von Patterns aus dem Buch auflisten indem ich die Zusammenfassung aus dem Buch pro Pattern zitieren und wo es für mein Verständis wichtig war habe ich noch Kommentare hinzugefügt. Für Details sei an das Buch verwiesen. Nicht erwähnte Patterns sind nicht weniger wichtig, doch haben sie in meinem Umfeld weniger Bedeutung da die Problemstellung nicht vorhanden ist oder ich diese bis heute durch ein Framework lösen lies.
Domain Logic PatternsDomain Model:
'An object model of the domain that incorporates both behavior and data.' Wegen
Domain Driven Design ist dieses Pattern für mich ein Muss.
Service Layer: 'Defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation.' Für den Service Layer gibt es die Variation 'Domain Facade' und 'Operation Script'. Da ich den
Domain Model-Ansatz bevorzuge habe ich hier auch eine Bevorzugung für die 'Domain Facade'. Die Eigenschaften eines einzelnen Service hat Evans auch
hier beschrieben.
Data Source Architectural PatternsActive Record:
'An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.' Dieses Pattern kann zu einer Vereinfachung in der Implementation eines
Domain Model führen indem die Datenbankstruktur und die Domain Model-Stuktur gleich gehalten werden.
Data Mapper:
'A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.' Im Gegensatz zum
Active Record wird das Mapping hier in den Data Mapper ausgelagert. Der Data Mapper wird in der Regel nicht selbst implementiert da dies ein komplexes Unterfangen ist (z.B kann für ein objekte-relationales Mapping
NHibernate verwendet werden). Auch wird ein Data Mapper oft zusammen mit einem
Domain Model verwendet. (siehe auch
Mapper)
OR Behavioral PatternsUnit of Work:
'Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.' Unit of Work sollte in der Regel zusammen mit einem
Data Mapper implementiert werden.
Identity Map: 'Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them. ' Identity Map muss im Zusammenhang mit einem
Data Mapper implementiert werden.
Lazy Load:
'An object that doesn't contain all of the data you need but knows how to get it.' Wichtiges Pattern in Zusammenhang mit
Data Mapper und
Domain Model um zu steuern wann welche Daten von einer Datenquelle geladen werden.
OR Metadata Mapping PatternsQuery Object:
'An object that represents a database query.' Das
Specification Pattern ist mit Query Object verwandt. Der Unterschied ist dass das Query Object auf technischer Ebene ein Query beschreibt. Das Specification Pattern selbst kann Begriffe aus der
ubiquitous Language verwenden und bilden und ist Teil der Geschäftslogik.
Repository: 'Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects'. Ich war hier immer unsicher was der Unterschied zwischen einem Repository und einer Factory ist. Aber in
Domain Driven Design von Evans wird klar definiert: 'The Factory makes new objects; the Repository finds old objects' und in
Applying Domain-Driven Design and Patterns wird dargestellt dass das Repository für die Persistierung von neu erzeugten Objekten zuständig ist. Ein Repository befindet sich auf einer höheren Ebene als ein
Data Mapper indem es
Query Object oder
Specifications auswertet und Objekte mit Hilfe eines
Data Mapper erzeugt.
Web Presentation PatternsModel View Controller: '
Splits user interface interaction into three distinct roles. (View, Controller, Model).' Siehe auch
MVP unter welche das Pattern weiter verfeinert dargstellt wird.
Page Controller: 'An object that handles a request for a specific page or action on a Web site'. Ich sehe im Page Controller eine Anpassung des
Model View Controller an das Web-Umfeld wo es die View einmal auf dem Client als HTML-Seite und einmal auf dem Server als Server-Seite gibt. Dies ist auf jeden Fall der Grund weshalb im Unterschied zum
Model View Controller die View keine Abhängigkeit auf den Page Controller hat. Die clientseitige HTML-Seite hat nämlich eine Abhängigkeit auf den Page-Controller indem diese Web-Requests übermittelt.
Front Controller: 'A controller that handles all requests for a Web site'. Der Controller instanziert abhängig vom Request
Commandos welche die weiteren Verarbeitungen vornehmen.
Template View: 'Renders information into HTML by embedding markers in an HTML page.' Das ist wie eine
ASP-Serverseite.
Application Controller:
'A centralized point for handling screen navigation and the flow of an application'.Distribution PatternsRemote Facade:
'Provides a coarse-grained facade on fine-grained objects to improve efficiency over a network.' Wichtig ist, als Unterschied zum
Service Layer, dass die Remote Facade grob-strukturierte Methoden aufweist.
Data Transfer Object:
'An object that carries data between processes in order to reduce the number of method calls.' Kann zusammen mit
Remote Facade zur Datenübertragung verwendet werden. In .NET werden so oft DataSet's oder XML-Serialisierte Objekte als DTO über Webservices verwendet.
Offline Concurrency PatternsOptimisitc Offline Lock:
'Prevents conflicts between concurrent business transactions by detecting a conflict and rolling back the transaction.' Pessimistic Offline Lock: 'Prevents conflicts between concurrent business transactions by allowing only one business transaction at a time to access data.' Coarse-Grained Lock: '
Locks a set of related objects with a single lock'. Damit verwaltet ein
Optimisitc Offline Lock oder ein
Pessimistic Offline Lock die Locks auf höherer Ebene (z.B:
Aggregate) um den Lockingaufwand zu verringern und die Konsistenzsicherheit zu erhöhen.
Implicit Lock: 'Allows framework or layer supertype code to acquire offline locks.' Stellt sicher dass das Locking implizit ist und somit vom Client-Code weder vergessen noch umgangen werden kann.
Session State PatternsClient Session State: 'Stores session state on the client.' Wird z.B von
ASP.NET-Seiten als ViewState implementiert. Kann aber auch für alle Arten von Sessions verwendet werden.
Server Session State: 'Keeps the session state on a server system in a serialized form'. Wird z.B von
ASP.NET-Seiten auf dem System.Web.HttpContext.Session -Property implementiert.
Database Session State: 'Stores session data as committed data in the database.' Kann bei
ASP.NET via Konfiguration für den
Server Session State eingeschaltet werden.
Base PatternsGateway:
'An object that encapsulates access to an external system or resource.' Vereinfacht ein komplexes externes Inteface und stellt evtl. die Basis zur Verfügung um einen
Service Stub anlegen zu können. Noch ein paar Erklärungen: Ein Gateway wird für externe Komponenten geschrieben während eine
Facade von einer externen Komponente zur Verfügung gestellt wird. Ein
Adapter wiederum ist eine technische Möglichkeit wie ein Gateway umgesetzt werden kann.
Mapper:
'An object that sets up a communication between two independent objects.' Ist komplexer zu implementieren als ein
Gateway. Der Mapper kann als Zwischenschicht gesehen werden welche die zwei angrenzenden Schichten aufeinander abbildet. Beide angrenzenden Schichten bleiben dabei unabhängig und nur der Mapper hat eine Abhängigkeit auf diese.
Layer Supertype: 'A type that acts as the supertype for all types in its layer.' Mag ich persönlich nicht da dadurch schnell das
Single Responsibility Prinzip verletzt wird. (z.B Domain Model hat Subertype für Persistenz).
Separated Interface:
'Defines an interface in a separate package from its implementation.' Die Konfiguration der konkreten Instanz (welche das Interface implementiert) kann danach von einem dritten, von beiden Packages abhängigen Komponente oder per
Plugin zur Laufzeit erfolgen.
Registry:
'A well-known object that other objects can use to find common objects and services.'Plugin: 'Links classes during configuration rather than compilation.' Dafür gibts heute eine Anzahl Frameworks (z.B Spring.NET). Plugin wird häufig auch im Zusammenhang mit dem
Dependency Inversion Principle und
Separated Interface verwendet.
Service Stub:
'Removes dependence upon problematic services during testing.'Record Set:
'An in-memory representation of tabular data.' = DataSet in .NET