简体   繁体   English

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

[英]What's the best way to return multiple enum values? (java and C#)

more of original content deleted to make question easier to reference: 删除了更多原始内容,使问题更易于参考:

So I have a House class that has a method House.buy(Person p) , causing the person to buy the house. 因此,我有一个House类,该类具有方法House.buy(Person p) ,导致该人购买房屋。 I want to know if its possible for the Person to buy the House, so I also have a method House.tryBuy(Player p) that returns if the Person can buy the house. 我想知道该人是否有可能购买房屋,因此我还有一个方法House.tryBuy(Player p) ,如果该人可以购买该房屋,则返回该方法。 I have an enum BuyState with values like OK , NotEnoughMoney , and AlreadyOwned . 我有一个枚举BuyState ,其值如OKNotEnoughMoneyAlreadyOwned There's a few different conditions to be satisfied, and the client would like to know which failed. 需要满足一些不同的条件,客户想知道哪个失败。 But what if multiple conditions fail? 但是,如果多个条件失败了怎么办? I could either have a hierarchy, like if House is already owned and Person doesn't have enough money, return BuyStates.AlreadyOwned . 我可以有一个层次结构,例如如果House已经拥有并且Person没有足够的钱,则返回BuyStates.AlreadyOwned But this only lets me tell the client one thing. 但这只能让我告诉客户一件事。

I could have N separate conditions and an enum with N*N values, like ConditionA_AND_ConditionB_ANDConditionC but that makes no sense at all for several reasons. 我可以有N个单独的条件,以及一个具有N * N值的枚举,例如ConditionA_AND_ConditionB_ANDConditionC但这出于几个原因根本没有任何意义。 I know there are bit-fields, with a bit for each condition, but they just seem too low-level, annoying to implement, and not-scalable. 我知道有一些位域,每个条件都有一些位,但是它们似乎太底层了,难以实现且无法扩展。 So I need a way to return a list of values from an enum, So how about a class like this: 所以我需要一种从枚举返回值列表的方法,那么像这样的类怎么样:

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

    //etc etc
}

Is this the "best" possible design? 这是“最佳”的设计吗?

(keeping this question about java AND C# to keep answers valid) (保留有关java和C#的问题以使答案有效)

In Java, the most natural way to do this is with EnumSet . 在Java中,最自然的方法是使用EnumSet An example of constructing one: 构造一个例子:

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

In C# I would go for a flags enumeration. 在C#中,我将进行标志枚举。

Check Designing Flags Enumerations . 检查设计标志枚举

Is this the "best" possible design? 这是“最佳”的设计吗?

This seems like a bizarre design all around. 这似乎是一个奇怪的设计。 When modeling real-world things in software, it pays dividends to make the model reflect reality; 在用软件对现实世界进行建模时,它会付出分红,以使模型反映现实。 such models are easier to understand, maintain, and expand. 这样的模型更容易理解,维护和扩展。

First off, a house is not something that buys a person. 首先,房子不是买人的东西。 A person is something that buys a house. 一个人就是买房的东西。 The "buy" method should be on "person", not on "house". “购买”方法应该在“人”上,而不是在“房屋”上。

Second, a house is not something which determines whether a house can be bought. 第二,房屋不是决定是否可以购买房屋的东西。 The owner of the house is the entity which determines whether it can be bought. 房子的所有者是确定是否可以购买的实体。 (Why is there an "already owned" error condition? Of course the house is already owned. Someone owns it.) (为什么会有“已拥有”错误条件?当然房屋已经拥有。 有人拥有它。)

Third, you might have to consider what happens in a world where multiple buyers might be attempting to buy the house all at once. 第三,您可能必须考虑在多个买家可能试图一次全部购买房屋的世界中发生了什么。 In reality, the seller collects various offers and makes counteroffers, sales may be contingent upon other events, and so on. 实际上,卖方收集各种报价并提出还价,销售可能取决于其他事件,依此类推。 Should all of those things be present in the model? 所有这些东西都应该存在于模型中吗? If so, where? 如果是这样,在哪里? Probably in the state of the object representing the owner, since the owner is the thing being negotiated with. 由于所有者是与之协商的事物,因此可能处于表示所有者的对象的状态。

Fourth, in reality, house purchasing transactions usually involve a trusted third party to do escrow, and various other parties such as the seller's and buyer's lenders who might be providing funds or holding liens. 第四,实际上,购房交易通常涉及受信任的第三方进行托管,以及可能提供资金或持有留置权的各种其他各方,例如卖方和买方的贷方。 Are those parties reflected in this model? 那些当事方反映在该模型中吗?

Fifth, if your intention is to add to your model "reasons why you cannot buy this house", then what you are describing is a policy system . 第五,如果您打算在模型中添加“为什么不能买这套房子的理由”,那么您所描述的是一个政策体系 In that case, represent policies as first-class objects in your system, so that they can be manipulated like any other objects. 在这种情况下,请将策略表示为系统中的一流对象,以便像其他任何对象一样对它们进行操作。 Owners have policies about under what conditions they will sell. 业主有关于在什么条件下出售的政策。 Banks have policies about the conditions under which they will lend. 银行制定有关放贷条件的政策。 And so on. 等等。

In this model, your problem becomes "ask the policy resolution engine if the buyer meets all the necessary conditions imposed by every relevant agency's policy trees in order to purchase a given house". 在此模型中,您的问题变成“如果购买者满足每个相关机构的政策树强加的所有必要条件才能购买给定房屋,请向政策解决引擎咨询”。 In other words, the question "can X buy Y?" 换句话说,问题“ X可以买Y吗?” is not for either X or Y to figure out; X或Y都不知道; it's a matter for a policy resolution engine to work out, and THAT thing is what gives you back a list of the policies X has failed to fulfill in order to purchase Y from Z. 制定政策解析引擎是一件很重要的事情,这就是让您返回X未能从Z购买Y的政策清单的原因。

Make sense? 说得通?

Yes, that does seem like the best design. 是的,这似乎是最好的设计。 You want to return a list (or set) of reasons, so it's natural to return it as a set. 您想返回一个原因列表(或集合),因此很自然地将其作为集合返回。

I think returning a list of reasons not to buy is great; 我认为返回不购买原因的清单很不错; it's very expressive of what you're trying to do. 它很能表达您的意图。 A set would probably be more appropriate, but only slightly so. 设置一组可能会更合适,但稍微合适一点。

It sounds fine to me. 对我来说听起来不错。 You want to return a list of the conditions that failed, and you're returning a list of the conditions that failed. 您要返回失败条件的列表,并且要返回失败条件的列表。

You could use a callback: 您可以使用回调:

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);

}

Instead of returning a list, you can pass a list pointer to the function, to be filled up with reasons in case error conditions arise. 您可以将列表指针传递给该函数,而不用返回列表,以将其填充以防出现错误情况。 The function itself can return 0 to indicate success and 1 for failure, in which case you can check the content of the list. 函数本身可以返回0表示成功,返回1表示失败,在这种情况下,您可以检查列表的内容。

This will make it faster to know if the function call was successful or not, assuming most of the time it will be success. 假设大多数情况下将成功,这将使它更快地知道函数调用是否成功。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 SQL 中模拟标志枚举(c#)的最佳方法是什么? - What's the best way to emulate a flags enum (c#) in SQL? C#创建被多个类使用的枚举的最佳方法是什么? - C# What is the best way to create an enum that is used by multiple classes? C#:检查一组枚举值的最佳方法? - C#: Best way to check against a set of Enum Values? 在C#中实现Rust枚举的最佳方法是什么? - What is the best way to implement a Rust enum in C#? 使用枚举实现层次结构的最佳C#模式是什么? - What's the best C# pattern for implementing a hierarchy with an enum? C#比较双精度值和一系列值并返回两个文本值的最佳方法是什么 - C# What is the best way to compare a double value to a range of values and return two text values 在 C# 中表示参数化枚举的最佳方式? - Best way to represent a parameterized enum in C#? 在 C# 字典中设置所有值的最佳方法是什么<string,bool> ? - What's the best way to set all values in a C# Dictionary<string,bool>? 在C#中使用一对(三重等)值作为一个值的最佳方法是什么? - What's the best way of using a pair (triple, etc) of values as one value in C#? 在C#中创建具有多个屏幕的Windows Mobile应用程序的最佳方法是什么? - What's the best way to create a Windows Mobile application with multiple screens in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM