【问题标题】:What's the best way to define a nested class / object / enum structure in Java?在 Java 中定义嵌套类/对象/枚举结构的最佳方法是什么?
【发布时间】:2023-03-17 05:30:01
【问题描述】:

我正在开发一个 Android 应用程序 (Java),它通过 HTTP POST 使用 Yamaha 蓝光播放器的 API。播放器具有 XML 格式的严格命令集。命令遵循层次结构:虽然大部分外部 XML 元素始终相同,但内部结构属于播放器函数的类型。例如,播放/暂停/停止函数在 XML 中具有相同的路径,而跳过函数具有其他父元素。您可以在下面的代码示例中看到我的意思。

public enum BD_A1010 implements YamahaCommand
{
    POWER_ON ("<Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone>"),
    POWER_OFF ("<Main_Zone><Power_Control><Power>Network Standby</Power></Power_Control></Main_Zone>"),
    TRAY_OPEN ("<Main_Zone><Tray_Control><Tray>Open</Tray></Tray_Control></Main_Zone>"),
    TRAY_CLOSE ("<Main_Zone><Tray_Control><Tray>Close</Tray></Tray_Control></Main_Zone>"),
    PLAY ("<Main_Zone><Play_Control><Play>Play</Play></Play_Control></Main_Zone>"),
    PAUSE ("<Main_Zone><Play_Control><Play>Pause</Play></Play_Control></Main_Zone>"),
    STOP ("<Main_Zone><Play_Control><Play>Stop</Play></Play_Control></Main_Zone>"),
    SKIP_REVERSE ("<Main_Zone><Play_Control><Skip>Rev</Skip></Play_Control></Main_Zone>"),
    SKIP_FORWARD ("<Main_Zone><Play_Control><Skip>Fwd</Skip></Play_Control></Main_Zone>");

    private String command;

    private BD_A1010 (String command)
    {
        this.command = command;
    }

    public String toXml ()
    {
        return "<?xml version=\"1.0\" encoding=\"utf-8\"?><YAMAHA_AV cmd=\"PUT\">" + this.command + "</YAMAHA_AV>";
    }
}

如您所见,我尝试了平面枚举方式,效果很好。我可以像这样在我的 RemoteControl 类中使用枚举:

remoteControl.execute(BD_A1010.PLAY);

枚举的 .toXml() 方法返回发送给播放器所需的完整 XML 代码。现在这是我的问题:我需要一种更好的方法来构建 Java 类中的函数层次结构。我想这样使用它:

remoteControl.execute(BD_A1010.Main_Zone.Power_Control.Power.On);

像嵌套的枚举或类。命令的每一级都应在其自身内部定义其 XML 元素。此外,路径上的每个命令只能定义可能的子命令:例如,在 Main_Zone.Play_Control 之后,我可能只使用 .Play 或 .Skip,而不是 .Tray 或其他任何东西。在链的最后,我喜欢调用 .toXml() 来获取完整的 XML 命令。

在 Java 中将这种层次结构定义为(嵌套)类的最佳方式是什么?应该很容易定义 - 尽可能少的代码。

稍后,应该可以合并两个或多个命令以获得如下的组合 XML - 但这对于第一次尝试来说并不那么重要。

remoteControl.execute(
    BD_A1010.Main_Zone.Power_Control.Power.On,
    BD_A1010.Main_Zone.Play_Control.Skip.Rev,
    BD_A1010.Main_Zone.Play_Control.Play.Pause
);

<Main_Zone>
    <Power_Control>
        <Power>On</Power>
    </Power_Control>
    <Play_Control>
        <Skip>Rev</Skip>
        <Play>Pause</Play>
    </Play_Control>
</Main_Zone>

【问题讨论】:

  • 你描述的有什么问题,我的意思是将枚举嵌套到另一个枚举?
  • 另外,YmanaCommand接口是否定义了toXml方法?
  • 据我所知,嵌套枚举在 Java 中是不可能的,是吗?
  • 是的,YamahaCommand 接口定义了 toXml(),所以我可以创建不同的枚举,每个设备一个。
  • 为什么不呢,可以将枚举嵌套到另一个枚举(它将被视为静态内部类)。实际上任何(类,接口枚举)上下文中的嵌套枚举都将被视为静态内部类

标签: java class enums nested


【解决方案1】:

为什么必须是枚举? Builder pattern 救援。 考虑一下这种味道:http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=2 而不是香草味。核心改进是非常易读的语法:

builder.withProperty(...).withFeature(...).finallyWith(...)

【讨论】:

  • 我同意,你可以在 Kerievsky 的“重构模式”中找到一个很好的例子 - “用生成器封装复合材料”(第 96 - 113 页)
  • 不错,我会考虑的。谢谢!
  • @BertKößler 你能告诉我们你是如何解决你的问题的吗?
  • @pavelrappo 我没有解决它。在我的第一个示例中,我坚持使用扁平枚举样式。
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
相关资源
最近更新 更多