File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes OO, Patterns, UML and Refactoring and the fly likes Design pattern needed Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Design pattern needed" Watch "Design pattern needed" New topic
Author

Design pattern needed

John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Hi,
I currently have a set of XML messages for which i am designing wrapper classes. These messages are in the form of requests and responses. I want to create a method on a Connection object that will send the request and return the response.
However i cant seem to figure a way that i can get one sendRequest method to be able to send all my requests and deliver responses. Will i need to have a sendRequest method for each pair of messages i have?
As an example i have four XML message, GetAccountBalance, BalanceResponse, WithdrawMoney, MoneyWithdrawlResponse and four corresponding wrapper classes.
I could have a ConnectionObject that has a method to send the request e.g.
public BankResponse sendRequest( BankRequest request )
this would assume that all my Requests inherited from BankRequest and all Responses inherited from BankResponse. However this would be of no use to me as i could not use the specific accessor methods of the message classes which would be the main reason for having the wrapper classes.
These wappers are going to be provided as an API so i dont want the client to have to use instanceOf or reflection.
Any suggestions welcome

John
[ July 16, 2002: Message edited by: John Ryan ]
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
How about your Connection object contains a List of objects which implement an interface (e.g. MessageTransaction) which defines a send method.
Then to send and receive all the configured messages, just iterate through the elements of the list and run "send" on each one.
Or have I missed the point of your question ?


Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Hi Frank,
I would be sending the messages one at a time so i wouldnt need the List.
I am thinking about having each Request Message class implement a Request interface which has a send Method. This send method would take the Connection object as a parameter (rather then the other way around, the Connection object being given the message which i thought about originally). That means that each message could use the Connection object in its own particular way.
However i now have the problem that the sendMethod in the Request interface should have the return type of the appropriate response message. This i cant do as the return type of the interface send method cannot vary upon implementation. So i now no better off. What was your thinking regarding the return type from the send method on your MessageTransaction class??
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
Hmm. You could always make it an Object, and cast it as needed. On the other hand if your returned messages have anything in common you could return an interface or base class. What sort of behaviour do these returned message wrappers have ? what wil you do with one when you get it back ?
Can we step back a little and ask what is the purpose of these "wrapper" classes ? It seems that they are causing a lot of head scratching, so maybe there is a simpler way of achieving the same ends. Can you list the benefits of using a "wrapper" class?
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Originally posted by Frank Carver:
Hmm. You could always make it an Object, and cast it as needed. On the other hand if your returned messages have anything in common you could return an interface or base class. What sort of behaviour do these returned message wrappers have ? what wil you do with one when you get it back ?
Can we step back a little and ask what is the purpose of these "wrapper" classes ? It seems that they are causing a lot of head scratching, so maybe there is a simpler way of achieving the same ends. Can you list the benefits of using a "wrapper" class?

If i was to return the response messages from the sendMethod the clients of the API would more than likely use the accessor methods to get the information returned and and perhaps display it on a GUI. Each wrapper class would have different accessor methods so i dont think there is anything which i could put into an interface or an abstract class. Also I would not think it is feasible that a client of an API should have to cast a return type.
How about returning a boolean from the send message to indicate success and then have the client access the returned message using an accessor method. Each request class would have a different accessor for its own response message???
Well the XML messages are a set of industry defined messages. Im thinking of creating these wrapper classes so that clients would have an easy way so create these messages and then send them to a service provider who can return the appropriate response all using the provided API. I think giving someone an API for these messages makes them easier to use, and also ensures that we dont have to check that the XML string submitted is valid.
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
OK, how "tree-like" is the data contained in the wrapper classes? My guess is that it is just a set of name-value pairs. If so, have you considered abandoning the custom classes and just returning a Map? This provides the ability to get individual named entries and iterate through them to display them "for free".
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
And for your interest, there is a similar discussion going on in later parts of this other thread.
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Originally posted by Frank Carver:
OK, how "tree-like" is the data contained in the wrapper classes? My guess is that it is just a set of name-value pairs. If so, have you considered abandoning the custom classes and just returning a Map? This provides the ability to get individual named entries and iterate through them to display them "for free".

Well not exacly. Theoretically I suppose the message classes are like that, but each message will have a number of subelements which can have subelements (just typical XML). If i was to use a MAP clients of the API would then need to understand the structure of the XML to get the Values out and this would remove a lot of value from the API....
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by John Ryan:
However i cant seem to figure a way that i can get one sendRequest method to be able to send all my requests and deliver responses. Will i need to have a sendRequest method for each pair of messages i have?

I think here are two different forces at work:
First, you want to present your clients an as explicit API as possible - you want to abstract from the XML messages and String keys and they shouldn't need to cast anything. To accomplish this, it would possibly be a good idea to give every Request object a send method which returns the appropriate Response object.
OTOH, you want to avoid duplicated code. The send methods are probably very similar - you might even need only one if factored properly.
So what do we do to get the best of the two worlds? It's hard to say without working directly on the code, but here is a rough idea:
The Request objects could expose the aforementioned specific send methods to the clients, but internally delegate most of the work to a general send method. The Request objects then would do all the casting, so that the clients don't need to care about it.
How does that sound to you?


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
John Ryan wrote: Well not exacly. Theoretically I suppose the message classes are like that, but each message will have a number of subelements which can have subelements (just typical XML). If i was to use a MAP clients of the API would then need to understand the structure of the XML to get the Values out and this would remove a lot of value from the API....
I'm even more puzzled then. Can you give me some examples of the "accessor methods" provded by your wrapper classes?
It seems to me you might have two possible types: Ones which return a specific value from somewhere in the returned message tree (e.g. String getDestinationAddress(), int getRowCount() ) and ones which return some complex type which requires further knowledge of what to do with it (e.g. AddressDetails getAddressDetails(), Iterator getMessageParts() ). In both these cases you actually have a simple name-value mapping (from the method name to the returned object) which could be represented in a Map.
Are you planning to use some other sort of "accessor" which I can't think of right now ?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Frank, you are certainly right that every set of properties can be implemented as a Map.
The advantage of a Map is also its drawback: flexibility. As a Map can contain any property, it is often hard to see what properties it *does* contain. If you don't get a property you expected to get, it is hard to find out wether that is because the property is wrongly missing, because you were wrong in expecting the property or because you simply used the wrong key. There are solutions to work around these problems, but they will make the system even more complex.
Simply said: using a Map not only adds flexibility, but also complexity. If you have a fixed set of properties, you are therefore most probably well advised to stick to simple fields and accessor methods.
BTW, Martin Fowler has written a good article on this topic: http://www.martinfowler.com/apsupp/properties.pdf
Regards, Ilja
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
Oh I agree it's a flexibility/complexity tradeoff. But in the particular situation described here, where someone wants to have a single data type to return from a "send" method, a Map nicely cuts through the crap.
I'm not saying that it has to be an unadorned HashMap or whatever, though.
I often subclass or decorate Maps to provide extra, specific, typed accessors, but leave the basic Map behaviour available. Then any client code may use the generic get/put/iterator interface if it doesn't need to know about specific types and accessors (such as when rendering all attributes to a form or table), and the specific ones if it knows about the domain classes and wants type-safe access to specific values.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Frank Carver:
Oh I agree it's a flexibility/complexity tradeoff. But in the particular situation described here, where someone wants to have a single data type to return from a "send" method, a Map nicely cuts through the crap.

I understood the original question to be about wether to use a single data type or not, not about how to implement a single data type. I might be wrong, of course.

I'm not saying that it has to be an unadorned HashMap or whatever, though.

I see.
I often subclass or decorate Maps to provide extra, specific, typed accessors, but leave the basic Map behaviour available. Then any client code may use the generic get/put/iterator interface if it doesn't need to know about specific types and accessors (such as when rendering all attributes to a form or table), and the specific ones if it knows about the domain classes and wants type-safe access to specific values.

Mhh, I wonder wether the OP does *need* the generic behaviour.
Regards, Ilja
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
Ilja wrote: I wonder wether the OP does *need* the generic behaviour.
That's one thing we haven't asked yet. What use is planned for the returned data. I may have been jumping to cvonclusions based on the similar thread I referred to, but often the end results are just iterated through and presented to the user. In this case, the use of custom classes and specific accessors just gets in the way.
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Originally posted by Ilja Preuss:

I think here are two different forces at work:
First, you want to present your clients an as explicit API as possible - you want to abstract from the XML messages and String keys and they shouldn't need to cast anything. To accomplish this, it would possibly be a good idea to give every Request object a send method which returns the appropriate Response object.
?

Yes I would wish the API to be explicit so that is my reason for having an appropriate Response object
Originally posted by Ilja Preuss:

OTOH, you want to avoid duplicated code. The send methods are probably very similar - you might even need only one if factored properly.
So what do we do to get the best of the two worlds? It's hard to say without working directly on the code, but here is a rough idea:
The Request objects could expose the aforementioned specific send methods to the clients, but internally delegate most of the work to a general send method. The Request objects then would do all the casting, so that the clients don't need to care about it.
How does that sound to you?

That is exactly my thinking at the moment and what i think is most appropriate........
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Originally posted by Frank Carver:

I'm even more puzzled then. Can you give me some examples of the "accessor methods" provded by your wrapper classes?
It seems to me you might have two possible types: Ones which return a specific value from somewhere in the returned message tree (e.g. String getDestinationAddress(), int getRowCount() ) and ones which return some complex type which requires further knowledge of what to do with it (e.g. AddressDetails getAddressDetails(), Iterator getMessageParts() ). In both these cases you actually have a simple name-value mapping (from the method name to the returned object) which could be represented in a Map.
Are you planning to use some other sort of "accessor" which I can't think of right now ?


No thats exacly it but by using a name value mapping it would be necessary that the clients of the API know which values exist in the Map and as Ilja said i wish by API to be as explicit as possible ( and a Map would not be explicit )
John Ryan
Ranch Hand

Joined: Mar 14, 2001
Posts: 124
Originally posted by Frank Carver:
Ilja wrote: I wonder wether the OP does *need* the generic behaviour.
That's one thing we haven't asked yet. What use is planned for the returned data. I may have been jumping to cvonclusions based on the similar thread I referred to, but often the end results are just iterated through and presented to the user. In this case, the use of custom classes and specific accessors just gets in the way.


I suppose with the API I want the clients to be able to access a specific set of data. Really what they do with that data is up to themselves. It may be presented on a GUI or perhaps it may be integrated into an existing application to expand its functionality.............
Eduard Jodas
Ranch Hand

Joined: May 14, 2002
Posts: 80
If I were you, I would choose to implement the send method as:
1. Object Connection.send(Request)
or
2. Object Request.send(Connection)
and let the user cast the response. After all, we are coding in Java, so casting is always required.
However, a possible solution with specific Response wrappers would be:
1. Object Connection.send(Request)
you may have a Request class, parent of all possible requests. This parent class would have a set of methods like:
public void response(ResponseWrapper1 aResp){}
public void response(ResponseWarpper2 aResp){}
so one response(XXXX) method for each possible answer. This way, the Connection.send method, before returning, can decode the response and call the appropiate method in Request. If the user wants to 'listen' to one specific response he/she has to subclass the Request and override the desired method.
2. Object Request.send(Connection)
Basically this solution is equal to the previous one, but here the Request Object has the control. This way the response(XXXX) methods can be protected instead of public, what I like more (again personal likes/dislikes).

With both methods the user can choose between casting the return object of the send() method or subclassing the Request object in order to listen to one or more possible responses (in general, freedom of choice -> happier users)
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Design pattern needed