首页 > 解决方案 > Switch 语句 vs Enum 变量

问题描述

我有一个具有以下方案的枚举:

public enum Enum{
    A,
    B,
    C,
    D
    //...
}

在另一堂课中,我score根据这个枚举计算 a。

我应该使用哪种方法,为什么?

解决方案1:

我使用 switch 语句

public int score(Enum value)
{
    switch(value){
        case Enum.A:
            this.score *= 25;
            break;
        case Enum.B: 
            this.score *= 7;
            break;
        case Enum.C:
            this.score *= 2;
            break;
        //...
    }
    return this.score;
}

解决方案2:

我向我的 Enum 添加了一个变量

public enum Enum{
    A(25),
    B(7),
    C(2),
    D(16),
    //...
    Z(100);

    private final int scoreMultiplier;

    Enum(int scoreMultiplier){
        this.scoreMultiplier = scoreMultiplier;
    }

    public int getScoreMultiplier(){return scoreMultiplier;}
}

然后,我的评分方法:

public int score(Enum value)
{
    this.score *= value.getScoreMultiplier();
    return this.score;
}

标签: javaenumsswitch-statement

解决方案


这是另一种选择:访问者模式。

定义访问者界面:

public interface Visitor<RESULT> {
    RESULT visitA(ABCD a);

    RESULT visitB(ABCD b);

    RESULT visitC(ABCD c);

    RESULT visitD(ABCD d);
}

让您的枚举接受访问者:

public enum ABCD {
    A {
        @Override
        public <RESULT> RESULT accept(Visitor<RESULT> visitor) {
            return visitor.visitA(this);
        }
    },
    B {
        @Override
        public <RESULT> RESULT accept(Visitor<RESULT> visitor) {
            return visitor.visitB(this);
        }
    },
    C {
        @Override
        public <RESULT> RESULT accept(Visitor<RESULT> visitor) {
            return visitor.visitC(this);
        }
    },
    D {
        @Override
        public <RESULT> RESULT accept(Visitor<RESULT> visitor) {
            return visitor.visitD(this);
        }
    };

    public abstract <RESULT> RESULT accept(Visitor<RESULT> visitor);
}

不,您可以将基于枚举的函数捕获为访问者。例如计算分数:

public static int score(ABCD abcd) {
    return abcd.accept(new Visitor<Integer>() {
        @Override
        public Integer visitA(ABCD a) {
            return 25;
        }
        @Override
        public Integer visitB(ABCD b) {
            return 7;
        }
        @Override
        public Integer visitC(ABCD c) {
            return 2;
        }

        @Override
        public Integer visitD(ABCD d) {
            return 16;
        }
    });
}

从一方面来说,这在某种意义上提供了一定的安全性,如果您添加新的枚举项,您将需要使用新visitX方法扩展访问者界面 - 因此所有现有的访问者实现。

另一方面,您不会用要在枚举上执行的操作的语义来污染您的枚举。如果您需要向枚举添加更多功能,则无需扩展它。只需编写新的访问者实现。


推荐阅读