在类中存储对象类型的最佳实践

时间:2016-08-24 17:20:18

标签: java enums const

我有两种类型的交易: - 收入 - 费用

class Transaction {
    final public static int IN = 0x1, OUT = 0x2;
    final private int type;

    Transaction(int type)
    {
        this.type = type;
    }

    public int getType() {
        return type;
    }

    // --- internal logic is same for both types ---
}

// create:
Transaction t = new Transaction(Transaction.IN);

此案例的最佳做法是什么?我应该宣布一个枚举?两个clases?我应该使用工厂模式吗?

4 个答案:

答案 0 :(得分:3)

我建议在这种情况下使用Enumeration,因为这样,您可以通过静态检查方式限制可能的值:

enum TransactionType {
    Income, Expense;
}

class Transaction {
    final private TransactionType type;

    Transaction(TransactionType type) {
        this.type = type;
    }

    public TransactionType getType() {
        return type;
    }

}

否则,可以向构造函数int提供任何Transaction(int type)值。

enum的另一个好处是,如果您愿意,以后可以向他们提供一些其他信息(例如,不同的格式化模式等)。

答案 1 :(得分:0)

这实际上取决于你最容易找到的东西。枚举的优点是你可以将它设置为任何枚举并传输实例并从itEnum获取值示例:

private enum ENUM{
    EX1, EX2
};

并称之为:

private ENUM instance = ENUM.EX1;

如果您想要检索值:

switch(instance){

case ENUM.EX1:

    break;
case ENUM.EX2:

    break;

}

以下是枚举示例:

enum Transaction { 

    IN(0x1), OUT(0x2); 

    private int marker; 
    Transaction(int marker) { 
    this.marker = marker; 
    } 

}

Enum更容易,是的。

Comparativly:

代码不同,呼叫也不同。但并不多。

主要区别在于您如何比较该值。您必须在切换循环中实际获取实例的值(instance.getType())。

两者都同样好,但在大多数情况下我都会使用enum,因为它可以节省我创建另一个类,因为我需要的只是一个枚举。虽然其他时候,枚举只是不削减它。在您的情况下,您似乎不能使用枚举(除非您将代码更改为"枚举可接受")。

  

此案例的最佳做法是什么?我应该声明一个枚举?

在这种情况下?也许。这完全取决于你。然而,Enum是最简单的存储方式。

答案 2 :(得分:0)

最佳做法实际上取决于用例。鉴于您在评论中添加的内容,enum似乎是更好的选择。 enum可以封装“标记”的附加信息。例如,您说您使用基于事务类型的颜色进行打印。为避免执行其他条件逻辑,您可以将该信息添加到enum值本身。例如:

enum TransactionType {
    IN(Color.GREEN), OUT(Color.RED);

    public final Color TEXT_COLOR;

    TransactionType(Color textColor) {
        TEXT_COLOR = textColor;
    }
}

它还通过编译时检查提供更安全的使用。通过让编译器检查正确的TransactionType s,您可以使代码更加虚拟化。虽然你仍然可以做TransactionType.valueOf("DUMMY"),但它并不是完全虚拟证明,但它比在任何可能需要使用标记的地方检查所有可能的混乱更好。

例如,您说需要查找给定类型的事务。你可以这样做:

List<Transaction> ins = transactions.stream()
    .filter(t -> t.getType() == TransactionType.IN).collect(Collectors.toList());

如果您的班级依赖于42值,则可以在其中投放int

List<Transaction> ins = transactions.stream()
    .filter(t -> t.getType() == 42).collect(Collectors.toList());

最糟糕的是,它只会返回一个空列表;没有编译或运行时错误,需要在某处验证值。

另外需要注意的是,如果它只是一个标记,您可以完全用Transaction替换enum类,但需要更多信息来确定。{/ p>

答案 3 :(得分:0)

这实际上取决于上下文,但如果你有:

public class Transaction {
    private double amount = 0.0d;
    public static Transaction newExpenseTx() {
        return new ExpenseTransaction();
    }
    public static Transaction newIncomeTx() {
        return new IncomeTransaction();
    }
    public void setAmount(double a) { amount = a; }
    public double getAmount() { return amount; }
    public abstract Color getColor();

    static class ExpenseTransaction extends Transaction {
        Color getColor() { return Color.RED; }
    }

    static class IncomeTransaction extends Transaction {
        Color getColor() { return Color.GREEN; }
    }
}

您可以看到您的调用者不需要知道子类,也不需要任何切换。

Transaction t1 = Transaction.newExpenseTx();
assertEquals("Exprense Transactions need to be red, has amount " +
                                                  t1.getAmount(),
                                             Color.RED, t1.getColor());

当然,如果您需要将类型作为值,则添加TransactionType枚举不会有害。