什么是一个好的数据结构来表示比枚举更复杂但不完全是类的字段?
我正在编写一个涉及划船的程序,并且正在创建一个名为“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为你的类大部分都很好,除了:
你应该将构造函数设为私有并使用静态工厂函数,这样可以重用标准船类型的对象。
您应该将标准类型的常量和集合放在类内部,而不是其他地方。
添加常用的基础设施(
toString
、hashCode
、equals
、getters)。所有实例变量都应该是
private
(coxswain
不是)和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) andfinal
.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.
您可以使 BoatType 抽象并创建 BoatType 的两个子类,即 ScullBoatType 和 SweepBoatType。然后,您可以在 SweepBoatType 上定义两个布尔字段“isPort”和“isCoxed”(但不能在 ScullBoatType 上)。像这样:
然后可以像这样创建新实例:
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:
New instances can then be created like this:
枚举实际上比处理您想要的复杂性更强大。你确定它还不够复杂吗?
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
我不明白这怎么那么麻烦。事情就是这样,我认为你不会找到一种更干净的方法。
请注意,您可能希望对
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.