开发者

Which Design Pattern should I use to model a Person-Role relationship?

I just couldn't figure out which design pattern I should adopt here. Say I have class like this:

class Person

String role;

public void takeRole(String role) {
  this.role = role;
}

public void do() {

  switch(role)

    case a:
      do this and that;
      this.role = b;

    case b:
      do this and that;

    case c:
      do this and that;
      this.role=a;

    ....

In short, a Person has roles and do() method depends on on what his role is. In some cases, he may have to switch roles. I think this do() should be abstracted (more so because there may be other roles defined in the future)---but how? Should there be a Role class?

Any help will be appreciated.

Edit:

Thanks for开发者_StackOverflow中文版 sparing your time, people. I'd like to add one more thing. I did think (at least as an idea) many of the suggested solutions. Here are are my difficulties: If I subclass Person class (such as PersonTypeA, personTypeB, etc., and assign each particular role to the appropriate person type, then I have a difficulty when switching roles (for instance, an engineer becomes an accountant!---Weird, to say the least.

On the other hand, if I create classes for each role; then (1) a role does not feel like an object, because (at least in my case) a role does not have attributes but only method(s). Consequently, role_A_1 is no different than role_A_2. But for each person I'll have to create a new role object---even if they both share the same role.

I'm not sure if I made myself clear and I'm not sure if my points make sense at all.


Not in a design pattern way, but more in a logical way:

Instead of having a huge 'if role is this, do that, else if it's this' statement, some kind of Role class with a DoThis() method would be easier.

A Person has-a Role. A Person can DoThis() and that the Role then also can DoThis().

Rather than a Person saying what they do according to the Role, the Role says what they can do.


I see a State Pattern emerging here, as well. For example, you can design something along the line of:

interface Role {
    public void doRole(Context context);
}

class RoleA implements Role {
    public void doRole(Context context) {
        // do this and that
        context.setRole(new RoleB());
    }
}

class RoleB implements Role {
    public void doRole(Context context) {
        // do that and this
        context.setRole(new RoleA());
    }
}

class Context {
    private Role _role;

    public Context() {
        // set initial role
        setRole(new RoleA());
    }

    public void setRole(Role newRole) { _role = newRole; }

    public doSomething() {
        _role.doRole(this);
    }
}

In this example, you delegate what behavior a Context object does by asking its currently assigned Role object to do it. The concrete roles themselves have methods that define the transitions between roles. In effect, what emerges here is a simple state machine where concrete Roles are the nodes and calls to setRole() the edges.


I have found that dealing with persons, companies and roles is something that is repeated over and over again. Martin Fowler's analysis patterns book (with Ward Cunningham and Ralph Jackson) has an extensive discussion that is worth reading in depth.

An online version of the "Dealing with roles" chapter (or a summary of it, I don't have the book handy) can be found as: http://martinfowler.com/apsupp/roles.pdf.

Martin Fowler's site also has an entire section dealing with analysis patterns: http://martinfowler.com/apsupp/roles.pdf


You may want to look at Coad's Domain-Neutral Component:

http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf

This has people with multiple roles but takes things a bit further by including events (moment-intervals). He also talks a lot about modelling in colour which is interesting but don't let it put you off - I think the ideas are pretty sound.

Ian.


Take a look at Replacing Conditional Dispatcher with command


I would make an interface with a do method, like

interface Action {
    void do()
}

And then define a Map<String, Action>, so that given a role, the related action could be retrieved by actionMap.get(role). Then simply call do() on the action by actionMap.get(role).do()


I would say that a Role HAS-A Person. I'd have a Role interface whose concrete implementation would wrap a Person and decorate it with whatever new capabilities I needed.

public interface Role
{
    Person getPerson();
    void action(); // might need more here
};

public class Person
{
   // whatever fields you need
}

public class Admin
{
    private Person person;

    public Admin(Person p) { this.person = person; }

    public void action() { } // some some admin stuff.
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜