"Service provider" pattern

C

chris.senior

Most Java programmers are familiar with what I have called the "service
provider" in Java (if there is a better, more widespread name - please
tell me). In the pattern we want to discover an implementation of an
interface at runtime without caring where the implementation comes
from. For example:

public interface MyService {
public void myMethod();
}

public class MyServiceImpl {
public void myMethod() {
System.out.println("Do stuff...");
}
}

public class MyServiceFactory {
public static MyService getImpl() {
// look up class by some mechanism (e.g. system property)
Class c = Class.forName(System.getProperty("MyService.impl"));
return (MyService)c.newInstance();
}
}

public void someClientMethod() {
MyService service = MyServiceFactory.getImpl();
service.myMethod();
}


This is a pretty typical example (Log4J does something like this) but
there are lots of ever so tiny variations on the pattern littered
through the VM code and common libraries and frameworks. At the end of
this post is a shortlist of place's I have seen this pattern - I'd be
interested if anyone has seen this (or something like it) anywhere
else? Inside and outside the VM?

- Chris

* Log4J's LogFactory - Uses system property (last time I looked)
* java.beans.PropertyEditorManager - Also uses a name based search path
to look for implementations
* java.beans.BeanInfo - Uses a purely name based pattern to locate the
implementation
* JAR file service provider -
http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Service Provider
(not sure who uses this?)
* URL handlers/connections - looks in certain packages (system
property) for implementations, using the package name (e.g. https) as
part of the search.
http://java.sun.com/j2se/1.4.2/docs...ing, java.lang.String, int, java.lang.String)
* Eclipse executable extension points -
http://wiki.eclipse.org/index.php/FAQ_What_are_extensions_and_extension_points?

That's all I could think of for now...
 
C

Chris Uppal

* Log4J's LogFactory - Uses system property (last time I looked)
* java.beans.PropertyEditorManager - Also uses a name based search path
to look for implementations
* java.beans.BeanInfo - Uses a purely name based pattern to locate the
implementation
* JAR file service provider -
* URL handlers/connections - looks in certain packages (system
property) for implementations, using the package name (e.g. https) as
part of the search.
* Eclipse executable extension points -


Hmm....

When you really get down to it, I can't think of a lot outside java.lang and
java.util which /isn't/ mediated by some variant or other on this pattern (i.e.
some configurable choice of factory).

File IO stuff does it.
Network IO stuff uses it.
Charsets use it.
Crypto uses it.
AWT is built on it.
XML handling is riddled with it.
JDBC uses it.
The management and instrumentation API uses it
The debugging API uses it.
....


Come to that, loading the JVM DLL is itself an application of the pattern --
choose which vendor's implementation you want, choose which release, which
version, Decide between -client or -server (or whatever). Between them, they
specify a filename; load the named DLL, and off you go with your choice of Java
platform implementation.

I suppose it's inevitable -- if you are trying to create a common platform over
a range of lower-level features (different OSs, etc), then you have to
introduce a common interface to a pluggable implementation at some level of the
design. There aren't many other options (off-hand I can't think of any) though
the "pluggability" can be concealed or be made static (compile-time). The way
that Java works (language /and/ architecture) makes it rather natural to use
that kind of pattern, explicitly and dynamically, wherever there's the need to
interface with potentially variable lower-level systems.

And once you've got into the habit of it, you'll use it everywhere else too ;-)

-- chris
 
E

Ed Kirwan

Most Java programmers are familiar with what I have called the "service
provider" in Java (if there is a better, more widespread name - please
tell me). In the pattern we want to discover an implementation of an
interface at runtime without caring where the implementation comes
from. For example:

OTish:

I'm sure I'm missing the point, but isn't this just the factory method
pattern?

Or are you particularly highlighting the factory pattern using
class.forName() to provide the implementation? As in defining:

Service provider = factory method pattern + class.forName()

Not that I've a problem with that, just trying to see where I've veered
mirkwoodianly from the path of understanding ...
 
C

Chris Senior

Ed said:
I'm sure I'm missing the point, but isn't this just the factory method
pattern?

Service provider = factory method pattern + class.forName()

I think you're right this is mostly just factory method pattern (as in
MyServiceFactory in the example).

Sometimes you don't need a factory though... OSGi (http://www.osgi.org/
the core of Eclipse) is essentially a large central Map of service
implementations registered under the key of their service name.

Service provider bundles register an implementation instance into the
Map keyed by service name, service consumers then discover the service
implementation (still without knowing the implementation) via the
service name - the name is often the fully qualified string name of the
interface/abstract class.

I was trying to get a handle on several things:

* How many places is this pattern used? I thought it was very common
- but how common?
* What are the variations on the theme? For example some
implementations register in a Map, others create impl class names by
sticking together known attributes, others use system properties etc.
What others are there?
* What is the best way of doing this? Would things be more simple if
everyone were to adopt a single approach?

Your thoughts....

- chris
 
C

Chris Senior

Ed said:
I'm sure I'm missing the point, but isn't this just the factory method
pattern?

Service provider = factory method pattern + class.forName()

www.EdmundKirwan.com - Home of The Fractal Class Composition.

Slightly off my original topic this....

I was reading through your web page on fractal class composition -
which is really cool, these are a lot of ideas I have tried to stick to
in my programming. I can certainly concur that inter-namespace
dependencies are the dry rot of software projects.

I agree whole heartedly with your concept "maximise the number of
classes with name-space-private access". Programmers tend to make all
classes public - but only intend certain ones to be used by other
(future) programmers. The "public public" ones are the ones with all
the API documentation, the "private public" ones are the ones with no
documentation or doc comments saying "do not use/change this class"...
what they lack is a mechanism to effectively control the access.

In http://www.edmundkirwan.com/servlet/fractal/frac-page56.html you
propose the "multi-name-space access" solution which you say does not
exist in modern OO langauges. I think you would be very interested in
the Eclipse approaches and the OSGi bundle dependency model used to
enforce it.

Prior to Eclipse adopting OSGi package interdependency was achieved by
"gentlemens agreement" - i.e.
http://www.eclipse.org/articles/Article-API
use/eclipse-api-usage-rules.html.

With OSGi component (bundle) dependencies get more formal ... a bundle
is a related "chunk" of code packaged as a single JAR file with a
special manifest. The manifest defines which packages within the bundle
are public (exposed to other bundles which depend on the declaring
bundle). Only those public classes in "public packages" are exposed to
other bundles. So public classes in separate packages within the bundle
can all see each other, but normally only one or two packages are
chosen to be the public API of the bundle. You can also declare that
packages only be exposed to certain other downstream bundles.

Whilst this is not "language level" it does support the extra level of
access control that you describe. Generally speaking I have found OSGi
to be an extremely useful tool in introducing and controlling
modularity and inter-dependency in large projects - curing the dry rot
(or at least stopping it spreading).

- chris
 
E

Ed Kirwan

Chris said:
In http://www.edmundkirwan.com/servlet/fractal/frac-page56.html you
propose the "multi-name-space access" solution which you say does not
exist in modern OO langauges. I think you would be very interested in
the Eclipse approaches and the OSGi bundle dependency model used to
enforce it.

Chris, that OSGi stuff is indeed quite fascinating. I've just read a
whopper of a whitepaper on the OSGi homepage: they've an entire stack of
technology for managing their, "Bundles," of software.

Will investigate further and thanks for the pointer.

(Oops, I mean, "Reference.")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top