0

我不想重复一段特定的代码,并且需要关于如何更好地构建它的建议

public static final int TAB_A= 0;
public static final int TAB_B= 2;
public static final int TAB_C= 3;
public static final int NO_TAB = -1;

public String getTabName() {
    switch (getTabId()) {
        case TAB_A:
            return "TA";
        case TAB_B:
            return "TB";
        case TAB_C:
            return "TC";
        default:
            return "NT";
    }
}

public string execute() {  
  setResults(getTabName());
}

public int getUserCount() {
    SomeVO vo = (SomeVO) getFirstResultSet().get(0);
    switch (getTabId()) {
        case TAB_A:
            return vo.getTabAResults();
        case TAB_B:
            return vo.getTabBResults();
        case TAB_C:
            return vo.getTabCResults();
        default:
            return vo.getSomeStuff();
    }        
}  

我希望能够整合getTabName()getUserCount()方法中的逻辑。

让 switch 语句检查相同的东西似乎效率不高,但它们返回了两种不同的东西......

4

7 回答 7

3

我能想到的唯一解决方案是在简单和不过度设计之间取得平衡(正如其中一条评论中强调的那样)是:

private <T> T mapFromTabId(T a, T b, T c, T def) {
    switch (getTabId()) {
        case TAB_A:
            return a;
        case TAB_B:
            return b;
        case TAB_C:
            return c;
        default:
            return def;
    }
}

你像这样使用它:

public String getTabName() {
    return mapFromTabId("TA", "TB", "TC", "NT");
}

public int getUserCount() {
    return mapFromTabId(vo.getTabAResults(), vo.getTabBResults(), vo.getTabCResults(), vo.getSomeStuff());
}

这种方法的唯一问题是所有参数都被急切地评估,这在你的情况下不是问题,但在其他情况下可能是问题。

于 2012-07-16T19:50:55.567 回答
2

下面是一个使用 enum 做脏活的例子:

import java.lang.reflect.Method;

public class Test {

    public enum TABS {
        TAB_A("TA", "getTabAResults"),
        TAB_B("TB", "getTabBResults"),
        TAB_C("TC", "getTabCResults"),
        NO_TAB("NT", "getSomeStuff");

        private String name, method;

        private TABS(String name, String method) {
            this.name = name;
            this.method = method;
        }

        public String getName() {
            return name;
        }

        public int getResults(SomeVO vo) {
            int result = -1;
            try {
                Method m = vo.getClass().getMethod(method);
                result = (Integer) m.invoke(vo, (Object[]) null);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return result;
        }
    }

    static class SomeVO {
        public int getTabAResults() {
            return 1;
        }

        public int getTabBResults() {
            return 2;
        }

        public int getTabCResults() {
            return 3;
        }

        public int getSomeStuff() {
            return 4;
        }
    }

    public static void main(String[] args) {
        SomeVO someVO = new SomeVO();
        System.out.println(TABS.TAB_A.getName() + " is "
                + TABS.TAB_A.getResults(someVO));
        System.out.println(TABS.TAB_B.getName() + " is "
                + TABS.TAB_B.getResults(someVO));
        System.out.println(TABS.TAB_C.getName() + " is "
                + TABS.TAB_C.getResults(someVO));
        System.out.println(TABS.NO_TAB.getName() + " is "
                + TABS.NO_TAB.getResults(someVO));
    }
}
于 2012-07-16T20:01:28.667 回答
1

我会使用 Javaenum而不是static ints 和switch子句。枚举的好处是您可以将值限制为您声明的值。

public enum AnEnum {
    VAL_A {
        public String getName() { return "A"; }
        public int getResult(Thing t) { return t.getResultsA(); }
    };

    public abstract String getName();
    public abstract int getResult(Thing t);
}

还值得一看Oracle的枚举文档

于 2012-07-16T19:50:23.790 回答
1

为选项卡的公共方面创建一个接口或抽象类,然后为每个方面使用实现类。在伪代码中:

public abstract class Tab {
    public abstract String getTabName();
    public abstract int getUserCount();

    // ...
}

public final class TabA extends Tab {
    private static final String NAME = "TA";

    // ...

    @Override
    public String getTabName() {
        return NAME;
    }

    @Override
    public int getUserCount() {
      SomeVO vo = (SomeVO)getFirstResultSet().get(0);
      return vo.getResults();
    }
}

您可以使用枚举来维护它们的列表,但要小心将实现逻辑放入枚举中。

于 2012-07-16T21:06:11.687 回答
1

像这样使用枚举:

public static enum TableType {

    TAB_A(0, "TA"){
        private int _getUserCound(SomeVO vo){
            return vo.getTabAResults();
        }
    },
    TAB_B(2, "TB"){
        private int _getUserCound(SomeVO vo){
            return vo.getTabBResults();
        }
    },
    TAB_C(3, "TC"){
        private int _getUserCound(SomeVO vo){
            return vo.getTabCResults();
        }
    },
    NO_TAB(-1, "NT"){
        private int _getUserCound(SomeVO vo){
            return vo.getSomeStuff();
        }
    };

    int id;
    String name;
    private TableType(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    private abstract int _getUserCound(SomeVO vo);

    public int getUserCount(){
        SomeVO vo = (SomeVO) getFirstResultSet().get(0);
        return _getUserCound(vo);
    }

    public static TableType fromId(int id){
        for (TableType v : values()){
            if (v.getId() == id) return v;
        }
        return NO_TAB;
    }

}

public String getTabName() {
    return TableType.fromId(getTabId()).getName();
}

public string execute() {
    setResults(getTabName());
}

public int getUserCount() {
    return TableType.fromId(getTabId()).getUserCount();
}
于 2012-07-16T19:53:05.707 回答
0

使用枚举作为其每个值的 CTOR 获取您需要的值(如“TA”,...),将其存储在 CTOR 中,并使用方法返回此值。

这样你就不需要使用开关了。

链接: http ://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

于 2012-07-16T19:45:46.750 回答
0

最好使用 bean 类并添加属性/操作以对该类进行访问和变异。您可以进行构造函数注入或 Setter 注入,我更喜欢 Setter 注入,它将我的代码与 bean 分离。

并编写一个返回 Bean 的方法,在 switch 中设置 bean 中的值并返回 bean。通过它,您实际上是在一个地方维护您的代码并将所有数据保存在一起。在我看来,这是最简单的解决方案。希望这对您有所帮助。

于 2012-07-16T20:45:53.883 回答