Factory methods and downcasting

I am having a class hierarchy and a factory method that creates the classes from this hierarchy. The factory method returns the root class of this hierarchy and every time I want to use a class specific method of one of the sub classes I will have to check the type of this class and cast to this class type. My question is now if there is a possibility to avoid the type checking and casting or if this is one of the few situations where type checking and casting is approriate. To illustrate the problem here is some code:

class Factory{

publicstatic A create(){

if (//someCondition)

returnnew B();

else

returnnew C();

}

}

abstractclass A{

publicvoid commonMethod(){

// do stuff

}

publicvoid polymorphicMethod();

}

class Bextends A{

publicvoid polymorphicMethod(){

// do something

}

publicvoid specificBMethod(){

// do stuff that only B can do

}

}

class Cextends A{

publicvoid polymorphicMethod(){

// do some other thing

}

publicvoid specificCMethod(){

// do stuff that only C can do

}

}

Now I run into a situation where I have to downcast to the correct type.

class Worker{

publicvoid work(){

A a = Factory.create();

if (ainstanceof B){

( (B) a).specificBMethod();

}elseif (ainstanceof C){

( (C) a).specificCMethod();

}else{

// Error

}

}

}

I think this problem always arises if you have a factory method that returns a class at the top of the hierarchy or a interface but you can not put all the methods that a client wants to call in this common class or interface. Is there a better a way to do this or is this already a good solution?

[4046 byte] By [IngoSeidela] at [2007-11-26 15:02:38]
# 1

If your client has to know what type they're dealing with you've lost all the benefit of factory, IMO. There's no polymorphism here. There's also no good way that I know of to avoid type casting and instanceof.

You can isolate the casts as you did in your Worker, but a better solution might be to move those specific methods up to the superclass.

Still another, perhaps better way, is to prefer mixin behavior. If there's an interface you can have B and C implement in such a way that you can change that specific method behavior by passing in different implementations of that interface, you can avoid the casts.

The casts are ugly. I'd think harder about an alternative design.

%

duffymoa at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

duffymo is right. If your implementation needs to know about the concrete class to handle class specifica, using the factory only seems useful if the factory-user should not care about the conditions which lead to creating one or the other class. It depends on your application goal, how to solve this. If you are aware of the complete hierarchy and possible methods, let A have stub or abstract methods and let the subclasses implement them to accomplish different behaviours. I'd actually assume this is the case, as you are checking the types for calling the specific behaviours and would have to extend those parts when adding a new class.

stefan.schulza at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

In my particular case I have an XML parser that parses messages. I implemented each different message type as a different class and the parser uses the factory to create new message objects. The parser then uses methods that are defined in the topmost Message class and in an interface to set the attributes of the object. Each message class overrides a "handleXMLElement" method defining how to deal with the message specific XML elements. So this is fine the parser is the client of the factory and he uses only methods that are defined in a common class and an interface.

After a message has been read the message object is forwarded to a hierarchy of message handlers. Of course the message handlers know of the message class hierarchy and want to access all methods of each message object. But since the parser only knows about the interface and the common class, the message handlers will have to cast the message objects to the concrete types.

So the parser-factory relationship works well but the (nasty) casting arises due to the later message handling. I also remembered why I implemented it this way. In the Desing Patterns book of Gamma et. al. the Chain of Responsibility pattern can be implemented this way using casts. So the solution can't be that bad at all, I guess.

@stefan: I can't pull all my methods from the subclasses in one upper class, because the methods are different and specialised for each sub class. I don't think that it is good when one sub class knows all the methods of all other sub classes.

IngoSeidela at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> In my particular case I have an XML parser that

> parses messages. I implemented each different message

> type as a different class and the parser uses the

> factory to create new message objects. The parser

> then uses methods that are defined in the topmost

> Message class and in an interface to set the

> attributes of the object. Each message class

> overrides a "handleXMLElement" method defining how to

> deal with the message specific XML elements. So this

> is fine the parser is the client of the factory and

> he uses only methods that are defined in a common

> class and an interface.

> After a message has been read the message object is

> forwarded to a hierarchy of message handlers. Of

> course the message handlers know of the message class

> hierarchy and want to access all methods of each

> message object. But since the parser only knows about

> the interface and the common class, the message

> handlers will have to cast the message objects to the

> concrete types.

If the message type that's passed in has its behavior in the common interface, why is there a need to cast?

> So the parser-factory relationship works well but the

> (nasty) casting arises due to the later message

> handling.

Maybe your message handling needs redesign. Or perhaps a hierarchy of callback objects that let you customize that part that changes for each message.

> I also remembered why I implemented it this

> way. In the Desing Patterns book of Gamma et. al.

> the Chain of Responsibility pattern can be

> implemented this way using casts. So the solution

> can't be that bad at all, I guess.

Don't take that as gospel. GoF isn't perfection. Patterns can be misapplied.

> @stefan: I can't pull all my methods from the

> subclasses in one upper class, because the methods

> are different and specialised for each sub class. I

> don't think that it is good when one sub class knows

> all the methods of all other sub classes.

Maybe a callback object can help sort this out. I think you need a redesign to eliminate the casts. More thinking is required.

%

duffymoa at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

> If the message type that's passed in has its behavior

> in the common interface, why is there a need to

> cast?

This only holds for the parser, the behavior that is needed to parse a message is defined in the interface and an abstract super class, so after parsing the message is of type AbstractMessage. But the message handlers also want to access the message specific behaviors that clearly have no place in a common interface and must therefore cast the AbstractMessage to the "real" type.

> Maybe your message handling needs redesign. Or

> perhaps a hierarchy of callback objects that let you

> customize that part that changes for each message.

What do you mean with callback objects in this context? How should this help to customize the messages?

IngoSeidela at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

Ok, one of the important information that was missing is about the hierarchy of message handlers (which is a quite different environment to the worker example in your OP). I'm not sure, whether there is a clean way to eliminate the casting. For your handlers to operate on a message correctly, they have to know about the message's type (one or the other way) for using its specific capabilities if they cannot be addressed by a common API. As we cannot see how distinct these specifics are, it is difficult to suggest a design (and I assume it would go beyond the scope of this forum to get into it). And actually I think, any approach of making access to the concrete classes more generic would weaken the stability of your code (e.g. using reflection-like approaches by passing tokens).

I'm not sure, why type conversion seems to be considered harmful in any situation. For your design, where handlers (have to?) use specifics of a concrete message, and I assume the handlers will only treat some message types and forward the message into the hierarchy otherwise, I cannot think of why one should not use it this way.

stefan.schulza at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

Finally an answer I wanted to hear ;)

Everywhere you can read that casts are evil and you should not use casts, so I kept worrying about my design. But I agree with you that there are situations where you can use casts and I think that in my case casts would be an appropriate solution. Referring to the Design Patterns book they use casting in a situation where they have requests that are exchanged between a sender and a hierarchy of receivers. This would be roughly equal to my situation where you have messages and a hierarchy of message handlers. Of course sender and receiver must agree on the type of messages but this is no problem in my case because sender (parser) and receiver (message handlers) are implemented in the same module.

It would be interesting if there are other people who agree with that.

IngoSeidela at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> Finally an answer I wanted to hear ;)

So you only care about the answers that coincide with your ideas? Tough way to learn things.

>

> Everywhere you can read that casts are evil and you

> should not use casts, so I kept worrying about my

> design.

Without having seen your design, it's hard to say which answer is correct. It is true sometimes you just gotta cast. All the previous suggestions were saying that there might be another alternative that you should explore before decided that you were right all along.

> But I agree with you that there are

> situations where you can use casts and I think that

> in my case casts would be an appropriate solution.

Then go with it. What were you posting for in the first place?

> Referring to the Design Patterns book they use

> casting in a situation where they have requests that

> are exchanged between a sender and a hierarchy of

> receivers. This would be roughly equal to my

> situation where you have messages and a hierarchy of

> message handlers. Of course sender and receiver must

> agree on the type of messages but this is no problem

> in my case because sender (parser) and receiver

> (message handlers) are implemented in the same

> module.

Sounds like you're all set.

> It would be interesting if there are other people who

> agree with that.

More confirmation for your ideas?I'd recommend that you go ahead with it if you're convinced. Your future experience with the design will confirm or deny its value.

%

duffymoa at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 9
For what it's worth, I'm with duffymo on this. That code smells to me.GoF has several patterns which break OO. Their Mediator, forexample, is a bigass if..else block. Remember that the book is old,and they were writing for procedural languages also.
es5f2000a at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

> > Finally an answer I wanted to hear ;)

>

> So you only care about the answers that coincide with

> your ideas? Tough way to learn things.

Thats why I used the smiley, the sentence was meant to be sarcastic.

> Then go with it. What were you posting for in the

> first place?

My intent was to get other ideas and the question if casts are always evil or may be used in some situations. Sure it's hard to give a good answer without seeing someones design, but I thought that maybe others also had to deal with this problem and could give me more concrete help. Btw, what did you mean with the callback objects exactly?

> > It would be interesting if there are other people who

> > agree with that.

>

> More confirmation for your ideas?I'd recommend

> that you go ahead with it if you're convinced. Your

> future experience with the design will confirm or

> deny its value.

Not confirmation of my ideas but the general question if this type of cast should be avoided by all chances or if it may be appropriate in some situations.

IngoSeidela at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

Uhm, well, I did not "confirm" anything, but saying that from what I can see, there is no way of suggesting the appropriate solution. If you can't pull up methods or make the main class have methods that will "please them all", I wonder what you expect.

I could say that the design of your Message implementation smells, as you need to have distinct, specific handling implementations for each type, but I wonder, if that helps.

For example, you could use only one Message class, give it a kind variable (e.g., using enum) and implement kind-specific operations seperately from the Message class. Maybe somewhat similar to the Command-Pattern (if you like to stay with GOF). This still leaves open the handing over of arguments (see below).

Similar with callback objects. Someone would have to provide the object and arguments that go into that object. If these arguments are specific to the kind of message in value and type and are to be determined by the handler, I am quite sure, that you will only be shifting casts to a different place in your code. But maybe duffymo can convince me that I am wrong. I am eager to learn about new things, too. :)

(no sarcasm in here!)

Message was edited by stefan.schulz:

Wording corrected

stefan.schulza at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 12

> For what it's worth, I'm with duffymo on this. That code smells to me.

>

> GoF has several patterns which break OO. Their

> Mediator, for

> example, is a bigass if..else block. Remember that

> the book is old,

Twelve years old now.

> and they were writing for procedural languages also.

This sentence reflects a profound misunderstanding.This person could not have read the book. If they did, they did not understand it.

The title is "Design Patterns: Elements of Reusable Object-Oriented Software", and all the examples are either in C++ or Smalltalk, both object-oriented languages. It had absolutely nothing to do with procedural coding.

%

duffymoa at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

> Thats why I used the smiley, the sentence was meant to be sarcastic.

That's one reason why e-mail and forums are such poor mediums for communication. The more subtle things, like sarcasm, are best communicated by body language, tone of voice, expression - all filtered out here.

> My intent was to get other ideas and the question if

> casts are always evil or may be used in some

> situations.

I find that there are very few absolutes in programming. I think that avoiding any "bad practice" is a good thing, but there are usually exceptions.

Without having an extended design discussion, I don't know that I'd disagree with your efforts to isolate the casts to a single factory method. I just wonder if there's an alternative to doing it this way.

> Sure it's hard to give a good answer

> without seeing someones design, but I thought that

> maybe others also had to deal with this problem and

> could give me more concrete help. Btw, what did you

> mean with the callback objects exactly?

It's an interface reference that you might pass into another class or method that would be the variable part of your implementation. You could change the implementation at will to do the adjustable part of your processing.

> Not confirmation of my ideas but the general question

> if this type of cast should be avoided by all chances

> or if it may be appropriate in some situations.

Yes and yes.

My only point is that you might not have explored all the design possibilities.

Factory isn't the only way. Visitor (aka "double dispatch") might be a good pattern. Do you know how to do that? No casting there.

%

duffymoa at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 14

The XML messaging ought to give you loose coupling, but it sounds like your design is doing exactly the opposite. You change the XML stream and it ripples right through your code. How are you going to insulate yourself from those changes? Tight coupling is a killer. Have you thought about how to isolate it? Your problem is much bigger than casting.

%

duffymoa at 2007-7-8 8:51:48 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

> The XML messaging ought to give you loose coupling,

> but it sounds like your design is doing exactly the

> opposite. You change the XML stream and it ripples

> right through your code. How are you going to

> insulate yourself from those changes? Tight coupling

> is a killer. Have you thought about how to isolate

> it? Your problem is much bigger than casting.

Coupling between whom? As said above I have a parser that parses String messages coming from a stream and uses a factory that creates concrete message instances. The factory returns a interface that defines all methods that are needed for the further parsing of the message. Then when the parsing of this message is finished the object is handed to the message handlers. But since the parser only knows about the common interface and the handlers want to access message specific functions the casting becomes necessary. So the parser and the factory are loosely coupled because they only share the common interface and the parser and the message handlers also only share the common interface.

IngoSeidela at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 16
> This sentence reflects a profound misunderstanding.> This person could not have read the book. If they> did, they did not understand it.<sigh> Brain first, mouth second. I needed morecoffee.
es5f2000a at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 17

> Coupling between whom? As said above I have a parser

> that parses String messages coming from a stream and

> uses a factory that creates concrete message

> instances. The factory returns a interface that

> defines all methods that are needed for the further

> parsing of the message. Then when the parsing of this

> message is finished the object is handed to the

> message handlers. But since the parser only knows

> about the common interface and the handlers want to

> access message specific functions the casting becomes

> necessary. So the parser and the factory are loosely

> coupled because they only share the common interface

> and the parser and the message handlers also only

> share the common interface.

A question that pops up immediately now: why do you have different implementations for each Message type when you are using Handlers afterwards to process each Message depending on its type? You have a tightt coupling here between the XML/String messages and these Message classes and thus the Handlers operating on them.

stefan.schulza at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 18

> A question that pops up immediately now: why do you

> have different implementations for each Message type

> when you are using Handlers afterwards to process

> each Message depending on its type?

Because I wanted to split the logic of different messages into different classes and because then the factory is easy, since you can generate message objects using reflection.

> You have a tightt

> coupling here between the XML/String messages and

> these Message classes and thus the Handlers operating

> on them.

I see, didn't think of it that way. The tight coupling between messages and handlers is intended but the problem is the parser in between who only knows the interface. If I let the parser and the factory access the whole message hierarchy, the creation process becomes more complicated, because I have to create each message seperately. Maybe I should really consider a whole redesign, but until now nothing good has come to my mind.

IngoSeidela at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 19

> Coupling between whom?

Sender and receiver.

> As said above I have a parser

> that parses String messages coming from a stream and

> uses a factory that creates concrete message

> instances. The factory returns a interface that

> defines all methods that are needed for the further

> parsing of the message. Then when the parsing of this

> message is finished the object is handed to the

> message handlers. But since the parser only knows

> about the common interface and the handlers want to

> access message specific functions the casting becomes

> necessary. So the parser and the factory are loosely

> coupled because they only share the common interface

> and the parser and the message handlers also only

> share the common interface.

Describe that interface. Sounds like nothing more than "I expect an XML string here."

So if someone sends a new kind of XML message, what happens?

Forgive my guesses. Since you've provided almost no information, I'm using my imagination.

%

duffymoa at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 20

> > This sentence reflects a profound

> misunderstanding.

> > This person could not have read the book. If they

> > did, they did not understand it.

>

> <sigh> Brain first, mouth second. I needed more

> coffee.

No worries. I've been guilty of it, too.

%

duffymoa at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 21

> Describe that interface. Sounds like nothing more

> than "I expect an XML string here."

>

> Forgive my guesses. Since you've provided almost no

> information, I'm using my imagination.

To give you a better a picture, I'll provide the overall structure:

class Parser {

MessageHandler1 msgHandler;

public void parse(String xml) {

AMessage msg = Factory.create(//name of msg);

// do parsing

msgHandler.handleMsg(msg);

}

}

class Factory {

public static AMessage create(String msgName) {

// create new concrete message, using reflection and return super type

}

}

abstract class AMessage {

public void setSomething(String value) { // code }

// Additional setters that will be used by the parser to set message attributes

public String getSomething() { // code }

// Additional Getters that can be used by the message handlers

public void handleSpecificElement(String element, String value);

}

class ConcreteMsg1 extends AMessage {

String specialAttr;

String getSpeciality() { return specialAttr; }

handleSpecificElement(String element, String value) {

if (element.equals("special1")) { specialAttr = value; }

}

}

class ConcreteMsg2 extends AMessage {

List<String> specialAttrs;

List<String> getSpciality() { return specialAttrs; }

handleSpecificElement(String element, String value) {

if (element.equals("special2")) { specialAttrs.add(value); }

}

}

class MessageHandler1 {

MessageHandler2 nextHandler;

public void handleMessage(AMessage msg) {

if (msg instanceof ConcreteMsg1) {

handleMessage( (ConcreteMsg1) msg);

} else {

nextHandler.handleMessage(msg);

}

}

public void handleMessage(ConcreteMsg1 msg1) {

// do something with this concrete msg

}

}

class MessageHandler2 {

public void handleMessage(AMessage msg) {

if (msg instanceof ConcreteMsg2) {

handleMessage( (ConcreteMsg2) msg);

} else {

// Error: Message can not be handled

}

}

public void handleMessage(ConcreteMsg2 msg) {

// do something special with concrete msg 2

}

}

Sorry to post so much code, but I think now everyone can get a clear picture of my architecture.

> So if someone sends a new kind of XML message, what

> happens?

The message can not be handled (reflection would fail in creating a concrete instance) but the message protocol is known in advance, so there will be no new types of message sent.

IngoSeidela at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 22
Patterns are used when there's a need for them. Factory method pattern is used when the client doesnt know which class to instantiate, it's not the case with your code. So, dont use factory !
mipsmea at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 23

How about this: provide an interface for the common functions and an interface for functions specific to a certain type of message. That way you are only bound to the interface and not to the implementations. You'll still have to typecheck and cast, but you are bound to an interface. The 2 interfaces provide 2 different windows to look into the same class.

Peetzorea at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 24

I think, I have mentioned it before: forget about using separate classes for each message. As your code shows, each handler only treats one kind of messages. Make your Message class implement somewhat like this interface:public interface Message {

enum Type { A, B, C };

Type getType();

String getMessage();

}

of course replacing A, B, C with the appropriate message types and add all the metadata and content as getters, too.

You can then use an EnumMap<Message.Type, Handler> to map the specific Handler to a message type and treat the message's content appropriately. The handling should be part of the Handler's knowledge not the Message's.

stefan.schulza at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 25

I wholeheartly agree with duffymo's post from 14 Jan 10:01!

Visitor Pattern is the weapon of choice for exactly your problem.

I will only sketch the solution, starting from your code:

class Parser

{

public void parse(String xml)

{

AMessage msg = Factory.create(//name of msg);

// do parsing

msg.accept(msgHandler);

}

...

}

// I prefer interface over your abstract class

interface IMessage

{

public void accept(IMessageHandler msgHandler);

...

}

class ConcreteMsg1 implements IMessage

{

public void accept(msgHandler)

{

msgHandler.handleConcreteMsg1(this);

}

...

}

interface IMsgHandler

{

public void handleConcreteMsg1(ConcreteMsg1 msg);

public void handleConcreteMsg2(ConcreteMsg2 msg);

...

}

class MessageHandler1 implements IMsgHandler

{

public void handleConcreteMsg1(ConcreteMsg1 msg)

{

// now you can do what you want with ConcreteMsg1

// i.e.:

handleMsg(msg);

}

public void handleConcreteMsg2(ConcreteMsg2 msg)

{

// other implementation dealing with ConcreteMsg2

}

}

Voila! No ugly casting. And it can be combined with the wonders of overloading and overriding - the handleMsg(msg) may be inherited from a superclass of the msghandler and it may have superclass of ConcreteMessage1 as parameter in the signature. (Well - this should be used only cautiously! Easy to loose track on which method gets actually called).

As the GoF Book says it, this assumes new MsgTypes occur only rarely, as you would have to add a new method to all MessageHandlers then.

And it works only for a relation between two Hierarchies (therefore double dispatch). If there are more, you need MultiMethods which (currently?) do not exist in Java.

Horst_Ma at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 26

Looking at my code again there is no need to call the visitor IMessageHandler:

So instead:

interface IMessage

{

public void accept(IMessageHandler msgHandler);

...

}

interface IMsgHandler

{

public void handleConcreteMsg1(ConcreteMsg1 msg);

public void handleConcreteMsg2(ConcreteMsg2 msg);

...

}

it is better to name it like this:

interface IMessage

{

public void accept(IVisitor visitor);

}

interface IVisitor

{

public void visitConcreteMsg1(ConcreteMsg1 msg);

public void visitConcreteMsg2(ConcreteMsg2 msg);

...

}

This makes it more clear that the IMessage has no knowledge about the visitor and can be used with different types of visitor - hierarchies.

(E.G. one for building up a DOM tree, one for transforming using some XSLT, one for storing it in an IMS database, ...)

Horst_Ma at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 27

I wonder, what the benefit of the Visitor approach would be? Each handler would have to implement handling methods for each existing type of Message. So the OP says, the kind of messages is known in advance. If it wasn't , for each new Message class one would have to make all Visitors to implement a new class (or use the abstract handler approach working with stubs). I honestly see no design benefit to the OP's approach on type checking, which actually needs less changes on changing requirements wrt. messages as the handler's decide, which type of message it supports.

stefan.schulza at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 28

> I wonder, what the benefit of the Visitor approach

> would be?

No casting required.

> Each handler would have to implement

> handling methods for each existing type of Message.

> So the OP says, the kind of messages is known in

> advance.

Yes, that's a prerequisite for the Visitor Pattern.

> I honestly see no design benefit

> to the OP's approach on type checking, which actually

> needs less changes on changing requirements wrt.

> messages as the handler's decide, which type of

> message it supports.

The Visitor pattern has as prerequisite that adding new message types is rare, ideally does not occur at all.

The benefit of the pattern (besides no casts) is that you can add new message-handlers without changing the message types.

Horst_Ma at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 29

Even more, if you look at the OPs usage of the Chain-of-Command Pattern to find out the MessageHandler which "matches", it's even better to use Visitor instead.

The Visitor - pattern calls the corrent method directly (without having to iterate over the chain of handlers) and can statically check that the method is at least there (you could of course trick it with an empty method).

If you need to introduce a new message type, you add the method in the message-handler - interface and the compiler will tell you all the concrete handlers you have to extend.

The OPs solution does not guarantee this; you may oversight a message-handler and find out at runtime.

If you find that preferable, welcome to the wonderful world of dynamically typed languages!

Horst_Ma at 2007-7-8 8:51:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 30

> The Visitor pattern has as prerequisite that adding

> new message types is rare, ideally does not occur at

> all.

Ok, so you're replacing the casts with stubs and a bloated Interface. I'm still not convinced that this is "good design". :)

Btw., you wouldn't have to name the visitor's methods differently, as you will have different signatures by parameter types (at least the message type will be different).

dit: Actually, if either design is suitable depends on some requirements both of us assume the OP has. If each Handler has to handle all messages, the Interface approach seems a good choice. If handlers are dedicated to handle specific types of messages, the one-Message-class approach would be a good choice.

stefan.schulza at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 31

> Ok, so you're replacing the casts with stubs and a

> bloated Interface. I'm still not convinced that this

> is "good design". :)

And i wouldn't say that casts and testing objects via instanceof per se is a good design. At least in circumstances where it could be avioded and the trade-offs won't hurt.

Java finally has take care for the most urgent uses of casts by introducing Generics.

In C++, usage of dynamic-casts is a rare exception (and was something that was not in the original release, but added later IIRC).

My impression is that the visitor pattern was intended for the C++ language and showed that the problem can be solved without requiring the message types knowing all the handlers.

In the original post it was asked for "a possibility to avoid the type checking and casting" and the further specifications the OP gave let me believe that visitor pattern is appropriate in this case.

>

> Btw., you wouldn't have to name the visitor's methods

> differently, as you will have different signatures by

> parameter types (at least the message type will be

> different).

Well, that's how the visitor pattern is described in the book of Gamma, Helm, Johnson and Vlissides.

Using method overloading is a dangerous thing: The compiler will decide which method to call and it diispatches on the static type, not on the real type of the object.

This is not a problem in this example, but still it is considered bad practice by some:

http://c2.com/cgi/wiki?JavaMethodOverloading

>

> dit: Actually, if either design is suitable depends

> on some requirements both of us assume the OP has. If

> each Handler has to handle all messages, the

> Interface approach seems a good choice. If handlers

> are dedicated to handle specific types of messages,

> the one-Message-class approach would be a good choice.

I agree, the circumstances decide if a pattern could be used gainfully.

Horst_Ma at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 32

> Using method overloading is a dangerous thing: The

> compiler will decide which method to call and it

> diispatches on the static type, not on the real type

> of the object.

> This is not a problem in this example, but still it

> is considered bad practice by some:

>

> http://c2.com/cgi/wiki?JavaMethodOverloading

It's not really overloading in this case, as there is no handler for the common interface of all messages, but only for concrete implementations. As method binding happens at compile time, calling visit(this) never is ambiguous.

But I actually don't care, as the OP seemed to have lost interest in his post or got a solution that suites him for now. ;)

stefan.schulza at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 33

> For what it's worth, I'm with duffymo on this. That

> code smells to me.

>

> GoF has several patterns which break OO. Their Mediator, for

> example, is a bigass if..else block. Remember that the book is old,

> and they were writing for procedural languages also.

Errr....I have a rather hard time getting past the following from that book. Perhaps if you could provide one of the patterns from that book that demonstrates the original usage from a procedural language? Just looking briefly I found the following....

Foreword...."All well-structured object-oriented architectures are full of patterns"

Introduction (1.1)..."Even though Alexander was talking about patterns in buildings and towns, what he says is true about object-oriented design patterns."

jschella at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 34

> The XML messaging ought to give you loose coupling,

> but it sounds like your design is doing exactly the

> opposite. You change the XML stream and it ripples

> right through your code. How are you going to

> insulate yourself from those changes? Tight coupling

> is a killer. Have you thought about how to isolate

> it? Your problem is much bigger than casting.

>

If I accept a message for placing an order into an inventory system and the order message changes then please explain to me how you are going to avoid changing the code that actually updates the inventory system?

For example consider the following message versions.

version 1 = <order type="widget">5</order>

version 2 = <order>

<type>widget</type>

<quantity>5</quantity>

<salesrep>JohnDoe</salesrep>

</order>

jschella at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 35

> Factory method pattern is used when the client doesnt

> know which class to instantiate, it's not the case

> with your code. So, dont use factory !

The first part of that incorrectly describes a factory. A factory is intended to allow actual instantiation by other classes.

When I use a DAO factory the clients know exactly what class they want created. They do not know the correct way to instantiate them however.

jschella at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 36

Thanks for all your replies and suggestions!

I began to think about replacing my design with the visitor pattern, although this also has some drawbacks as was already pointed out (stubs, all handlers must provide implementations for each message type). At least you can avoid the casts, the instanceof operations and the compile time safety would also be a plus. Furthermore message types won't change frequently which makes the Visitor pattern also appealing.

Concerning stefans suggestion I have a question:

public interface Message {

enum Type { A, B, C };

Type getType();

String getMessage();

}

> of course replacing A, B, C with the

> appropriate message types and add all the metadata

> and content as getters, too.

Where would the metadata and the getters/setters, etc. be defined? Should they be defined in the enum declaration? Because this would make the enum very big and all the code would be in one place.

IngoSeidela at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 37

> Concerning stefans suggestion I have a question:

> > public interface Message {

>enum Type { A, B, C };

> Type getType();

>String getMessage();

>

> > of course replacing A, B, C with the

> > appropriate message types and add all the metadata

> > and content as getters, too.

>

> Where would the metadata and the getters/setters,

> etc. be defined? Should they be defined in the enum

> declaration? Because this would make the enum very

> big and all the code would be in one place.

Of course not. The enum only holds the types of messages, so one can identify it and register a handler for a type of message (i.e., if you have one handler per message type, otherwise you would have to map an array of handlers to a message type).

Metadata and data would be stored within the Message object. I'm not sure, how different your message data will be. In a generic case, one could use some getAttribute/setAttribute approach to access named data of a message. But maybe, this is not appropriate in your case, if only the Message knows about how to represent the data as specific Object or if specific Object types are needed.

stefan.schulza at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 38

> Metadata and data would be stored within the Message

> object. I'm not sure, how different your message data

> will be. In a generic case, one could use some

> getAttribute/setAttribute approach to access named

> data of a message. But maybe, this is not appropriate

> in your case, if only the Message knows about how to

> represent the data as specific Object or if specific

> Object types are needed.

Ok, I somehow thought that your solution would only have one message class. Yes in my case it does not suffice to access the data only through named members, so I can't use that approach.

IngoSeidela at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...
# 39

> dit: Actually, if either design is suitable depends

> on some requirements both of us assume the OP has. If

> each Handler has to handle all messages, the

> Interface approach seems a good choice. If handlers

> are dedicated to handle specific types of messages,

> the one-Message-class approach would be a good choice.

Rereading the whole thread it appears to me our disagreement was caused by interpreting the example of the OP and coming to different assumptions what the requirements are.

If it really is an explicit requirement that each message type must be processed by a different MessageHandler, i agree that the Visitor approach is misused.

My idea was that the message handler contains methods to handle all message types - so no stub methods.

If one really requires to have separate message handler classes for each message type, i would favor your approach.

It still is possible to use the visitor approach then, but in a modified way:

The visitor works as dispatcher which delegates the processing to individual message handlers:

class MessageDispatcher implements IVisitor

{

ConcreteMsg1Handler msg1handler;

ConcreteMsg2Handler msg2handler;

...

public void visitConcreteMsg1(ConcreteMsg1 msg)

{

msg1handler.handleMsg(msg);

}

public void visitConcreteMsg2(ConcreteMsg2 msg)

{

msg2handler.handleMsg(msg);

}

}

The ConcreteMsgHandler-classes do not (necessarily) implement an interface, the dispatcher knows their real type.

While this solution avoids the casting and does not use stub methods, it is some overhead which will pay only in some scenarios.

The dispatcher links the calls to the concrete implementations of the message handlers, so i.e. exchanging the dispatcher may allow to bind to mock handlers for testing purposes.

null

Horst_Ma at 2007-7-8 8:51:52 > top of Java-index,Other Topics,Patterns & OO Design...