Skip to main content

Dynamic Client Subtyping

Posted by cajo on December 7, 2006 at 8:44 PM PST

Given the enthusiastic feedback to the Take That .NET! blog entry; I thought I might expound a bit upon a small, but highly important bit, at the end of the example.

Oftentimes service objects implement a large, rich interface. Other times service objects implement several interfaces, grouping their functionality into distinct logical concerns. Quite often, a client needs only to use a small portion of an interface; or perhaps some methods from a few of the logical grouping interfaces, to satisfy its own needs.

The ability of a client to define its own interface, from ones defined by the service object, is known as subtyping in Java. (in contrast to subclassing) However, unlike conventional Java subtyping; Dynamic Client Subtyping means creating an entirely different interface. What makes this subtyping dynamic, is that it works with the original, unmodified service object.

This can be a very potent technique, for client-side complexity management.

Doubtlessly, an example would help.

Assume we had a service object representing an auto manufacturer, and it implements several interfaces in its own package; say auto.perspectives:

<pre>
public interface Physical {
   Location currentLocation();
   Terms shipTo(Location location);
   Petrol petrolRequirement();
   int kilogrammes();
   int litresPer100kilometres();
}
public interface Visual {
   Colour colour();
   Image image();
}
public interface Financial {
   int costEuro();
   Set&lt;Terms&gt; terms(int downpaymentEuro);
}
public interface Advert {
   String description();
   int modelYear();
}
...

Then assume it had an implementation class in some other package; say auto.products:

<pre>
public class AutoX implements Physical, Visual, Financial, Advert... {
   ...
}

Now let's assume a client, perhaps an auto broker, needed only a small portion of this. It could define its own interface, i.e. a subtype, in its own package; say broker.info:

<pre>
public interface Commission {
   Location currentLocation();
   Terms shipTo(Location location);
   Colour colour();
   int costEuro();
   Image image();
   String description();
}

An extremely useful feature of the cajo project is that it allows ordinary objects to be used between Java Virtual Machines, exactly as they are used locally; without modification.

Assume we have an auto reference:

<pre>
Object auto;

Suppose when the auto object is local to the client JVM:

<pre>
auto = AutoFactory.selectAuto(Details...);

If the auto object is in a remote JVM:

<pre>
auto = <a href=https://cajo.dev.java.net/docs/gnu/cajo/invoke/Remote.html#getItem(java.lang.String)>Remote.getItem</a>("//somehost:1198/someAuto");

In either case, the auto object reference is customised thus:

<pre>
Commission commission = (Commission)<a href=https://cajo.dev.java.net/docs/gnu/cajo/utils/extra/TransparentItemProxy.html>TransparentItemProxy</a>.
   <a href=https://cajo.dev.java.net/docs/gnu/cajo/utils/extra/TransparentItemProxy.html#getItem(java.lang.Object,%20java.lang.Class[])>getItem</a>(auto, new Class[] { Commission.class });

Now it will work exactly as you would expect:

<pre>
System.out.println(commission.description());

Enjoy,

John

Related Topics >>