okay, back to the factory
Status: Alpha
Brought to you by:
madduck
|
From: stephan b. <st...@s1...> - 2005-06-23 17:00:23
|
Hi, martin!!!
i'm working over the internal factory layer for s11n, and here's what i
would like to try out:
Let's hash out a basic factory *interface*. Internally in s11n, we will
use that interface. For example, when an s11n'd class registers with
the s11n factory layer, it would do the equivalent of:
s11n::cl::register_factory<MyInterface>("MyType", my_factory );
Internally, that would use an instance of this base interface. The
instance of course can do what it likes. Essentially, this is a Policy
behaviour, but it would in theory be runtime-defined, and i definitely
don't want the client having to know if they're using cllite or libfac,
for example. The fact that cllite is a "public" part of the s11n 1.0
API has come back to haunt me when it comes around to porting my
1.0-based clients on to 1.1 (which doesn't have cllite, but my clients
use it for their own purposes).
Basically what i think we need is an interface for the following
features:
a) register factory functions (or functors) in the form of a key-value
pair. Experience suggests that the key type is a String 99% of the
time, but that other types are occasionally useful. i honestly don't
have a strong preference for whether the core interface hard-codes the
key as std::string or templatizes it.
b) query factory to see if it has a class, without having to instantiate
it. This is useful in allowing the factory manager to search for DLLs
in advance. e.g.
bool gotit = factory_mgr::instance<MyInterface>().has_class("Foo");
The factory impl could potentially check for DLLs at this point, but to
correctly do so the factory has to have a non-const has_class() or
mutable internal data and a quasi-bogus const qualifier on has_class().
Whether or not we can truly enforce const behaviour on a factory is
another point entirely - at this point i don't believe it is really
possible, due to the inherently backwards nature of the registration
process, in which any thread may inject classes into the factory at any
given time.
c) A create()-like function. Whether or not the base interface specifies
exception guarantees here needs to be defined, as would a base
exception type. cllite, for example, normally returns NULL on error but
a toggle can be set to enable a throw cl_exception on a failed
create(), which allows it to report more specific errors, like
informative messages direct from dlerror().
d) A destroy()-like function, BUT i do not believe it is realistic to
require the user to call it. We can't, for most practical reasons,
because client software which creates objects is often several layers
removed from the factory, and has no way of getting to it.
Of those features, i think (a) and (c) are the only critical ones. The
has_class() idea is theoretically useful, and not critical to the
interface. (d) is a point who's importance i know you and i disagree
on, but i think you agree with me that we can't expect a client to have
a direct connection with the factory layer (i also agree with you that
destroy() is technically the right thing to do, but i think the
dependency problem clearly outweighs that).
The exact registration techniques/macros used is irrelevant for our
purposes. i'm only looking for an interface (or interfaces) which i can
publish in the s11n factory layer, without tying s11n clients to a
specific underlying factory layer. They should be able to, for example,
pop in their own implementation of our basic interface. Whether or not
this requires compile-time knowledge (i.e., is templatized) or can
truly be done at runtime, i'm still uncertain. Both have their
potential problems.
Last summer i worked briefly on such an interface, but gave up on it for
reasons i don't remember. The goal at the time was the same, however -
hiding from s11n the detail of which underlying factory manager it
uses.
Before i make a concrete proposal, is there anything specific i haven't
addressed, or where you feel i'm off base? i'd especially like to hear
your ideas on exceptions, when to throw them, exact scope of the
interface (for example, DLL lookups don't belong in it).
i'm going to spend part of tonight going over libfac, and refreshing my
memory of how you handled non-default ctors. That is a feature i would
eventually like to get in to s11n.
--
----- st...@s1... http://s11n.net
"...pleasure is a grace and is not obedient to the commands
of the will." -- Alan W. Watts
|