User Tools

Site Tools


patterns:role

This is an old revision of the document!


Rollenmuster / Role Pattern

Das Rollenmuster ist ein recht interessantes Muster über das man Bereiche sinnvoll verknüpfen kann, bzw. erweitern kann. Wenn man ein Unternehmen abbilden möchte, wäre es z.B. sinnvoll, dass man eine Person zu einem Mitarbeiter machen kann. Eine Person hat einen Namen und eine Anschrift, ein Mitarbeiter eine Personalnummer und einen Angestelltenzeitraum, sowie eine Jobbeschreibung, usw. Dieses Dokument basiert auf einem Artikel von Martin Fowler aus 1997.

Eine Möglichkeit in einer einfachen Domäne, die ausschließlich mit Mitarbeitern arbeitet, wäre es, der Person einfach die Merkmale1) eines Mitarbeiters zu geben. Eine Person ist in dem Fall immer gleichzeitig ein Mitarbeiter.

Wenn das aber nicht der Fall sein soll, und eine Person ein Mitarbeiter sein kann, wäre es eventuell sinnvoll, den Mitarbeiter getrennt von der Person zu haben, und eine Referenz zwischen einer Person und einem Mitarbeiter herzustellen, um zu verdeutlichen, dass ein bestimmter Mitarbeiter eine bestimmte Person ist und anders herum.

Man müsste sicherstellen, dass die Referenz eindeutig ist. Trotzdem ist eine Referenz ein recht schwache Aussage über die Beziehung von der Person zum Mitarbeiter. Eine Referenz sagt aus, dass die Person einen Mitarbeiter hat/besitzt, oder anders herum, einem Mitarbeiter gehört. Nicht aber, dass der Mitarbeiter die Person ist2).

Eine Möglichkeit wäre es somit, den Mitarbeiter von der Person abzuleiten, in der Form

public class Person
{
  public Guid Id {get; set;}
  public string Name {get; set;}
}
public class Employe: Person 
{
  public string EmployeeKey {get; set;}
}
public class Contact: Person 
{
  public Debtor Customer {get; set;}
}

In Sprachen mit Einfachvererbung könnte eine Person auf diesem Weg aber nicht gleichzeitig ein Mitarbeiter und ein Kundenkontakt sein. Das ist in vielen Fällen zu einschränkend, da eine Person durchaus mehrere Rollen einnehmen kann.

Das ist der springende Punkt. Eine Person kann Rollen einnehmen. Daher soll das auch so modelliert werden:

public abstract class PersonRole
{
  public Person Person {get; set;}
}
public class Person
{
  public Guid Id {get; set;}
  public string Name {get; set;}
  private readonly IDictionary<Type, PersonRole> Roles = new Dictionary<Type, PersonRole>();
  public PersonRole GetRole(Type roleType)
  {
    if (Roles.ContainsKey(roleType)) return Roles[roleType];
    throw new PersonRoleInterfaceNotImplementedException(this.Id, roleType.ToString());
  }
}
public class Employe: PersonRole 
{
  public string EmployeeKey {get; set;}
}
public class Contact: PersonRole
{
  public Debtor Customer {get; set;}
}

So kann eine Person mehrere Rollen erhalten, sie kann gleichzeitig die Rolle eines Mitarbeiters einnehmen, einer Kontaktperson, oder eine beliebige andere Rolle. Referenziert wird immer die Person, und über Person.GetRole(typeof(Employee)) wird die Person in der Rolle als Mitarbeiter angesprochen. Nochmal, weil es so wichtig ist: Referenziert wird immer die Person. Das ist wichtig, denn das spiegelt wieder, was modelliert werden soll. Die Person ist ja der Mitarbeiter, und wenn ich ihn in als Mitarbeiter brauche, und nicht als Kumpel, dann spreche ich ihn in seiner Rolle als Mitarbeiter an. Wenn ich einen Mitarbeiter einem Projekt zuordne, dann wird die Person zum Projektmitarbeiter, d.h. die Person wird auch referenziert. Alle Eigenschaften und Verhaltensweisen der Person die das Projekt benötigt erhält man, indem man die Person in der Rolle Mitarbeiter verwendet.

Das Rollenmuster in Domain Driven Design (DDD)

In DDD ist eine Hauptelement das Aggregate. Eine Strukturierungsmethode sind Bounded Contexts. Es wäre in DDD sinnvoll, die Person und den Mitarbeiter in unterschieliche Bounded Contexts zu packen, denn wenn man von jemanden als Person spricht, meint man oft was anderes, als wenn man im Kontext eines Mitarbeiterdaseins von der Person spricht.

Das ist eine sehr strikte Trennung. Man könnte keine Aggregate

1) und natürlich hauptsächlich das Verhalten
2) es wäre schön den Unterschied zwischen der ist-Beziehung und der kennt/hat-Beziehung im Objektmodell zu erkennen, und nicht in der Dokumentation nachlesen zu müssen, wissen zu müssen oder indirekt durch Code-Durchforstung und Nachfragen raus zu bekommen
patterns/role.1357302268.txt.gz · Last modified: 2013/01/04 13:24 by rtavassoli