Java:String类型的返回必须转换为3种不同类型中的一种。如何避免开关/外壳呢?

时间:2011-03-15 20:17:59

标签: java

我浏览了几个答案,但没有运气。实际上,解释我试图用文字做什么有点复杂,所以让我们看看一些snipets:

我有4个属性:

private int pageCount; //type 1
private int[] monoColorCount; //type 2
private float cost;  //type 3
private int type;

但是在任何时候,一个对象只对其中一个有价值。它们由一个返回字符串(从XML解析)的方法提供,并根据类型我将知道哪个具有值。我的第一次尝试是一个开关/案例,一个有效的解决方案,但效率很低:

switch(type){
        case 1: pageCount = Integer.parseInt(QuotasBalance.getUserQuota(user, domain)); break;
        case 2: StringTokenizer st = new StringTokenizer(QuotasBalance.getUserQuota(user, domain), "|");
                monoColorCount = new int[]{Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken())}; break;
        case 3: cost = Float.parseFloat(QuotasBalance.getUserQuota(user, domain));
    }

也许我之前应该提到过:我已经完成了Java 1.4,因此是StringTokenizer。在这种情况下,每次我需要来自外部类的值时,我都必须在类型上使用开关/案例:

switch(myQuotaInstance.getType){
        case 1: /*Do something with pageCount*/
        case 2: /*Do something with monoColorCount*/
        case 3: /*Do something with cost*/
    }

毋庸置疑,这太荒谬了。我也尝试过多态和反射,但由于我还没有完全掌握反射的概念,那是另一个死胡同。我尝试创建一个不同的类来仅封装那些仅考虑委托不可避免的三个属性。好吧,我想我已经说清楚了。现在我愿意接受有关如何解决这个问题的建议。

4 个答案:

答案 0 :(得分:2)

你可以抓住战略模式。首先有一个界面。

public interface Strategy {
    void execute(QuotaInstance instance);
}

然后有一个映射

private Map strategies = new HashMap();

{
    strategies.put(Integer.valueOf(1), new PageCountStrategy());
    // ...
}

然后执行如下

((Strategy) strategies.get(Integer.valueOf(type))).execute(myQuotaInstance);

execute()内,您只需访问/修改实例。

答案 1 :(得分:1)

@BalusC为什么Strategy优于State?我建议说状态,因为在这种类型的代码中我似乎很自然,但我记得你关于模式的“臭名昭着的帖子”,所以我猜你是对的;)

答案 2 :(得分:0)

您的配额对象在其生命周期内是否会更改其类型?

如果没有,最好创建三个不同的类(可以有一个公共接口或基类)。

class CostQuota extends Quota {
}

class PageCountQuota extends Quota {
}

class ColorPageCountQuota extends Quota {
}

它们中的每一个都可以有一个字符串构造函数来进行解析,因此在创建对象时只需要一个类型的开关。 (但您也可以将它们序列化为不同的XML元素,因此根本不需要int类型。)

答案 3 :(得分:0)

嗯......我研究了战略和国家模式,他们完全矫枉过正。实际上,我以一种非常简单的方式(甚至是一种不同的方式)解决了这个问题:我在应用程序第3层中将字符串的返回值转换为正确的类型。当我意识到这个值类型在到达第一层(UI)之前无关紧要时,我决定将它作为一个字符串传递到第一层,我会切换它(就像我在做的那样)在第3次)和连铸,我正在调用一个不同的方法来构建UI本身,因为它依赖于这个值类型来构建,但不依赖于值本身。是的,不是“优雅”或任何东西,但在这个领域,我认为它很适合(总的来说,Quota类实际上可以是静态的。)

但是感谢您的评论,我已经完成了状态和策略模式,并最终学习(实际上,“重新学习”)一些在任何地方都非常有用的模式 - 例如方法模板和工厂。

方法模板如此明显,却被忽视了...... ^^