Multiple listings versus one listing

I watched an example implementation of the Publisher ( AsyncIterablePublisher.java ) jet stream specification when I came across something that I don't understand why it was done this way.

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

Being realistic that I am not such an advanced programmer as the person who wrote this, I am sure that there is a reason to do it that way. But I also can’t explain why it would be better than doing it (that’s how I would do it).

 enum Signal { Cancel, Subscribe, Send; } 

Can someone explain to me why it would be better? Advantages disadvantages?

+7
java enums reactive-streams
source share
5 answers

So, since I did not know which of the answers to approve, I sent the author part of the code and asked him what he thought about it. Here is the conversation (block from it. My normal text):

Hi Michael,

What is the difference with having only one listing? You would not have three singletons, but three more uniquely defined objects:

Of course, this can be done, but then I will have to invent a name for it (for example, ConcreteSignal), my chosen encoding avoids :)

 enum Signal { Cancel, Subscribe, Send; } 

I think this is also thread safe, and if you really want to have a common interface that you can use with objects, for example, you can do it like this:

 enum ConcreteSignal implements Signal { Cancel, Subscribe, Send; } 

You could do as you did above, however I would say that they [Cancel, Subscribe, Send] are no more specific than the Request (which is also a signal): https://github.com/reactive-streams/ reactive-streams-jvm / blob / v1.0.0 / examples / src / main / java / org / reactivestreams / example / unicast / AsyncIterablePublisher.java # L49

In addition, it may also facilitate the use of Enum methods to list all the possible Signals that failed, since Request is not a signal. Has the meaning?

Indeed, in Scala, you would prefer to do this with Object, but in Java it is very rare to see something like your implementation. I was just curious that I lacked some neat feature in Java. But if I understand correctly, is it because you are more comfortable with this implementation, since it is closer to Scala, your preferred language?

I suppose this is a little, but the singleton-as-enum-pattern in Java is pretty well known, so the only “weird” thing would be to have a separate “enumeration” for each of the “Cancel”, “Sign” and “Send”, but how I explained earlier, since the request cannot be encoded the way I chose the more "Scala -y" version.

So, if the "Request" does not need any parameters, I would do as you suggested: enum Signal {Cancel, Request, Sign, Send}

Mystery solved: -).

0
source share

Don't be too strict, here is my interpretation of this code. We will name the owner of the Roland jet streams.

Roland first requires a common interface for all inboundSignals

 static interface Signal {}; ConcurrentLinkedQueue<Signal> inboundSignals = new ConcurrentLinkedQueue<Signal>(); 

Signals like Cancel , Subscribe and Send are always the same, unchanged, and occur very often, so it's a good idea to implement them as Joshua Bloch Singleton :

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

another way to do the same is similar to your suggestion and my favorite:

 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 } 

As you can see, this is a different implementation. But the idea is the same: the signal is like singleton

We pass and find this code:

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

Since inboundSignals can contain multiple Request objects, it is not possible to implement this type of signal as a Singleton. Therefore, it cannot be a member of CommonSignals or implemented as an enum .


Conclusion

Roland used one of many opportunities to sell singletons. I think more important is how to do this.
+2
source share

For the type of use in AsyncIterablePublisher, the two forms are equivalent, and perhaps the last one enumeration with several constants is more natural.

Actually, the first form is very rare. I can see one argument in favor of its use (but so rarely does this mean that this item is usually not so important): when you define each constant in your own enumeration, you get the opportunity to define different methods / fields, such as:

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

so now you can do Send.Instance.someSendSpecificMethod() . Very uncomfortable, very rare.

+1
source share

The difference is that you can add another instance of Signal without changing the original enumeration. Your code can work with Signal instances, and various types can be provided. The same as the interface for classes - gives you flexibility, but it is only useful if you need it. In your case, I do not see much benefit, because the interface is empty, and the listings that implement it have nothing in them.

You can check this site for a good example of listing with interfaces:

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

+1
source share

that I think the only reason for using the enumeration interface is that some signals have data that is different from other signals, so it needs to expand the type of enumeration to attach data to it.

0
source share

All Articles