0

I want to not repeat a specific piece of code and need advice on how to structure it better

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

I'd like to able to consolidate the logic in getTabName() and getUserCount() methods.

Having switch statements checking for the same thing doesn't seem efficient, but they are returning two different things....

4

7 に答える 7

3

私が考えることができる唯一の解決策は、シンプルで過度に設計されていないことのバランスがとれている (コメントの 1 つで大きく強調されているように) です。

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

s と節のenum代わりにJava を使用します。列挙型の良いところは、宣言した値とまったく同じになるように値を制限できることです。static intswitch

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 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 に答える
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 に答える
0

Beanクラスを使用し、そのクラスへのアクセスと変更のための属性/操作を追加することをお勧めします。コンストラクターインジェクションまたはセッターインジェクションを実行できます。コードをBeanから切り離すセッターインジェクションが好きです。

そして、Beanを返すメソッドを記述し、スイッチでBeanの値を設定してBeanを返します。これにより、実際にコードを1つの場所に保持し、すべてのデータをまとめて維持します。私の見解では、これが最も簡単な解決策です。これがお役に立てば幸いです。

于 2012-07-16T20:45:53.883 に答える
0

各値の CTOR として必要な値 (「TA」など) を取る列挙型を使用し、それを CTOR 内に格納し、メソッドを使用してこの値を返します。

この方法では、スイッチを使用する必要はありません。

リンク: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

于 2012-07-16T19:45:46.750 に答える