C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Name-Based Object Creation

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Mike Monagle
Guest





PostPosted: Sat Aug 14, 2004 3:06 am    Post subject: Name-Based Object Creation Reply with 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;
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





PostPosted: Sat Aug 14, 2004 1:34 pm    Post subject: Re: Name-Based Object Creation Reply with quote



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





PostPosted: Mon Aug 16, 2004 7:53 pm    Post subject: Re: Name-Based Object Creation Reply with quote



"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





PostPosted: Tue Aug 17, 2004 10:00 am    Post subject: Re: Name-Based Object Creation Reply with quote

[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.

Quote:
===


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.