Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


conditional object creation


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 //Lumia   Members   -  Reputation: 516

Like
0Likes
Like

Posted 16 August 2013 - 06:56 AM

Hi there,

 

i'm currently trying to write a kind of XML-Parser for my gui framework and i'm struggling with the object creation.

 

So a possible XML-File could look like this:

<Window id="Notification" title="Notification" message="An Error occured while...">
   <button id="Button_try_again" caption="Try again" />
   <button id="Button_cancel" caption="cancel" />
</Window> 

For iterate through all tags i'm using StaX. The name of each tag is accessible by calling the getLocalName()-method.

Furthermore there is an corresponding class for each valid tag (just like window and button in the example above) and i need to get an object of one of them.

 

So here is a little snippet of what came to my mind to achieve this:

String tagname = Staxparser.getLocalName();

if(tagname.equalsIgnoreCase("Window")) {
     // instantiate window class
} else if(tagname.equalsIgnoreCase("Button")) {
     // instantiate button class
}

Well, this looks pretty much nasty and should not be done like this.

 

So here is the actual question:

Is there a way to not use a whole bunch of if-else-statements to figure out what class needs to be instantiated?

Is there a design pattern or anything else that is able to simplify the problem?

 

Thanks in advance.

 



Sponsor:

#2 Nik02   Crossbones+   -  Reputation: 2875

Like
2Likes
Like

Posted 16 August 2013 - 08:19 AM

A common solution for this type of problem is to use a dictionary structure as a "catalog" or a "type repository". The keys for such a dictionary would be the type names that can be instantiated, and the values would be simple structures that could contain, among other things, a pointer to the constructor of the given type.

 

At your convenience (for example, app startup), you would add the instantiable types to your catalog dictionary; later, when you enumerate through the xml, you would simply look up each element from the catalog and instantiate them using the info in the catalog values.

 

The catalogs could be constructed by inspecting actual classes and/or modules using reflection at runtime, as opposed to hardcoding the object data to the catalog in your code. This way, your application core doesn't have to care about which actual classes are created in the end (but be sure to provide common interfaces to all the objects so that you can actually use them in the core application somehow).

 

Even though you use Java, it may be worthwhile to check out Microsoft's MEF architecture for inspiration. It is not as difficult to implement by yourself as one would think.


Edited by Nik02, 16 August 2013 - 08:22 AM.

Niko Suni


#3 NightCreature83   Crossbones+   -  Reputation: 2932

Like
0Likes
Like

Posted 16 August 2013 - 09:55 AM

.Net and Java basically already grant you the abilities to do this in their frame works and the thing you are looking for is called reflection. Effectively this allows you to create objects that are defined in your program by only knowing their names, without having to write any special code to track what can be created as described by Nik02..

 

Reflection in both languages are advanced features and you might need to experiment a little bit with what you have to specify in the names.

 

In C++ you can actually construct this list at compile time through some macro tricks and function pointers, it is not a nice solution to look at but this achieves what nik02 describes:

http://code.google.com/p/dxengine/source/browse/trunk/src/ClassRegistration.h

http://code.google.com/p/dxengine/source/browse/trunk/src/Misc/ObjectFactory.h

and these two macros:

//This goes in the header of the class
#define REGISTER_CLASS(CLASS) static const ClassRegistrar s_registration##CLASS;
//this goes in the cpp of that class
#define DL_REGISTER(CLASS) const ClassRegistrar CLASS::s_registration##CLASS(&CLASS::m_rttiInfo, #CLASS,&ObjectFactory::objectCreationFunctionTemplate<CLASS>); 

The only reason I ever wrote this code was because I wanted to know how this could work in C++, there are other ways of achieving this in nicer ways probably.


Edited by NightCreature83, 16 August 2013 - 10:02 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#4 nonoptimalrobot   Members   -  Reputation: 416

Like
0Likes
Like

Posted 16 August 2013 - 09:55 AM

[ edit ]...what NightCreature83 said.

 

This doesn't change things in a absolute sense.  Someplace, under-the-hood or not, there will be a loop, if-else-if cascade or switch statement that ends up instantiating types from strings.  The only difference is where this code exists and who wrote it (you, the compiler, an API or a synergistic combination).


Edited by nonoptimalrobot, 16 August 2013 - 10:03 AM.


#5 Juliean   GDNet+   -  Reputation: 2692

Like
0Likes
Like

Posted 16 August 2013 - 11:57 AM


This doesn't change things in a absolute sense. Someplace, under-the-hood or not, there will be a loop, if-else-if cascade or switch statement that ends up instantiating types from strings. The only difference is where this code exists and who wrote it (you, the compiler, an API or a synergistic combination).

 

At some point or another, there has got to be some controll structure to make things work. Such structures are the first main feature that differ programming languages from descriptive languages like HTMl, etc... . You can't just expect to get rid of all if-else by some kind of black magic, and why would you want to in the first place? What the OP wants makes sense, he wants to get rid of a potential hundreds of nestes if-else's to read all possible types of gui elements in, therefore also making things more modular.

 

To be all honsest, I personally would just create a ILoadRoutine-interface, and derive for each widget(type?) an implementation from it. Then store those by string in an array or such structure, look them up by the name of the tag, and call a "Create(...)"-method. In this method, you handle the instantiation of the class, and all proper setup. Thats how I'd do it, would even work without any if/else, but don't know if this is a commonly seen good method or not...



#6 King Mir   Members   -  Reputation: 2031

Like
0Likes
Like

Posted 17 August 2013 - 05:00 PM

If the only difference between instantiate window class and instantiate button class is the class name, then reflection is the way to go. Something like:
Class.forName(tagname).newInstance()

Be sure to sanitize and verify the correctness of the input.

#7 dmatter   Crossbones+   -  Reputation: 3254

Like
2Likes
Like

Posted 17 August 2013 - 05:50 PM

Marshalling XML to and from Java objects is a solved (and not very interesting) problem, Java actually has built in support for XML-binding called JAXB which will just take care of it all for you. There are similar other 3rd party libraries that essentially do the same thing too.

#8 //Lumia   Members   -  Reputation: 516

Like
0Likes
Like

Posted 19 August 2013 - 09:59 AM

Hi there,

 

i'm sorry for not replying until now.

So there are 3 Options i can choose from:

  • a catalog system to map the elements used in the xml to its corresponding entities
  • reflection
  • existing xml marshalling frameworks like JAXB

 

So i tried out the reflection approach during the weekend and at some point i realized that i am not able to generalize all possible entities due to the fact that a button maybe has different attributes than a label.

 

A catalog system seems to be a much easier way to handle this. But in my opinion there is another problem:

For every entry in the catalog system, representing a special widget, there must be another dictionary that contains every possible attribut for that special widget. This can grow a lot since more and more widgets are implemented.

 

In the end i will try out JAXB. As far as i read through some examples its mostly based on annotations and should be working fine.

So thanks to all of you for your advices, it helped me a lot.



#9 dmatter   Crossbones+   -  Reputation: 3254

Like
0Likes
Like

Posted 19 August 2013 - 11:14 AM

In the end i will try out JAXB. As far as i read through some examples its mostly based on annotations and should be working fine.
So thanks to all of you for your advices, it helped me a lot.

It's been a while but my memory of it is that most (all?) of the annotations are actually optional and, if not used, JAXB will employ "convention over configuration" and just directly use the names of methods/classes/etc as long as you stick to standard java-bean naming conventions (i,.e. setCaption and getCaption etc).



#10 JohnnyCode   Members   -  Reputation: 261

Like
0Likes
Like

Posted 19 August 2013 - 06:00 PM

 

For every entry in the catalog system, representing a special widget, there must be another dictionary that contains every possible attribut for that special widget.

You are making a xml file with many different objects alive in your system side. The fact that you instantiate proper objects on those types, will not somehow miracly get you rid off managing them and aproaching them the way their datatype demands (a label is not window so much). You should rethink deeply not only instantiating them conditianaly, but runinng them conditionaly. The aproach I use is that I use inharitance and that I have an all shared class, and inside that most basic class I have an int that detects their highest datatype- the type. This gives me assurance that anywhere in my code ever I will be able to do type conditional  aproaches to them. The nummber in the most basic class is simply set in constructor of any class that inherits the all shared class.



#11 NightCreature83   Crossbones+   -  Reputation: 2932

Like
0Likes
Like

Posted 21 August 2013 - 09:12 AM

Hi there,

 

i'm sorry for not replying until now.

So there are 3 Options i can choose from:

  • a catalog system to map the elements used in the xml to its corresponding entities
  • reflection
  • existing xml marshalling frameworks like JAXB

 

So i tried out the reflection approach during the weekend and at some point i realized that i am not able to generalize all possible entities due to the fact that a button maybe has different attributes than a label.

 

A catalog system seems to be a much easier way to handle this. But in my opinion there is another problem:

For every entry in the catalog system, representing a special widget, there must be another dictionary that contains every possible attribut for that special widget. This can grow a lot since more and more widgets are implemented.

 

In the end i will try out JAXB. As far as i read through some examples its mostly based on annotations and should be working fine.

So thanks to all of you for your advices, it helped me a lot.

JAXB is probably built on top of reflection anyway, all of these solutions are mapped under the reflection name as reflection code stands for code that writes itself.

 

You can still use relfection in that case except you need to add a initialise/deserialise function on the button that accepts the xml node it is created from. This function then determines which fields of the instance to setup so if the node only has one attribute field it will initialise the other one to a default value. This in response is called data driven development and there are a million ways to solve that as well XML is only one solution.
 


Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#12 dmatter   Crossbones+   -  Reputation: 3254

Like
0Likes
Like

Posted 21 August 2013 - 09:39 AM

JAXB is probably built on top of reflection anyway

Yes it is. It just introspects the typenames, method signatures and public variables along with any JAXB-specific annotations to map the XML tags and attributes to/from method and variables on the object. It's pretty much just what you do if you were rolling your own but comes with extra bells and whistles should you need them.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS