多个枚举vs一个枚举

当我偶然发现一些我不明白为什么会这样做的事情时,我正在研究reactive-streams规范的Publisher(AsyncIterablePublisher.java)的示例实现。

static interface Signal {};
enum Cancel implements Signal { Instance; };
enum Subscribe implements Signal { Instance; };
enum Send implements Signal { Instance; };

我不是写这个高级程序员的现实人物,我确信有这样做的理由。 但我也无法解释为什么它会比这样做更好(这是我如何做到的)。

enum Signal {
  Cancel,
  Subscribe,
  Send;
}

有人可以向我解释为什么它会更好吗? 优点缺点?


不要太严格,这里是我对这段代码的解释。 让我们打电话给反应流Roland的所有者。

起初Roland需要所有inboundSignals的通用接口

static interface Signal {};

ConcurrentLinkedQueue<Signal> inboundSignals = new ConcurrentLinkedQueue<Signal>();

CancelSubscribeSend这样的信号具有相同的目的是不可变的,并且发生得非常频繁,因此将它们实现为Joshua Bloch的Singleton是个好主意:

enum Cancel    implements Signal { Instance; };
enum Subscribe implements Signal { Instance; };
enum Send      implements Signal { Instance; };

另一种做同样的方式类似于你的建议和我的最爱:

enum CommonSignals implements Signal{

    Cancel {
        @Override
        void debug() {
            System.out.println("Cancel");
        }
    },

    Subscribe {
        @Override
        void debug() {
            System.out.println("Subscribe");
        }
    },

    Send {
        @Override
        void debug() {
            System.out.println("Send");
        }
    };

    abstract void debug();

    [...] some other methods I could need in the future
}

正如你所看到的,这是一个不同的实现。 但这个想法是一样的 - 信号与单身人士一样

我们继续前进,找到这个代码:

static final class Request implements Signal {
    final long n;
    Request(final long n) { // every Request has different value of n
        this.n = n;
    }
};

由于inboundSignals可以包含多个Request对象,因此不可能将这种类型的信号实现为单例。 因此它不能是CommonSignals的成员,也不能作为enum实现。


结论

罗兰使用了许多可能性来实现一个单身人士。 我认为这更多的是品味如何去做。


对于AsyncIterablePublisher中的使用类型,两种形式是等价的,可以说是后者,一种具有多个常量的枚举更自然。

其实,前一种形式非常罕见。 我可以看到一个赞成使用它的论点(但是非常罕见,这意味着这一点通常不那么重要):当您在自己的枚举中定义每个常量时,您将有机会定义不同的方法/字段,例如:

enum Cancel implements Signal { Instance; };
enum Send implements Signal { 
  Instance; 
  public void someSendSpecificMethod() { ... }
}

所以你现在可以做Send.Instance.someSendSpecificMethod() 。 非常尴尬,非常罕见。


不同之处在于,您可以添加另一个Signal实例而不更改原始枚举。 你的代码可以和Signal实例一起工作,并且可以提供不同的类型。 与类接口相同 - 为您提供了灵活性,但仅在您需要时才有用。 在你的情况下,我没有看到太多的用处,因为界面是空的,实现它的枚举没有任何内容。

你可以在这个网站上查看带接口枚举的例子:

http://www.selikoff.net/2011/06/15/java-enums-can-implement-interfaces/

链接地址: http://www.djcxy.com/p/85195.html

上一篇: Multiple enums vs One enum

下一篇: forgery / CSRF token with latest version ring/compojure?