我参与了一个应用程序迁移项目。这个应用程序应该根据当前用户角色执行一些逻辑,所以这样的代码片段在代码中无处不在:
if ("Role1".equals(user.getUserRole())){
operationVersionForRole1();
} else if ("Role2".equals(user.getRole())){
operationVersionForRole2();
} else if ("Role3".equals(user.getRole())){
operationVersionForRole3();
}
大约有五个角色和近五十个操作,并且一些操作对于某些角色(近1000行代码)非常复杂,因此编程风格使源代码变得混乱且难以遵循。是否有任何已知的设计模式有助于在这种情况下组织源代码?嵌套的“if-else”感觉不对劲。
答案 0 :(得分:3)
是不是抽象工厂提供了一个接口,用于创建相关或依赖对象的族,而不指定它们的具体类?指定的角色将是创建具体实现的参数。 operationVersionForRoleX
可以设计为IOperation
接口的不同实现或策略。
interface IOperation
{
void Execute();
}
class OperationVersionForRoleX : IOperation
{
public void Execute()
{
// …
}
}
string role = "roleX";
IOperation operation = operationFactory.Create(role);
operation.Execute();
答案 1 :(得分:1)
Simmilar对卡萨布兰卡的回答。
我通常会避免在枚举中使用业务逻辑,因为他们的工作只是唯一性而且几乎不如其他所有类中的类。
public enum Role {
ROLE1 { public Actions getActions(){ return new Role1Actions() } },
ROLE2 { public Actions getActions(){ return new Role2Actions() } },
ROLE3 { public Actions getActions(){ return new Role3Actions() } };
}
我会使用与角色一样多的操作类型来创建Actions接口
public interface Actions {
void action1();
// useful when there are more than 1 different actions per role
// even if only 1 now, there will be more in the future
vpod action2();
}
然后,只使用您可以从角色中获得的操作
user.getUserRole()动作1();
user.getUserRole()动作2();
答案 2 :(得分:0)
您可以执行以下操作:所有操作都扩展Operation
超类,而Role
是实际对象而不是字符串:
public abstract class Operation {
public void execute(User user) {
user.getRole().apply(this);
}
public abstract void operationForRole1();
public abstract void operationForRole2();
public abstract void operationForRole3();
}
public enum Role {
ROLE1 { public void apply(Operation op) { op.operationForRole1(); } },
ROLE2 { public void apply(Operation op) { op.operationForRole2(); } },
ROLE3 { public void apply(Operation op) { op.operationForRole3(); } };
public abstract void apply(Operation op);
}
然后每个Operation
实现各种角色的逻辑,客户端只需调用operation.execute(user)
。在任何地方都没有if-else
。