From: Eric Armstrong <eric.armstrong@eng.sun.com>
I'm seeing two requirements for either dynamic or
configurable extensibility. (Configurable extensibility
is sufficient, but dynamic extensibility seems to fall
out as a consequence.)
Definitions:
Dynamic Extensibility
The ability to change an app "on the the
fly", while it is execution.
Configurable Extensibility
The ability to configure the app so that new
features and functions are added the next
time it starts.
The two requirements I see are:
a) Class Replacement
b) Dynamic Messaging
Class Replacement
--------------------
First, it goes without saying that APIs are defined in
terms of interfaces. So, rather than defining parameters
using classes, they are defined using interfaces. That lets
subclasses and different implementations take the place
of the original object.
However, at some point, it is necessary to create an
object. What has to happen at that point is that the
object is obtained from a factory. The factory, in turn,
*is configured with the class to use*. In essence, the
factory is configured with a table of "expected class /
actual class" pairs. When the factory is asked for an
instance of the expected class, it returns an instance of
the actual class -- which is either the expected class or
a subclass of it.
That architecture lets you take advantage of existing
classes when you define an extension. Instead of having
to satisfy an interface -- and therefore implement every
behavior, you can subclass the existing class, overriding
only those behaviors you want to change.
Dynamic Messaging
--------------------
Class replacement is fine for changing behaviors, but what
about when you add new functions? As long as those
functions are *only* invoked by methods in the class and
by objects it creates, class replacement is still sufficient.
But how often does that restriction hold?
When you extend an existing class with additional functions,
you need to extend its interface, as well. But the static
interfaces satisfied by the factory's actual class, are the
*expected class* interfaces. As a result, the additional
functions are "invisible" within the context in which the
"expected class" instance was obtained.
The solution I see is to return to "Smalltalkish" messaging.
In SmallTalk, a "message" was literally that -- a message
that included the name of the function to invoke, along with
any arguments.
In Java, "SmallTalk" messaging can be achieved using
"reflection" (it's all done with mirrors). The reflection APIs
give the app a list of methods implemented by a class. That
means:
a) All methods other than "msg()" would be protected.
(They could not be called by other classes, but would
be overridable in sub classes).
b) "msg()" would be the only public method.
c) The first argument to msg() would be a String specifying
the method to invoke. The second argument would be a
HashList of type-name/value pairs.
(Type-name is needed, because the value might be
a subclass of the type specified in the method signature.)
With this structure, when expected class A is replaced by A',
and expected class B is replaced by B', A' can invoke the
additional methods in A' that were never part of A.
That is the way I see things working at the moment, at least.
Does anyone see any other ways to solve the problem?
------------------------------------------------------------------------
DON'T HATE YOUR RATE!
Get a NextCard Visa, in 30 seconds! Get rates as low as
0.0% Intro or 9.9% Fixed APR and no hidden fees.
Apply NOW!
http://click.egroups.com/1/2120/3/_/444287/_/953342154/
------------------------------------------------------------------------
Community email addresses:
Post message: unrev-II@onelist.com
Subscribe: unrev-II-subscribe@onelist.com
Unsubscribe: unrev-II-unsubscribe@onelist.com
List owner: unrev-II-owner@onelist.com
Shortcut URL to this page:
http://www.onelist.com/community/unrev-II
This archive was generated by hypermail 2b29 : Fri Mar 17 2000 - 17:23:01 PST