Results 1 to 5 of 5
- 12-04-2010, 11:04 AM #1
Member
- Join Date
- Mar 2010
- Posts
- 11
- Rep Power
- 0
Proper generics approach for the following design
Hi!
I am writing a little messagebus, which distributes messages based on the messageclass. The messagebus consists of a number of messageChannels, each for a certain type of message.
Java Code:public abstract class MessageChannel<T extends Message> { List<MessageReceiver<T>> messageReceivers=Collections.synchronizedList(new ArrayList<MessageReceiver<T>>()); Class<T> messageClass; public MessageChannel(Class<T> messageClass) { this.messageClass=messageClass; } public void registerReceiver(MessageReceiver<T> messageReceiver) { messageReceivers.add(messageReceiver); } public boolean publishMessage(T message) { .. } }"Problem"class:Java Code:public interface MessageReceiver<T extends Message> { public boolean messageDelivery(T message); public Class<T> getMessageClass(); }
These are my three classes, and in the last one (MessageBus) I am getting one of those generics compile errors. I read up about generics and I think the problem here is the "MessageBus" as it does not specify any generic parameters. I read that if one uses "? extends Message" one can only access that object as Message, ie only those methods (obviously). And I think because I try to pass this on to a method in a generically parameterized class (registerReceiver(..)) Java complains, because it kindof needs to upgrade to a more specified state of the class. If you know what I mean.Java Code:public abstract class MessageBus { Map<Class<? extends Message>, MessageChannel<?>> messageChannels=Collections.synchronizedMap(new HashMap<Class<? extends Message>, MessageChannel<? extends Message>> ()); public void addMessageChannel(MessageChannel<? extends Message> channel) { messageChannels.put(channel.getMessageClass(), channel); } public void registerReceiver(MessageReceiver<? extends Message> receiver) { MessageChannel<? extends Message> channel=messageChannels.get(receiver.getMessageClass()); if(channel!=null) { channel.registerReceiver( receiver); //This is the problem line, compile error see further down } } }
Anyway, what is the correct pattern here? For now I will remove all generics use from Messagebus, but it d be nice to see how it works.
Thanks!!
ps.: Exact compile error message:
The method registerReceiver(MessageReceiver<capture#7-of ? extends Message>) in the type MessageChannel<capture#7-of ? extends Message> is not applicable for the arguments (MessageReceiver<capture#8-of ? extends Message>) MessageBus.java
pps.: I think logically it should work, otherwise why can I get the MessageReceiver out of the map without problems?Last edited by CChange; 12-04-2010 at 11:09 AM.
- 12-04-2010, 08:23 PM #2
Member
- Join Date
- Nov 2010
- Posts
- 54
- Rep Power
- 0
No this is not possible. Generics are there to ensure type safety.
You're trying to add a MessageReciever for an unknown Message type to a MessageChannel for a completely different Unknown message type. Java is telling you that it can't be sure what will happen.
Effectively you're throwing all your MessageChannels of every Message type into a bag (and shaking it around a bit). When someone wants to add a MessageReciever you rummage round in the bag, pull out the one you think is right and try to add the listener to it without any garuntee from Java that you got the right MessageChannel.
I wonder if you really need an abstract message bus like this. I can see there are possible (though un-common) reasons why you might. If you do then you simply need to force it through by doing something like type casting. You need to forcably tell Java you got it right even through java can't be sure.Last edited by couling; 12-04-2010 at 08:24 PM. Reason: My gramma sucks
----Signature ----
Please use [CODE] tags and indent correctly. It really helps when reading your code.
- 12-04-2010, 10:30 PM #3
Member
- Join Date
- Mar 2010
- Posts
- 11
- Rep Power
- 0
Cheers mate!
Though I have to say that "bag" example is not quite right. The shortcoming is actually that Java does nothing about the generics at runtime. Conceptually I believe all this is logical because the channel and the listener are bound by the extension of Message class. (Class<T> getMessageClass() of course returns the what is defined by the generic parameter which is then used to register the listener).
So, how would you approach this, if you wanted a single messagebus to send and receive messages, rather than addressing each channel seperately?
Would you, in a sense, go for:
messageBus.getChannel(MyMessage.class).registerLis tener(this); //or whatever
Thanks for your help and opinions!
CC
- 12-04-2010, 11:36 PM #4
Member
- Join Date
- Nov 2010
- Posts
- 54
- Rep Power
- 0
I'm more used to seeing the getChannel approach. It means that if you add extra functionality to a MessageChannel you dont have to add extra functions to pass this through MessageBus. Note that getChannel may not remove the need to cast. At some point you need to cast from a MessageChannel<? extends Message> to a MessageChannel<Specific>.
If you still really want the functions to work as you've laid out, you could allways just remove generics internally in the function, but keep them for the function prototypes:This is actually a really good example of the reason Generics did not completely remove the need to cast some times.Java Code:@SuppressWarnings("unchecked") public void registerReceiver(MessageReceiver<? extends Message> receiver) { @SuppressWarnings("rawtypes") MessageChannel channel=messageChannels.get(receiver.getMessageClass()); if(channel!=null) { channel.registerReceiver( receiver); } }
Hope this helps----Signature ----
Please use [CODE] tags and indent correctly. It really helps when reading your code.
- 12-04-2010, 11:39 PM #5
Member
- Join Date
- Mar 2010
- Posts
- 11
- Rep Power
- 0
Similar Threads
-
design & generics for socket server
By gilme in forum New To JavaReplies: 1Last Post: 06-18-2010, 04:24 AM -
design approach for multi-lingual gui
By j2me64 in forum AWT / SwingReplies: 1Last Post: 05-14-2010, 05:54 PM -
Regex approach
By karlito in forum LuceneReplies: 1Last Post: 11-04-2009, 05:53 PM -
Please suggest me the correct approach!
By rjuyal in forum Advanced JavaReplies: 6Last Post: 05-05-2008, 02:54 PM -
Opinions on best approach for objects
By spikey in forum Advanced JavaReplies: 1Last Post: 04-11-2008, 05:20 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks