User Tools

Site Tools


patterns:inheritancerolestragegyoverview:role

Rolle - Implementierung

Rollen werden ganz nach dem Open-Closed Prinzip implementiert. Vorhandene Bereiche sind Änderungen gegenüber geschlossen, und Erweiterungen gegenüber offen. Wenn eine Person also als Mitarbeiter fungieren können soll, kann er die Rolle Employee bekommen. Diese Rolle erhält er in einem neuen Mitarbeiter Kontext1), und für die Rolle wird ein neues Aggregate erzeugt. Die ID der Rolle ist die ID der Person im Personen Kontext.

Das Teilen der ID anstatt einer Referenz von Employee auf Person macht Employee zur Rolle von Person. So wird die Person nicht verändert. Sie wird aber erweitert - hauptsächlich für den Anwender, denn Formulare für eine Person werden über Komponenten dargestellt, und die Employee Komponenten können zu den anderen Person Komponenten dazu geladen werden, damit der Anwender sieht, dass sie zusammen gehören. Listen, Übersichten, Reports, Workflows, usw. für die Mitarbeiter Rolle können Personendaten enthalten.

Wenn ich die Person benötige, kann ich sie mit Repository<Person>.Get(ID) laden und Methoden aufrufen. Wenn ich die Person als Mitarbeiter benötige, lade ich die Rolle einfach über Repository<Employee>.Get(ID) und rufe Methoden von Employee auf. Einen Mitarbeiter über Repository<Person>.Get(ID).GetRole(typeof(Employee)) zu laden ist weder einfacher noch notwendig. Es sei denn, man möchte die Rolle Employee so dem Person Aggregate hinzufügen. Dann könnten die Ereignisse der Mitarbeiter Rolle transaktional mit denen der Personen Rolle gespeichert werden. Das ist aber nicht notwendig, wir wollen ja weg von Transaktionen. Worauf man achten kann ist, dass ein AddEmployee Befehl immer erst geschickt wird nachdem PersonAdded Erfolgreich erhalten/beobachtet wurde2). So kann man zumindest sicher stellen, dass keine Mitarbeiter Rollen ohne Person brach rum liegen. Und wenn sie es doch tun? Dann die Sichten auf Mitarbeiter immer so bauen, dass sie nur Daten raus reichen, wenn auch eine Person dahinter steckt. So kann dann niemals ein Anwender einen Mitarbeiter ohne Person sehen und weitere Aktionen mit ihm durchführen.

Der abstrakte Mitarbeiter

Wäre es im Sinne einer möglichen Erweiterbarkeit sinnvoll, den Mitarbeiter als selbstständiges Aggregate zu bauen, dabei abstrakt zu halten? Es könnte dann ein PersonEmployee geben, der die Person referenziert3)?

Die Antwort lautet wie in so vielen Fällen: es kommt darauf an. Lohnt sich die zusätzliche Komplexität? Ich kann mir keinen anderen Mitarbeiter vorstellen als eine Person. Wenn man die Person weg abstrahieren möchte, und den Employee an eine beliebige Implementierung von einer Person über abgeleitete Klassen von Employee4) hängen können möchte, würde man keine Domäne mehr bauen, sondern ein Framework. Man würde sich dann tot-abstrahieren, jede konkrete Implementierung ablehnen, und nie fertig werden.

Man müsste sich höchstens Gedanken über die möglichen Berührungspunkte für potenzielle Schnittstellen machen. In dem Fall wäre es nicht so, dass man den Mitarbeiter als Schnittstellenpunkt nehmen würde, sondern die Person. Wenn die Person somit aus einem anderen Bereich kommt, würde man eine Schnittstelle bauen, die eine FremdsystemPerson in eine Person wandelt. Der Mitarbeiterkontext hat dann immer den Personenkontext auf den er sich beziehen kann. Wenn die Kontexte klein genug gehalten werden, dann sind auch solche Schnittstellen schnell und einfach umzusetzen.

Vor allem aber wird der Personenbereich nicht ersetzt werden. Und wenn doch, dann wird der vorhandene Person BC einfach als Schnittstelle verwendet zwischen dem neuen Personenbereich und dem Mitarbeiterbereich. Wenn sich in dem anderen Bereich ein Name ändert, dann fängt ein Handler das OtherPersonBCPersonNameChanged Ereignis ab und sendet ein ChangePersonName Befehl an die Person in der Person BC. Befehle an die Person BC werden in Befehle an die OtherPersonBCPerson umgeleitet. Das ist flexibel und pragmatisch genug.

1) Employment BC
2) und/oder im Command Handler für AddEmployee die Person erst abfragt und einen Fehler meldet, wenn die Person nicht gefunden wird
3) ähnlich wie Account und UserAccount/SystemAccount
4) ProMPersonEmployee, MSCRMPersonEmployee, usw.
patterns/inheritancerolestragegyoverview/role.txt · Last modified: 2013/01/08 21:21 by rtavassoli