title: Role Object pattern question
body: <p>I am looking at a paper done by Martin Fowler called <a href="http://martinfowler.com/apsupp/roles.pdf" rel="nofollow">Dealing With Roles</a>. In it, Fowler breaks out three basic strategies for dealing with roles for a Person in an organization (ie, Employee, Engineer, Manager, Salesman) which include Role Subtyping, Role Object, and Role Relationships.</p>
  
  <p>Having been written in 1997 it is certainly old, and being a "working draft" it also has some errors that otherwise wouldn't be there. I am confused going over an example of Role Object he goes through, and have included a my c# interpretation of some of his java code below.</p>
  
  <p>I have three questions:<br>
  (1) there's a lot of type identification being done with strings that seems like it should be replaceable with generics, but I can't get a handle on how to do so yet. How would you implement this code using generics?<br>
  (2) JobRole is in the code as the string name for a type but it is not specifically defined with the rest of the code. I can't tell if this is a base class for PersonRole or not. What is the definition of JobRole? Does the unit test look like a correct example of the pattern's usage?<br>
  (3) Does anyone have any links  towards a more recent implementation and example of using a Role Object?</p>
  
  <p>Cheers,<br>
  Berryl</p>
  
  <pre><code>public class PersonWithRoles : Person
  {
      private readonly IList&lt;PersonRole&gt; _roles = new List&lt;PersonRole&gt;();
  
      public static PersonWithRoles CreatePersonWithRoles(string identifierName) {
          ...
      }
  
      public void AddRole(PersonRole role) { _roles.Add(role); }
  
      public PersonRole RoleOf(string typeName) { return _roles.FirstOrDefault(x =&gt; x.HasType(typeName)); }
  }
  
  public class PersonRole
  {
      public virtual bool HasType(string typeName) { return false; }
  }
  
  public class Salesman : PersonRole
  {
      public override bool HasType(string typeName)
      {
          if (typeName.Equals("Salesman", StringComparison.InvariantCultureIgnoreCase)) return true;
          if (typeName.Equals("JobRole", StringComparison.InvariantCultureIgnoreCase)) return true;
  
          return base.HasType(typeName);
      }
  
      public int NumberOfSales { get; set; }
  
  }
  
  [TestFixture]
  public class RoleUsageTests
  {
      [Test]
      public void Test() {
          var p = PersonWithRoles.CreatePersonWithRoles("Ted");
          var s = new Salesman();
          p.AddRole(s);
  
          var tedSales = (Salesman) p.RoleOf("Salesman");
          tedSales.NumberOfSales = 50;
      }
  }
  </code></pre>