我无法弄清楚我应该采用哪种设计模式。说我有这样的课:
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;
....
简而言之,一个人有角色,而do()方法取决于他的角色是什么。在某些情况下,他可能不得不转换角色。我认为这个do()应该是抽象的(更多是因为将来可能会定义其他角色)---但是如何?应该有角色类吗?
任何帮助将不胜感激。
修改
感谢您节省时间,人们。我想补充一点。我确实认为(至少作为一个想法)许多建议的解决方案。以下是我的困难:如果我将Person类(例如PersonTypeA,personTypeB等)子类化,并将每个特定角色分配给适当的人员类型,那么在切换角色时我会遇到困难(例如,工程师成为会计师! ---很奇怪,至少可以说。
另一方面,如果我为每个角色创建类;然后(1)一个角色感觉不像是一个对象,因为(至少在我的情况下)角色没有属性而只有方法。因此,role_A_1与role_A_2没有什么不同。但对于每个人,我都必须创建一个新的角色对象 - 即使他们都有相同的角色。
我不确定自己是否清楚,我不确定我的观点是否有意义。
答案 0 :(得分:7)
不是以设计模式的方式,而是以更合理的方式:
而不是拥有一个巨大的'if角色就是这样,那么,如果是这个'语句,那么某种带有DoThis()方法的Role类会更容易。
一个人有一个角色。一个人可以DoThis(),然后角色也可以DoThis()。
而不是一个人根据角色说出他们做了什么,角色说出他们能做什么。
答案 1 :(得分:6)
我看到这里也出现了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);
}
}
在此示例中,您通过询问当前分配的 Context
对象来委派Role
对象执行的操作。具体角色本身具有定义角色之间转换的方法。实际上,这里出现的是一个简单的状态机,其中具体的Role
是节点并调用setRole()
边缘。
答案 2 :(得分:1)
你可能想看看Coad的Domain-Neutral Component:
http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf
这让人们有多个角色,但通过包含事件(时刻间隔)可以更进一步。他还谈了很多关于颜色建模的内容,这很有意思,但不要让它让你失望 - 我认为这些想法很合理。
伊恩。
答案 3 :(得分:1)
我发现与人,公司和角色打交道是一遍又一遍的重复。 Martin Fowler的分析模式书(与Ward Cunningham和Ralph Jackson一起)进行了广泛的讨论,值得深入阅读。
“处理角色”一章的在线版本(或其摘要,我没有这本书很方便)可以找到:http://martinfowler.com/apsupp/roles.pdf。
Martin Fowler的网站还有一整节涉及分析模式:http://martinfowler.com/apsupp/roles.pdf
答案 4 :(得分:0)
答案 5 :(得分:0)
我会用do方法创建一个接口,比如
interface Action {
void do()
}
然后定义Map<String, Action>
,以便在给定角色的情况下,actionMap.get(role)
可以检索相关操作。然后,只需通过do()
actionMap.get(role).do()
操作即可
答案 6 :(得分:0)
我会说角色是一个人。我有一个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.
}