我有两种类型的交易: - 收入 - 费用
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?我应该使用工厂模式吗?
答案 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枚举不会有害。