【问题标题】:Which Design Pattern should I use to model a Person-Role relationship?我应该使用哪种设计模式来模拟人-角色关系?
【发布时间】:2017-01-23 01:26:10
【问题描述】:

我只是想不通我应该在这里采用哪种设计模式。假设我有这样的课:

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;

    ....

简而言之,Person 具有角色,do() 方法取决于他的角色。在某些情况下,他可能不得不转换角色。我认为这个 do() 应该被抽象化(更是如此,因为将来可能会定义其他角色)---但是如何呢?应该有 Role 类吗?

任何帮助将不胜感激。

编辑:

感谢您抽出时间,各位。我想再补充一件事。我确实认为(至少作为一个想法)许多建议的解决方案。以下是我的困难:如果我将 Person 类(例如 PersonTypeA、personTypeB 等)子类化,并将每个特定角色分配给适当的人员类型,那么我在转换角色时就会遇到困难(例如,工程师变成了会计师! ---至少可以说很奇怪。

另一方面,如果我为每个角色创建类;那么(1)一个角色感觉不像一个对象,因为(至少在我的情况下)一个角色没有属性而只有方法。因此,role_A_1 与 role_A_2 没有什么不同。但是对于每个人,我都必须创建一个新的角色对象——即使他们都共享相同的角色。

我不确定我是否说清楚了,我不确定我的观点是否有道理。

【问题讨论】:

  • 所以一个用户永远不能同时拥有 2 个以上的角色。 IE:负责人,开发人员?
  • 感谢您的所有回复。我会再考虑再回复你。
  • 如果您想提供更多信息,请更新您的问题或离开 cmets。我已将您留下的答案转换为评论。

标签: java design-patterns


【解决方案1】:

不是以设计模式的方式,而是以逻辑的方式:

与其有一个巨大的“如果角色是这个,那就做那个,否则如果是这个”语句,具有 DoThis() 方法的某种角色类会更容易。

一个人有一个角色。 Person 可以 DoThis() 并且 Role 也可以 DoThis()。

不是一个人根据角色说他们做什么,而是角色说他们可以做什么。

【讨论】:

  • Nitpick:do 是一个关键字,像 do() 这样的方法不会编译 ;)
  • 我将编辑我的答案。我只是离开了 OP 发布的代码。 ;-)
【解决方案2】:

我也看到State Pattern 出现在这里。例如,您可以按照以下方式设计一些东西:

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);
    }
}

在此示例中,您通过要求其当前分配 Role 对象来委托Context 对象执行的行为。具体角色本身具有定义角色之间转换的方法。实际上,这里出现的是一个简单的状态机,其中具体的 Roles 是节点,而对 setRole() 的调用是边。

【讨论】:

    【解决方案3】:

    我发现,与人、公司和角色打交道是一件不断重复的事情。 Martin Fowler 的分析模式书(与 Ward Cunningham 和 Ralph Jackson 合着)进行了广泛的讨论,值得深入阅读。

    “处理角色”章节的在线版本(或摘要,我手边没有这本书)可以找到:http://martinfowler.com/apsupp/roles.pdf

    Martin Fowler 的网站也有一整节涉及分析模式:http://martinfowler.com/apsupp/roles.pdf

    【讨论】:

      【解决方案4】:

      您可能想查看 Coad 的域中立组件:

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

      这有多个角色的人,但通过包含事件(时刻间隔)使事情更进一步。他还谈到了很多关于颜色建模的话题,这很有趣,但不要让它让你失望——我认为这些想法很合理。

      伊恩。

      【讨论】:

        【解决方案5】:
        【解决方案6】:

        我会用 do 方法做一个接口,比如

        interface Action {
            void do()
        }
        

        然后定义一个Map<String, Action>,这样给定一个角色,actionMap.get(role)就可以检索到相关动作。然后在actionMap.get(role).do()的操作上调用do()

        【讨论】:

          【解决方案7】:

          我会说一个角色有一个人。我有一个 Role 接口,它的具体实现将包装一个 Person 并用我需要的任何新功能装饰它。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多