返回多个枚举值的最佳方法是什么? (java和C#)

时间:2009-11-17 22:38:40

标签: c# java enums bit-fields

删除了更多原始内容,以便更容易引用问题:

所以我有一个House类有一个方法House.buy(Person p),导致这个人买房。我想知道是否可以让人买房子,所以我也有一个方法House.tryBuy(Player p),如果人可以买房子的话。我有一个枚举BuyState,其值为OKNotEnoughMoneyAlreadyOwned。有几个不同的条件需要满足,客户想知道哪个失败了。但是如果多个条件失败怎么办?我可以有一个层次结构,比如House已经拥有且Person没有足够的钱,返回BuyStates.AlreadyOwned。但这只能让我告诉客户一件事。

我可以有N个单独的条件和一个带有N * N值的枚举,比如ConditionA_AND_ConditionB_ANDConditionC,但由于几个原因,这根本没有意义。我知道有些字段,每个条件都有一点,但它们看起来太低级,实现起来很烦人,而且不可扩展。所以我需要一种从枚举中返回值列表的方法,那么这样的类怎么样:

class C<type_of_enum> {
    private List<type_of_enum> values;

    //etc etc
}

这是“最佳”设计吗?

(保留关于java和C#的问题以保持答案有效)

8 个答案:

答案 0 :(得分:12)

在Java中,最自然的方法是使用EnumSet。构建一个的例子:

return EnumSet.of(BuyConditions.NotEnoughMoney, BuyConditions.AlreadyOwned);

答案 1 :(得分:8)

在C#中,我会选择一个标志枚举。

检查Designing Flags Enumerations

答案 2 :(得分:7)

  

这是“最佳”设计吗?

这似乎是一个奇怪的设计。在用软件对现实世界进行建模时,为了使模型反映现实而付出代价;这些模型更容易理解,维护和扩展。

首先,房子不是买人的东西。一个人是买房子的东西。 “购买”方法应该是“人”,而不是“房子”。

其次,房子不是决定房子是否可以买的东西。房屋的所有者是确定是否可以购买的实体。 (为什么有一个“已经拥有”的错误条件?当然房子已经拥有。有人拥有它。)

第三,你可能不得不考虑在多个买家可能试图一次性购买房屋的世界中会发生什么。实际上,卖方收集各种报价并进行还价,销售可能取决于其他事件,等等。模型中是否应该包含所有这些内容?如果是的话,在哪里?可能处于代表所有者的对象的状态,因为所有者是正在协商的事物。

第四,实际上,购房交易通常涉及一个受信任的第三方进行托管,以及其他各方,例如卖方和买方的贷方可能提供资金或持有留置权。这些派对是否反映在这个模型中?

第五,如果您打算在模型中添加“无法购买此房屋的原因”,那么您所描述的是政策系统。在这种情况下,将策略表示为系统中的第一类对象,以便可以像处理任何其他对象一样对它们进行操作。业主有关于他们将在何种条件下出售的政策。银行有关于贷款条件的政策。等等。

在此模型中,您的问题变为“询问政策解决引擎,以确定买方是否满足每个相关机构的政策树为购买特定房屋而施加的所有必要条件”。换句话说,问题是“可以X买Y?”不是X或Y要弄清楚的;这是政策解决引擎的一个问题,而这就是为什么会给你一张X未能实现的政策清单,以便从Z购买Y.

有意义吗?

答案 3 :(得分:1)

是的,这似乎是最好的设计。您希望返回一个列表(或一组)原因,因此将其作为一组返回是很自然的。

答案 4 :(得分:1)

我认为返回一系列不买的理由是很好的;它非常能表达你想要做的事情。一组可能更合适,但只是稍微如此。

答案 5 :(得分:0)

对我来说听起来不错。您想要返回失败条件的列表,并且您将返回失败条件的列表。

答案 6 :(得分:0)

您可以使用回调:

class House {

    public void buy(Result result) {

        if (true)
            result.ok(this);
        else
            result.error(this, EnumSet.of(Status.NOT_ENOUGH_MONEY, Status.ALREADY_OWNED));

    }

}

enum Status {

    NOT_ENOUGH_MONEY,
    ALREADY_OWNED

}

interface Result {

    public void ok(House house);

    public void error(House house, EnumSet<Status> status);

}

答案 7 :(得分:0)

您可以将列表指针传递给函数,而不是返回列表,以便在出现错误情况时填充原因。函数本身可以返回0表示成功,1表示失败,在这种情况下,您可以检查列表的内容。

这样可以更快地知道函数调用是否成功,假设大部分时间它都会成功。