 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mike Monagle Guest
|
Posted: Sat Aug 14, 2004 3:06 am Post subject: Name-Based Object Creation |
|
|
I'm working on the client side of a distributed application that uses what I
call an XML over quasi-HTTP protocol. The client and server are connected
with a single persistent socket and exchange messages that look something
like this:
Content-type: P51Mustang
Content-length: 147
<?xml version="1.0"?>
<P51Mustang>
<Pilot>SGT Yeager</Pilot>
<Fuel units="gallons">600</Fuel>
<Guns caliber="50">6</Guns>
</P51Mustang>
After parsing the HTTP-like headers, the problem boils down to how to
deserialize this object give its name in the Content-type string. In other
words, how to go about creating an object of type class P51Mustang given
that the message is a "P51Mustang" message.
I'm considering a number of ways to do this and wondered if anyone else has
any different ideas. So far I've come up with:
1. A BIG if-else if-else statement that considers all possible object types:
// maintenance nightmare, I know.
if(contenttype == "P51Mustang")
p = new P51Mustang;
2. A "map" object, using STL or another library, that maps a string to a
function pointer to create the appropriate type of object. The map object
must be populated (hard-coded) to map the names of the various types of
objects to the appropriate function pointers before being used. Another
maintenance nightmare, much like the BIG if-else if- else statement above.
Use would go something like this:
typedef IncomingMessage* (*fpCreateMsg)( );
void *fpv = 0;
if(map.Lookup(contenttype, fpv))
{
// fpv now points to a function will create the appropriate object
type.
fpCreateMsg fp = (fpCreateMsg)fpv; // now we have a function pointer
that can be invoked.
IncomingMessage *pMessage = (*fp)( );
// We now have an uninitialized P51Mustang object, although the
calling object only knows that it's an IncomingMessage.
// pMessage can be use to initialize the object with the XML here.
// Getting the right thing to happen next is a double-dispatch
problem, but I don't want to get into that here.
}
3. Use a DLL (running on Windows) to find the appropriate function based on
contenttype. Easier maintenance, but might be slower than above methods:
void *fpv = GetProcAddress(hModule, contenttype);
if(fpv)
{
// we can proceed as in 2. above if Lookup succeeds.
4. A combination of 2. and 3. above where the function pointer is retrieved
from the DLL if it is not found in the map and then stored in the map for
later (and faster) use. Easier maintenance than 1. and 2. above, and
probably pretty fast.
Any other ideas? I realize that there are many middleware solutions as well
as commercially available and shareware libraries that deal with such object
deserializations over a network, but unfortunately I am not able to use any
of these do to management decisions.
Thanks!
Mike
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Sat Aug 14, 2004 1:34 pm Post subject: Re: Name-Based Object Creation |
|
|
Mike Monagle <mikemonagle (AT) nospam (DOT) comcast.net> wrote:
| Quote: | I'm working on the client side of a distributed application that uses what I
call an XML over quasi-HTTP protocol. The client and server are connected
with a single persistent socket and exchange messages that look something
like this:
Content-type: P51Mustang
Content-length: 147
?xml version="1.0"?
P51Mustang
Pilot>SGT Yeager</Pilot
Fuel units="gallons">600</Fuel
Guns caliber="50">6
/P51Mustang
After parsing the HTTP-like headers, the problem boils down to how to
deserialize this object give its name in the Content-type string. In other
words, how to go about creating an object of type class P51Mustang given
that the message is a "P51Mustang" message.
I'm considering a number of ways to do this and wondered if anyone else has
any different ideas. So far I've come up with:
1. A BIG if-else if-else statement that considers all possible object types:
// maintenance nightmare, I know.
if(contenttype == "P51Mustang")
p = new P51Mustang;
|
If the number of types relatively low and stable there is nothing wrong with this approach.
| Quote: | 2. A "map" object, using STL or another library, that maps a string to a
function pointer to create the appropriate type of object. The map object
must be populated (hard-coded) to map the names of the various types of
objects to the appropriate function pointers before being used. Another
maintenance nightmare, much like the BIG if-else if- else statement above.
|
There are a number of ways to automate populating the map. If portabilty is not an issue for you might go for some really neat compiler-dependable solutions, like the one with building at link time a list of pointers to functions that MSVC uses for invoking static object constructors: http://msdn.microsoft.com/msdnmag/issues/01/01/hood/default.aspx (The Dark Underbelly of Constructors section)
| Quote: | Use would go something like this:
typedef IncomingMessage* (*fpCreateMsg)( );
void *fpv = 0;
if(map.Lookup(contenttype, fpv))
{
// fpv now points to a function will create the appropriate object
type.
fpCreateMsg fp = (fpCreateMsg)fpv; // now we have a function pointer
that can be invoked.
IncomingMessage *pMessage = (*fp)( );
// We now have an uninitialized P51Mustang object, although the
calling object only knows that it's an IncomingMessage.
// pMessage can be use to initialize the object with the XML here.
// Getting the right thing to happen next is a double-dispatch
problem, but I don't want to get into that here.
}
|
I see real problem here is two-phase creation - first you create an object and then you need to initialize it without knowing its dynamic type.
I would suggest passing additional data to the factory function, so that it has enough information to create and initialize the object. The additional data here should most likely be the object's XML section, so that the object's constuctor pulls the data out of it to initialize itself.
You might want to go futher abstracting out XML using the GoF builder pattern. In this case you would feed factory function with not XML, rather with an interface that the object will use to pull the data from.
The bottom line is use single-phase creation, when objects are created already initialized.
| Quote: | 3. Use a DLL (running on Windows) to find the appropriate function based on
contenttype. Easier maintenance, but might be slower than above methods:
void *fpv = GetProcAddress(hModule, contenttype);
if(fpv)
{
// we can proceed as in 2. above if Lookup succeeds.
|
That only solves problem of finding appropriate factory function.
--
Maxim Yegorushkin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Aug 16, 2004 7:53 pm Post subject: Re: Name-Based Object Creation |
|
|
"Mike Monagle" <mikemonagle (AT) nospam (DOT) comcast.net> wrote
| Quote: | I'm working on the client side of a distributed application that uses
what I call an XML over quasi-HTTP protocol. The client and server are
connected with a single persistent socket and exchange messages that
look something like this:
Content-type: P51Mustang
Content-length: 147
?xml version="1.0"?
P51Mustang
Pilot>SGT Yeager</Pilot
Fuel units="gallons">600</Fuel
Guns caliber="50">6</Guns
/P51Mustang
After parsing the HTTP-like headers, the problem boils down to how to
deserialize this object give its name in the Content-type string. In
other words, how to go about creating an object of type class
P51Mustang given that the message is a "P51Mustang" message.
I'm considering a number of ways to do this and wondered if anyone else has
any different ideas. So far I've come up with:
1. A BIG if-else if-else statement that considers all possible object types:
// maintenance nightmare, I know.
if(contenttype == "P51Mustang")
p = new P51Mustang;
|
An impossible maintenance nightmare in the general case you seem to be
considering.
| Quote: | 2. A "map" object, using STL or another library, that maps a string to
a function pointer to create the appropriate type of object. The map
object must be populated (hard-coded) to map the names of the various
types of objects to the appropriate function pointers before being
used.
|
Why does the population have to be hard-coded. I generally use a map
populated by constructors to static objects for this. That is:
- The map is string->Builder const*, where Builder is an abstract base
class with a virtual function to create an object. Also, the map is
a classic singleton.
- Obviously, for each type of object, I've got to write the function
to construct it; in this case, I have to define the derived class,
implement the builder function and the constructor, and define an
instance of the builder class at namespace scope. This is done in
the file where I define the rest of the class functions, so it isn't
too much of a maintenance problem.
- The base class Builder constructor takes the name of the class, and
inserts the necessary record to access it into the map.
I link in the objects for the different objects, and the map gets
constructed automatically.
If I wanted to get fancier, when I didn't find a pointer to a Builder in
the map, I could search for it in a DLL or a shared library, and link
that in. (Linking the dynamic library in should cause the constructors
of static objects to be called, causing any builders in the library to
register themselves in the map.)
I've used this technique fairly often, and never had any problems with
it.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Shorn Mo Guest
|
Posted: Tue Aug 17, 2004 10:00 am Post subject: Re: Name-Based Object Creation |
|
|
[13 Aug 2004 23:06:38 -0400]from "Mike Monagle"
<mikemonagle (AT) nospam (DOT) comcast.net>'s Terminal:
| Quote: | ===
===>After parsing the HTTP-like headers, the problem boils down to how to
===>deserialize this object give its name in the Content-type string. In other
===>words, how to go about creating an object of type class P51Mustang given
===>that the message is a "P51Mustang" message.
|
plz see also "object factory pattern" from MODERN C++ DESIGN by Andrei
Alexandrescu.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|