Is the Factory Pattern suitable for this?

Hi guys,

I have the following question: I have some functionality which is divided in two parts: basic functionality that is created implementing only one interface , i.e. IBasicClient, and functionality that is methods with different data types as parameters , i.e.:

ISDOClient, IStAXClient , which both have:

ISDOClient:

==============

public void fireAndForget(QName opName, DataObject payload);

public void sendReceive(QName opName, DataObject payload, DataObject result);

//... and so on

IStAXClient:

==============

public void fireAndForget(QName opName, XMLStreamReader payload);

public void sendReceive(QName opName, XMLStreamReader payload, XMLStreamWriter writer);

//... and so on

-

each of these interfaces (IStAXClient, ISDOClient, etc) extends the interface IBasicClient, which contains methods like:

public void setup();

public void engageModule();

and so on ....

the implementations of these look like that :

BasicClientImpl implements IBasicClient

SDOClientImpl extends BasicClientImpl implements ISDOClient

StAXClientImpl extends BasicClientImpl implements IStAXClient

and so on ...

My question is: How to make a factory that will most suitably instantiate these ?

There are several options which I can think of :

1) create a class ClientFactory that will have methods :

public Object newClient(String clientClassName, String arg1);

public Object newClient(String clientClassName, String arg1, String arg2);

where arg1, arg2, etc. are the parameters that constructors take. The Factory will use reflection internally, but the problem which that approach is that a developer has to explicitly cast the client to the approproate type before using it. I cannot return a "IBasicClient" type object, because IBasicClient does not contain the actual execution methods of my functionality, such as : sendReceive(...) , fireAndForget(..) and so on, so casting will also be necessary.

2) do it like that :

public ISDOClient newSDOClient(String arg1);

public ISDOClient newSDOClient(String arg1, String arg2);

....

public IStAXClient newStAXClient(String arg1);

public IStAXClient newStAXClient(String arg1, String arg2);

... etc

which is more type safe, but whenever a new "type" of client is added, the factory's public methods have to be changed, i.e. I have to add creational methods for the new type of client.

Which method 1) or 2) would you suggest, or , alternatively, is there a better way using Java to achieve what I want? Thank you very much in advance.

Regards,

Angel

[2734 byte] By [atodorova] at [2007-11-27 5:35:22]
# 1

I prefer style 2, which is more type safe. That style is also what is used by the java.util.concurrent.Executors factory (if you want an example where Java uses it).

Even though you would need to modify the factory to have a couple more creational methods for any new interface you support; I believe the pro of having that type safety and reduced confusion on the API coder outweighs short-term gains of just passing back Object which must be type-casted.

My two cents

Zoan333a at 2007-7-12 15:04:20 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

I think you are asking the wrong question.

Why do you want to branch your interfaces in this way?

Could you not create two interfaces: Payload and Result and create XMLPayload, XMLResult, DataObjectPayLoad and DataObjectResult? Or, even more simply just create XMLHandler and DataObjectHandler.

What you are ending up with is not uncommon but it's kind of pretend OO. What's the point of creating a single factory for these two interfaces? You'll have to change it anytime you add a new type of client and all the users are bound to a single type of client anyway. If you must have two versions of this interface, you might as well create two factories. It's really not any different in terms of high-level design.

dubwaia at 2007-7-12 15:04:20 > top of Java-index,Other Topics,Patterns & OO Design...