什么是一个好的数据结构来表示比枚举更复杂但不完全是类的字段?

发布于 2024-10-17 04:43:24 字数 2173 浏览 4 评论 0原文

我正在编写一个涉及划船的程序,并且正在创建一个名为“BoatType”的不可变类来表示现有的不同“类型”的船。这变得越来越复杂,因为有许多类型需要独特的描述。

BoatType 应具有以下内容:

  • SCULL 或 SWEEP 类型
  • 数字,表示船上可容纳的人数
  • PORT 或 STARBOARD 类型,但仅当第一种类型为 SWEEP
  • 表示 COXED 的布尔值或 UNCOXED,通常仅用于 SWEEP

由于在赛艇世界中仅存在这些字段的某些组合,这一事实甚至使情况变得更加复杂。我希望我的程序能够轻松枚举访问这些标准类型,而无需创建新的 BoatType 对象。这些是完整的:

SCULL 8
双桨4
双桨2
双桨1
横扫 8 端口 COXED
SWEEP 8 右舷有舵机
横扫 4 端口 COXED
扫频 4 端口无轴电缆
SWEEP 4 右舷有舵机
SWEEP 4 右舷非滑行
横扫 2 端口 COXED
SWEEP 2 端口无轴连接
SWEEP 2 右舷有舵机
SWEEP 2 STARBOARD UNCOXED

目前这是我用 Java 编写的类:

public class BoatType
{
public enum RiggerType{SCULL, SWEEP_PORT, SWEEP_STARBOARD}

private int numSeats;

private RiggerType riggerType;

public boolean coxswain = true;

public BoatType(RiggerType type, int seats, boolean coxed)
{
    numSeats = seats;
    riggerType = type;
    coxswain = coxed;
}
}

在其他地方枚举了标准类型:

    public static final BoatType 
    SCULL_OCTUPLE = new BoatType(RiggerType.SCULL, 8, false),
    SCULL_QUAD = new BoatType(RiggerType.SCULL, 4, false),
    SCULL_DOUBLE = new BoatType(RiggerType.SCULL, 2, false),
    SCULL_SINGLE = new BoatType(RiggerType.SCULL, 1, false),
    SWEEP_PORT_EIGHT_COXED  = new BoatType(RiggerType.SWEEP_PORT, 8, true),
    SWEEP_STARBOARD_EIGHT_COXED = new BoatType(RiggerType.SWEEP_STARBOARD, 8, true),
    SWEEP_PORT_FOUR_COXED = new BoatType(RiggerType.SWEEP_PORT, 4, true),
    SWEEP_PORT_FOUR_UNCOXED = new BoatType(RiggerType.SWEEP_PORT, 4, false),
    SWEEP_STARBOARD_FOUR_COXED = new BoatType(RiggerType.SWEEP_STARBOARD, 4, true),
    SWEEP_STARBOARD_FOUR_UNCOXED = new BoatType(RiggerType.SWEEP_STARBOARD, 4, false),
    SWEEP_PORT_PAIR_COXED = new BoatType(RiggerType.SWEEP_PORT, 2, true),
    SWEEP_PORT_PAIR_UNCOXED = new BoatType(RiggerType.SWEEP_PORT, 2, false),
    SWEEP_STARBOARD_PAIR_COXED = new BoatType(RiggerType.SWEEP_STARBOARD, 2, true),
    SWEEP_STARBOARD_PAIR_UNCOXED = new BoatType(RiggerType.SWEEP_STARBOARD, 2, false);

目前这看起来相当麻烦,所以我想知道是否有人有更好的想法如何表示它。枚举是不可能的,因为虽然这些是现有的标准类型,但我不想将其限制为这些组合。

I am writing a program that is involved with rowing, and I am creating an immutable class called "BoatType" to represent the different "types" of boats that there are. This is becoming complex because there are many types that require unique description.

A BoatType should have the following:

  • Either SCULL or SWEEP type
  • A number that is the number of people that fit in the boat
  • Either PORT or STARBOARD type, but only if the first type is SWEEP
  • A boolean representing COXED or UNCOXED, generally only for SWEEP

This is even further complicated by the fact that in the rowing world, there only exist certain combinations of those fields. I'd like my program to have easy enumerated access to these standard types without having to create new BoatType objects. These are, in full:

SCULL 8
SCULL 4
SCULL 2
SCULL 1
SWEEP 8 PORT COXED
SWEEP 8 STARBOARD COXED
SWEEP 4 PORT COXED
SWEEP 4 PORT UNCOXED
SWEEP 4 STARBOARD COXED
SWEEP 4 STARBOARD UNCOXED
SWEEP 2 PORT COXED
SWEEP 2 PORT UNCOXED
SWEEP 2 STARBOARD COXED
SWEEP 2 STARBOARD UNCOXED

Currently this is the class I have written in Java:

public class BoatType
{
public enum RiggerType{SCULL, SWEEP_PORT, SWEEP_STARBOARD}

private int numSeats;

private RiggerType riggerType;

public boolean coxswain = true;

public BoatType(RiggerType type, int seats, boolean coxed)
{
    numSeats = seats;
    riggerType = type;
    coxswain = coxed;
}
}

with a enumeration of standard types elsewhere:

    public static final BoatType 
    SCULL_OCTUPLE = new BoatType(RiggerType.SCULL, 8, false),
    SCULL_QUAD = new BoatType(RiggerType.SCULL, 4, false),
    SCULL_DOUBLE = new BoatType(RiggerType.SCULL, 2, false),
    SCULL_SINGLE = new BoatType(RiggerType.SCULL, 1, false),
    SWEEP_PORT_EIGHT_COXED  = new BoatType(RiggerType.SWEEP_PORT, 8, true),
    SWEEP_STARBOARD_EIGHT_COXED = new BoatType(RiggerType.SWEEP_STARBOARD, 8, true),
    SWEEP_PORT_FOUR_COXED = new BoatType(RiggerType.SWEEP_PORT, 4, true),
    SWEEP_PORT_FOUR_UNCOXED = new BoatType(RiggerType.SWEEP_PORT, 4, false),
    SWEEP_STARBOARD_FOUR_COXED = new BoatType(RiggerType.SWEEP_STARBOARD, 4, true),
    SWEEP_STARBOARD_FOUR_UNCOXED = new BoatType(RiggerType.SWEEP_STARBOARD, 4, false),
    SWEEP_PORT_PAIR_COXED = new BoatType(RiggerType.SWEEP_PORT, 2, true),
    SWEEP_PORT_PAIR_UNCOXED = new BoatType(RiggerType.SWEEP_PORT, 2, false),
    SWEEP_STARBOARD_PAIR_COXED = new BoatType(RiggerType.SWEEP_STARBOARD, 2, true),
    SWEEP_STARBOARD_PAIR_UNCOXED = new BoatType(RiggerType.SWEEP_STARBOARD, 2, false);

This currently seems rather cumbersome, so I was wondering whether anyone had a better idea how to represent this. An enum is out of the question, because while those are the standard types in existence, I don't want to restrict it to those combinations.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甲如呢乙后呢 2024-10-24 04:43:24

我认为你的类大部分都很好,除了:

  • 你应该将构造函数设为私有并使用静态工厂函数,这样可以重用标准船类型的对象。

  • 您应该将标准类型的常量和集合放在类内部,而不是其他地方。

  • 添加常用的基础设施(toStringhashCodeequals、getters)。

  • 所有实例变量都应该是 privatecoxswain 不是)和 final

是的,有点麻烦,但Java就是这样。像 Eclipse 这样的 IDE 可以通过生成一些代码来提供帮助。

I think your class is mostly fine, except that:

  • You should make the constructor private and use static factory functions, which can reuse objects for standard boat types.

  • You should put the constants and a collection for the standard types inside the class, not elsewhere.

  • Add the usual infrastructure (toString, hashCode, equals, getters).

  • All instance variables should be private (coxswain isn't) and final.

Yes, it's a bit cumbersome, but that's the way Java is. An IDE like Eclipse can help by generating some of that code.

不弃不离 2024-10-24 04:43:24

您可以使 BoatType 抽象并创建 BoatType 的两个子类,即 ScullBoatType 和 SweepBoatType。然后,您可以在 SweepBoatType 上定义两个布尔字段“isPort”和“isCoxed”(但不能在 ScullBoatType 上)。像这样:

abstract class BoatType {
    protected int numSeats;

    public BoatType(int numSeats) {
            this.numSeats = numSeats;
    }
}

final class ScullBoatType extends BoatType {
    public ScullBoatType(int numSeats) {
        super(numSeats);
    }
}

final class SweepBoatType extends BoatType {
    private boolean isPort;
    private boolean isCoxed;

    public SweepBoatType(int numSeats, boolean isPort, boolean isCoxed) {
        super(numSeats);
        this.isPort = isPort;
        this.isCoxed = isCoxed;
    }
}

然后可以像这样创建新实例:

BoatType SCULL_OCTUPLE = new ScullBoatType(8);
BoatType SWEEP_PORT_EIGHT_COXED = new SweepBoatType(8, true, true);
// and so on...

You could make BoatType abstract and create two subclasses of BoatType, namely ScullBoatType and SweepBoatType. Then you can define two boolean fields "isPort" and "isCoxed" on SweepBoatType (but not on ScullBoatType). Like so:

abstract class BoatType {
    protected int numSeats;

    public BoatType(int numSeats) {
            this.numSeats = numSeats;
    }
}

final class ScullBoatType extends BoatType {
    public ScullBoatType(int numSeats) {
        super(numSeats);
    }
}

final class SweepBoatType extends BoatType {
    private boolean isPort;
    private boolean isCoxed;

    public SweepBoatType(int numSeats, boolean isPort, boolean isCoxed) {
        super(numSeats);
        this.isPort = isPort;
        this.isCoxed = isCoxed;
    }
}

New instances can then be created like this:

BoatType SCULL_OCTUPLE = new ScullBoatType(8);
BoatType SWEEP_PORT_EIGHT_COXED = new SweepBoatType(8, true, true);
// and so on...
锦爱 2024-10-24 04:43:24

枚举实际上比处理您想要的复杂性更强大。你确定它还不够复杂吗?

http://download.oracle.com/javase/tutorial/java/javaOO /enum.html

http:// /www.basilv.com/psd/blog/2006/advanced-uses-of-java-5-enums

Enum is actually more than powerful to handle the complexity you want. Are you sure it's not complex enough?

http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

http://www.basilv.com/psd/blog/2006/advanced-uses-of-java-5-enums

孤星 2024-10-24 04:43:24

我不明白这怎么那么麻烦。事情就是这样,我认为你不会找到一种更干净的方法。

请注意,您可能希望对 BoatType 的成员具有一致的可见性,并使所有这些成员成为最终成员。

I don't see how it's all that cumbersome. It is what it is, and I don't think you're going to find a significantly cleaner way.

One note, you might want to have consistent visibility for the members of BoatType and make all of those members final.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文