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.

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 ist.

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 Rolle spielen. 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. 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.

1) und natürlich hauptsächlich das Verhalten
patterns/role.1357243717.txt.gz · Last modified: 2013/01/03 21:08 by rtavassoli