Click to See Complete Forum and Search --> : Polymorphism and Collections


diofanto
August 1st, 2009, 01:14 AM
Hi everybody, I'm quite sure this is a common question about OO design, but I'm really, really in hurry.. I hope you'll forgive me.

Let's say that I have an abstract class Message, with title and description:

public abstract class Message{

private String title;
private String body;

public Messaggio(String title, String body) {
super();
this.title = title;
this.body = body;
}

public String getTitle() {
return title;
}

public String getBody() {
return body;
}

public abstract String getPreview() ;

}


Let's say that I have also different kinds of Message with more attributes, for example:


public abstract class SignedMessage extends Message{

private Person author;

public Messaggio(String title, String body, Person author) {
super(title, body);
this.author = author
}

public String getAuthor() {
return author;
}


public String getPreview() {
return "A preview";
}

}


I'm writing an application which is meant to dispatch these Messages.
For each user to which i'm sending the messages, I have to provide a buffer wich *must* be unique (for reasons of timestamping and concurrent dispatching), and I mean I cannot have different kinds of Buffer for each user:

Buffer<SignedMessage>, Buffer<MessageWithDraw>....

but I *have* to have only one Buffer<Message> per user.

Now, my problem is: every message has to be treated differently by the receiver (it's a client-server system using RMI), but how can the sender or the receiver recognize the specific kind of message when it sends or receive it?

If I initialize Buffer<Message> aBuffer = new Buffer<Message>() and add a SignedMessage, then upcasting occurs: what if I want to call remote method onReceiveSignedMessage(SignedMessage) from the dispatcher, OR call onReceiveMessage(Message) and recognized SignedMessage inside the receiver?
Do I need to downcast? How?
Is there a better OO workaround?

Thank you sooo much!

dlorde
August 1st, 2009, 12:30 PM
Now, my problem is: every message has to be treated differently by the receiver (it's a client-server system using RMI), but how can the sender or the receiver recognize the specific kind of message when it sends or receive it?This is the perennial polymorphism problem - if you pass objects around by a superclass reference, you can't tell what the subtype is without some kind of runtime type identification. Only the object itself knows what type it really is.

So you have to let the object do the work, which means having some common superclass method that the receiver can call to get the object to do whatever it is each particular type of object does.

If it's not that simple, and the receiver really needs to know the object type in order to call a bunch of subclass-specific methods, you can extend this by using 'double-dispatch' code, commonly called the 'Visitor' pattern. In this technique, the receiver would be the 'visitor' and would have a method (usually called 'visit') overloaded for every type of message. The message interface would have an 'accept' method that takes the receiver as a parameter, and each message type implements this method - passing itself to the receiver's overloaded 'visit' method.

So, when the receiver gets a message object, it calls the message's 'accept' method, passing itself as the argument. Inside this particular message's method, the message's real type is known, so the message can pass itself to the receiver's overloaded 'visit' method and the correct overload will be selected for that message type. Once inside the receiver's overloaded 'visit' method, any custom methods can be called on the message subtype. This A-calls-B-calls-A palaver to resolve the message type is why it's called 'double-dispatch'.

Of course, you don't have to call the methods 'visit' and 'accept', but it does make it clearer when you come to read it three months later... Just be sure that when you send your messages across to the receiver, the full message subclass object gets to the other end...

There some drawbacks with the Visitor pattern, but it would fit your requirement. There are plenty of examples online - even Wikipedia has sample Java code.

The outcome of any serious research can only be to make two questions grow where only one grew before...
T. Veblen

diofanto
August 1st, 2009, 03:38 PM
Thank you dlorde!

I feel a little ashamed because the same topic was on the first page of the forum, with basically the same title: http://www.codeguru.com/forum/showthread.php?t=479574

What should I say about Visitor.. it's a very powerful pattern... freakin genius actually!! :D
And it's easier to learn than it might seem.

nuzzle
August 1st, 2009, 07:31 PM
Thank you dlorde!

I feel a little ashamed because the same topic was on the first page of the forum, with basically the same title: http://www.codeguru.com/forum/showthread.php?t=479574

What should I say about Visitor.. it's a very powerful pattern... freakin genius actually!! :D
And it's easier to learn than it might seem.

That's right, and that's something for Mr. dlorde to contemplate. :)

I'm saying this because dlorde strongly has argued that the Visitor pattern should be avoided because it's likely to not being understood by maintainers of your code. That's nonsense. The Visitor pattern is in the public domain and should be understood by every Java programmer - unless they're a moron of course or being recruited from some burger flipping shop to save the money an educated programmer would cost.

dlorde
August 2nd, 2009, 06:24 AM
I'm saying this because dlorde strongly has argued that the Visitor pattern should be avoided because it's likely to not being understood by maintainers of your code. That's nonsense.
It is nonsense, and I didn't say that. What I did say was:... there are a couple of disadvantages - it makes more work to add new items to the hierarchy, and it may be confusing for novice coders maintaining code. Full post here (http://www.codeguru.com/forum/showpost.php?p=1854162&postcount=3), and follow-up here (http://www.codeguru.com/forum/showpost.php?p=1855034&postcount=5).

I don't mind you paraphrasing or quoting my posts, but please don't misrepresent them.

The greatest obstacle to discovery is not ignorance, but the illusion of knowledge...
D. Boorstin

nuzzle
August 8th, 2009, 07:32 PM
It is nonsense, and I didn't say that. What I did say was: Full post here (http://www.codeguru.com/forum/showpost.php?p=1854162&postcount=3), and follow-up here (http://www.codeguru.com/forum/showpost.php?p=1855034&postcount=5).

I don't mind you paraphrasing or quoting my posts, but please don't misrepresent them.


I'm not misinterpretating anything . You've claimed that one should avoid standard OO techniques because,

"it may be confusing for novice coders maintaining code"

I don't buy that. Anybody not knowing the Visitor design pattern is a moron and shouldn't be hired to maintain anything.

dlorde
August 9th, 2009, 06:09 PM
You've claimed that one should avoid standard OO techniques ...
If true, you should be able to post a quote of me making the claim :rolleyes:

Any clod can have the facts; having opinions is an art...
C. McCabe

ProgramThis
August 10th, 2009, 07:48 AM
That's right, and that's something for Mr. dlorde to contemplate. :)

I'm saying this because dlorde strongly has argued that the Visitor pattern should be avoided because it's likely to not being understood by maintainers of your code. That's nonsense. The Visitor pattern is in the public domain and should be understood by every Java programmer - unless they're a moron of course or being recruited from some burger flipping shop to save the money an educated programmer would cost.

Give it up kid, seriously. We get it, you think you're better than everybody else. :thumb:

Your elitist attitude and immature rantings about topics, dropped two weeks ago, really demonstrate your immaturity. Just give it up and move on with your life.