aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Question about interfaces and different implementation Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Question about interfaces and different implementation" Watch "Question about interfaces and different implementation" New topic
Author

Question about interfaces and different implementation

Shuai Liu
Ranch Hand

Joined: Jan 25, 2002
Posts: 49
Hi all, this is probably a beginner's question: how can I design it so that I can call methods given in certain interfaces without knowing which implementation of the interface is actually being used?
For example, Xalan calls XML parser and obviously It doesn't require certain implementation to be used, and no code change is required when I change from one implementation to another. How does it pick up either Xercers or JAXP jars I drop in?
A friend suggested Abstract Factory pattern. It makes sense but I am not sure how to actually implement it.
Thank you for you time.
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
I think your question is a bit too broad. The easiest answer is just to create an interface. When an object is passed as a parameter, use the interface name, rather than a concrete class:

Of course, this is fine and dandy when you are writing myMethod(). You simply rely on the methods from MyInterface. But if you are calling myMethod() from somewhere else, you still need to create a concrete object that implements MyInterface. I assume your real question is how to go about creating this object.
Your friend is (somewhat) correct. Abstract Factory is one solution to this problem. There are several other patterns that address the "creation issue" as well. Which one you use depends on the constraints of the given system you are designing/implementing. In short, you need to give some more details about your specific project in order to decide which patterns fit well. Even then, it sometimes boils down to a personal preference, imho.


Java API Documentation
The Java Tutorial
Shuai Liu
Ranch Hand

Joined: Jan 25, 2002
Posts: 49
Thank you for your reply, Layne. Here goes an example:
Let's say I have an interface
<code>
public interface IEnvironmentVariable
{
public String getSomething();
}
</code>
and I may have two concrete classes that implement IEnvironmentVariable
<code>
public class EnvironmentVariableImpl1 implements IEnvironmentVariable
{
public String getSomething()
{
return "something from a xml file";
}
}
public class EnvironmentVariableImpl2 implements IEnvironmentVariable
{
public String getSomething()
{
return "something from database";
}
}
</code>
and in my user class, I want to call getSomething in IEnvironmentVariable(directly or indirectly) without knowing which implementation is called.
I want to make it so that I can change the actual implementation class in different applications without making ANY code changes in my user class. The only thing I want to do is to swap the implementation classes(may be a jar file).
I can't set the actual concrete class by using myMethod(MyInteface param) because I don't have any knowledge of the concrete class to be created.
Does that sound crazy?
[ June 16, 2003: Message edited by: Shuai Liu ]
Richard Jensen
Ranch Hand

Joined: May 14, 2003
Posts: 67
Originally posted by Shuai Liu:
Let's say I have an interface

and in my user class, I want to call getSomething in IEnvironmentVariable(directly or indirectly) without knowing which implementation is called.
...

This is what you do. When people use the interface they don't know (and shouldn't care) what the actual implementation is. Think about the Collections interfaces. When I write a function that returns a List, I (as the developer) make a choice of whether the ArrayList or TreeList is better suited to the particular application, but all I advertise to the user of the class is that they have a List.
Yes, somebody somewhere has to have a reason for creating one specific concrete class, but I'm not sure why that is causing you concern.
I can't set the actual concrete class by using myMethod(MyInteface param) because I don't have any knowledge of the concrete class to be created.
Does that sound crazy?

I'm just not understanding your real concern. The factory approach alluded to in an earlier post would basically say something like:
make me a list that is good for random access or
make me a list that is easy to keep ordered or
make me an instrumented list for tracing...
The factory determines the specific subclass, but the caller shouldn't care which type is given to them. They just rely on the List interface.


Richard
N 37 33 W 122 18
Shuai Liu
Ranch Hand

Joined: Jan 25, 2002
Posts: 49
Richard, if I understood you correctly, I will have a factory like this:

and the author can change the concrete class ( EnvironmentVariableImpl1 in this case) being returned to the user.
But my real problem is: in my factory class, I don't know what concrete class to create, so it would look like

so that I don't need to change the getEnvironmentVariable() method in MyEnvironmentVariableFactory class, and it will return the current available implementation of IEnvironmentVariable. I want MyEnvironmentVariableFactory be able to pick up the available implementaion itself at run time.
I assume that one way I can do it is that I specifiy the classname of the implementation in some sort of property file that my Factory class can read and use reflection to create the concrete class on the fly. I am just wondering if there is a simpler/cleaner way.
I hope that I made myself understandable.
Thank you for your time.
[ June 16, 2003: Message edited by: Shuai Liu ]
[ June 16, 2003: Message edited by: Shuai Liu ]
John Wetherbie
Rancher

Joined: Apr 05, 2000
Posts: 1449
At some point you do have to know what concrete instance to create. You could have a string param for your factory method that would tell it what derived class to instantiate. This will (hopefully) solve your problem.


The only reason for time is so that everything doesn't happen all at once.
- Buckaroo Banzai
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Shuai, you first need to decide which class(es) should decide about the actual implementation to use. What are your needs?


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
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
I am also somewhat confused about the question. As stated, you HAVE to decide SOMEWHERE which concrete instance to use. The AbstractFactory pattern simply centralizes this decision into one class. Once the object is created, it can be returned as the interface and dealt with in that manner, but you DO have to eventually decide which concrete class to use.
I think now we need an idea of how this portion of code fits in with the rest of the program. What other classes are involved and how do they interact with each other?
Richard Jensen
Ranch Hand

Joined: May 14, 2003
Posts: 67
Originally posted by Shuai Liu:
Richard, if I understood you correctly, I will have a factory like this:

and the author can change the concrete class ( EnvironmentVariableImpl1 in this case) being returned to the user.
But my real problem is: in my factory class, I don't know what concrete class to create, so it would look like

so that I don't need to change the getEnvironmentVariable() method in MyEnvironmentVariableFactory class, and it will return the current available implementation of IEnvironmentVariable.

This is basically the idea, but put some logic in the factory.

I want MyEnvironmentVariableFactory be able to pick up the available implementaion itself at run time.
I assume that one way I can do it is that I specifiy the classname of the implementation in some sort of property file that my Factory class can read and use reflection to create the concrete class on the fly.

Are the classes that implement the interface dynamic or fixed? That is, do you know all the possible types when you code the factory class or do you have to allow for an unknown class to be used at runtime? Reflection handles the latter case, but can be a bit tricky.
Shuai Liu
Ranch Hand

Joined: Jan 25, 2002
Posts: 49
John,Ilja and Layne
Sorry I still didn't state the question clearly. So here it goes again:
For an example, in Xalan document, the authors ask the user to "The SAX, DOM, and JAVAX interfaces are in xml-apis.jar. These interfaces are shared by a number of tools (Xalan-Java, Xerces-Java, etc.), so placing them in a separate JAR simplifies coordination and reduces risk of duplication. Be sure to put both JAR files (and xercesImpl.jar or another JAXP 1.2-compliant XML parser) on your classpath!"
Obviously, Xalan utilize SAX and DOM interface in xml-apis.jar and I am responsible for providing an implementation of those XML parsers(Xerces or JAXP). Since Xalan doesn't depend on certain implementation, I could possibly write my own JAXP 1.2-compliant XML parser and use it. Bottom line is, Xalan doesn't know what implementation I am using.
So John: I can't have a string param for my factory method since I don't know what derived class to instantiate. I want the return type changes as I changes the actual implementation I use(again, without changing anything in factory class).
Ilja: I assume that some sort of Factory class will decide about the actual implementation to use. But the factory class shouldn't have that knowledge hard wired. That means, when I decide to use another implemenation, I don't need to change anything in the Factory class. In the case of Xalan, I can replace the parser from Xerces to my own parser and Xalan can pick it up.
Layne: I understand that my question is kinda vague and maybe the pattern to use is not Abstract Factory. What I want to achieve is something like the way Xalan utilize XML parser interface. Let's say Xalan is my user class and it get a XML parser via some sort of factory class. The factory class shall return Xalan the available implemenation of XML parser interface based on certain rules. The rules should be flexible such that the facotry won't know what particular concrete class to call until run time. That way it can return any kind of implemenation without change the code.
Sorry for my English if you guys still don't know what I am talking about.
[ June 17, 2003: Message edited by: Shuai Liu ]
Shuai Liu
Ranch Hand

Joined: Jan 25, 2002
Posts: 49
Originally posted by Richard Jensen:

Are the classes that implement the interface dynamic or fixed? That is, do you know all the possible types when you code the factory class or do you have to allow for an unknown class to be used at runtime? Reflection handles the latter case, but can be a bit tricky.

Yes the classes that implemenat the interface is dynamic. It's the later case and I assume that reflection is necessary.
I was looking at the source code of Xalan, it picks up the implemenation by looking for certain system property. Is that the standard way to do it?
In that case, when I swap my implementation class, I need to update some kind of property like "IEnvorinmentVariableImp" to be "Foo.Bar.SomeClass" so that I can load the class at run time?
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Most factory implementations have a default that they use that can be overridden at run time. You can do it through a property file (or even better, use the Preferences class) or through a system property.


Associate Instructor - Hofstra University
Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
Shuai Liu
Ranch Hand

Joined: Jan 25, 2002
Posts: 49
Thomas,
Yeah, that makes sense. Just one more thing. When I switch XML Parsers, I don't need to make property or config file changes(I only need to include different jars in my classpath) and Xalan seems to be able to pick it up, how is that implemented?
Thank you.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
I guess that Xalan makes use of JAXP here (which is Suns implementation of Factories for XML parsers etc.).
Take a look at the jar file of your parser. There should be a META-INF/services folder. The content of the files in this folder defines which actual classes will get instanciated.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Question about interfaces and different implementation