Dynamic role-switching

Instructor's Guide

intro polymorphism idioms patterns events summary, Q/A, literature
For many applications, static type hierarchies do not provide the flexibility needed to model dynamically changing roles. For example we may wish to consider a person as an actor capable of various roles during his lifetime, some of which may even coexist concurrently. The characteristic feature of the dynamic role switching idiom underlying the actor pattern is that it allows us to regard a particular entity from multiple perspectives and to see that the behavior of that entity changes accordingly. We will look at a possible realization of the idiom below.

Taking our view of a person as an actor as a starting point, we need first to establish the repertoire of possible behavior.

  class actor { 
public static final int Person = 0; public static final int Student = 1; public static final int Employer = 2; public static final int Final = 3; public void walk() { if (exists()) self().walk(); } public void talk() { if (exists()) self().talk(); } public void think() { if (exists()) self().think(); } public void act() { if (exists()) self().act(); } public boolean exists() { return false; } public actor self() { return this; } public void become(actor A) { } public void become(int R) { } };

slide: actor.java

Apart from the repertoire of possible behavior, which consists of the ability to walk, talk, think and act, an actor has the ability to establish its own identity (self) and to check whether it exists as an actor, which is true only if it has become another self. However, an actor is not able to assume a different role or to become another self. We need a person for that!

Next, we may wish to refine the behavior of an actor for certain roles, such as for example the student and employer roles, which are among the many roles a person can play.

  class student extends actor { 
public void talk() { System.out.println("OOP"); } public void think() { System.out.println("Z"); } };
  class employer extends actor { 
public void talk() { System.out.println("money"); } public void act() { System.out.println("business"); } };

slide: Students and Employers

Only a person has the ability to assume a different role or to assume a different identity. Apart from becoming a Student or Employer, a person may for example become an adult_person and in that capacity again assume a variety of roles.
  class person extends actor { 
public person() { role = new actor[ Final+1 ]; for( int i = Person; i <= Final; i++ ) role[i]=this; become(Person); } public boolean exists() { return role [role] != this; } public actor self() { if ( role[ Person ] != this ) return role[ Person ].self(); else return role [role]; } public void become(actor p) { role[ Person ] = p; } public void become(int R) { if (role[ Person ] != this) self().become(R); else { _role = R; if ( role [role] == this ) { switch(_role) { case Person: break;
nothing changes

case Student: role [role] = new student(); break; case Employer: role [role] = new employer(); break; case Final: role [role] = new actor(); break; default: break;
nothing happens

} } } } int _role; actor role[]; };

slide: person.java

A person may check whether he exists as a Person, that is whether the Person role differs from the person's own identity. A person's self may be characterized as the actor belonging to the role the person is playing, taking a possible change of identity into account. When a person is created, his repertoire is still empty. Only when a person changes identity by becoming a different actor (or person) or by assuming one of his (fixed) roles, is he capable of displaying actual behavior.

Assuming or `becoming' a role results in creating a role instance if none exists and setting the _role instance variable to that particular role. When a person's identity has been changed, assuming a role affects the actor that replaced the person's original identity. (However, only a person can change roles!)

The ability to become an actor allows us to model the various phases of a person's lifetime by different classes, as illustrated by the adult class.

  class adult extends person {  
public void talk() { System.out.println("interesting"); } };

slide: adult.java

In the example code below we have a person talking while assuming different roles. Note that the person's identity may be restored by letting the person become its original self.
  public class go { 
public static void main(String[] args) { person p = new person(); p.talk();
p.become(actor.Student); p.talk();
p.become(actor.Employer); p.talk();
p.become(new adult()); p.talk();
p.become(actor.Student); p.talk();
p.become(p); p.talk();
old role: employer
p.become(actor.Person); p.talk(); // initial state } };

slide: go.java

The dynamic role switching idiom can be used in any situation where we wish to change the functionality of an object dynamically. It may for example be used to incorporate a variety of tools in a drawing editor, as illustrated in chapter 4.