在自己的类中声明的枚举结构是业务逻辑类的成员变量。该枚举基本上代表了其他类的状态。
虽然我已多次重新审视这个问题,但替换或删除这些案例陈述对我来说非常令人沮丧。
几个业务逻辑方法简单地遍历枚举,并通过分配相同枚举的其他值和其他属性来更改该类的状态。
public enum MyEnum{ A,B,C,D }
业务逻辑类将此枚举作为成员:
public class BusinessLogic {
private MyEnum CurrentSelection;
private int propertyX;
private int propertyY;
public void operation1(){
switch(CurrentSelection){
case A: {alter propertyX this way; break;}
case B: {alter propertyY this way; break;}
case C: {alter propertyX that way; break;}
case D: {alter propertyY that way; break;}
}
}
public void operation2(){
switch(CurrentSelection){
case A: {CurrentSelection=MyEnum.B; break;}
case B: {CurrentSelection=MyEnum.C; break;}
....etc
}
}
public void operation3(){
switch(CurrentSelection){
case A: {CurrentSelection=MyEnum.D; break;}
case B: {CurrentSelection=MyEnum.A; break;}
....etc
}
}
}
另一个客户端类将实例化业务逻辑类,初始化其属性,然后使用其操作方法。
我成功完成的操作(在SO的帮助下)将操作方法封装到命令模式结构中,因此我可以在没有任何case语句的情况下调用操作。 (here)。
我想我的麻烦是如何将case语句封装在我的业务逻辑类中。我怀疑我需要多态性和适当的数据结构。
重构专家建议每个case语句应该是一个通用接口的实现。但是如果我有3个方法迭代4个成员的枚举,这意味着我可能需要3个接口,每个接口有4个实现,给我12个类(加上3个接口)。那不是班级超载吗?逻辑在这3种方法中运行良好,但问题是重复的开关/案例陈述。
有没有办法重构那些switch语句,但避免了多态性名称中的无数其他类?是否有可能将迭代的枚举部分分解出来?或者只是重构的情况(逻辑在哪里)?
作为第一步,我完全删除了这些方法,让他们实现了一个简单的界面:
public interface Command {
void execute();
}
因此,它的操作方法实现了命令接口:
public class Operation1 implements Command {
private void doOperation1(){
switch(CurrentSelection){
..all the cases here
}
}
public void execute() {
doOperation1();
}
}
正如我所看到的那样,它将购买我更清洁的业务逻辑类,但切换案例的痕迹仍然存在,对吗?
答案 0 :(得分:1)
你可以在接口中包含所有三种方法,并且具有该接口的不同实现(每个枚举一个),并且让这个buisness类委托调用..
也用于更改状态,使操作的返回值为该公共接口,以便在调用这些方法时,调用类可以返回下一个状态的相应对象。
答案 1 :(得分:1)
要详细说明我的评论,并接近我认为rmn所说的话,你可以做以下事情:
public interface MyInterface {
operation1(property);
operation2(property);
operation3(property);
}
public enum MyEnum implements MyInterface {
A {
operation1(property) {
//Do Stuff
}
operation2(property) {
//Do Stuff
}
operation3(property) {
//Do Stuff
}
},
B {
operation1(property) {
//Do Stuff
}
operation2(property) {
//Do Stuff
}
operation3(property) {
//Do Stuff
}
},
C {
operation1(property) {
//Do Stuff
}
operation2(property) {
//Do Stuff
}
operation3(property) {
//Do Stuff
}
},
D {
operation1(property) {
//Do Stuff
}
operation2(property) {
//Do Stuff
}
operation3(property) {
//Do Stuff
}
}
}
这使得你有一个命令模式 - 即根据所选的不同元素为你工作的东西。它也类似于状态模式,尽管这里的重点是执行而不是数据或数据状态。
希望这有帮助。
答案 2 :(得分:0)
正如您可能从其他回答中猜到的那样,这是一个常见问题,并且已经被Martin Fowler编成了重构。看一下重构Replace Conditional with Polymorphism。 Joshua Kerievsky(Replace Conditional with Strategy)也进行了类似的编纂重构。