Jump to content

  • Log In with Google      Sign In   
  • Create Account


Is this OO design or Evil?


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
14 replies to this topic

#1 Gyzmo   Members   -  Reputation: 162

Like
Likes
Like

Posted 31 December 2000 - 10:55 AM

Well I was thinking about making a Singleton object in my program that contains in a hashmap (or other associative container) where the key is a string (or numerical ID) and the value is an object that is both a factory that creates the object specified by the key (for example "Thread", "Goblin", "Socket" or any other object used by the program) and a container that holds all the objects it contains. Since it''s a Singleton and thus globally accessible, every object in the program can ''request'' access to any object held in this object. It would be useful for DLL-plugins, which can access any data created with this object. Now, what I was wondering was wether it was ugly oo design to give global access to every game-object? Or rather, is this entire idea bad oo design? Gyzmo ======================= Meddle not in the affairs of dragons for you are crunchy and go well with toast.

Sponsor:

#2 fugue88   Members   -  Reputation: 122

Like
Likes
Like

Posted 31 December 2000 - 04:05 PM

---- BEGIN QUOTE ----
Now, what I was wondering was wether it was ugly oo design to give global access to every game-object?
----- END QUOTE -----

Yes and no. I believe that some things, like a game-world, are just better when implemented as global variables. However, writing functions that manipulate these variables directly can lead to a design disaster.

For example, if you write a routine to perform transformation on objects, pass the global variables as parameters instead of hard-coding them in. You''ll be able to use this function on other model data later on.

#3 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 01 January 2001 - 05:50 AM

Will your factory/container be able to handle multithreaded access? That might be a problem for a global access factory. You''ll have to be careful of that case. Other than that, i dont think there is anything wrong with a centralized global entity factory. I use several global factories as well to create my entites and other game objects such as packets, etc.. Though i would suggest implementing a form of refrence counting for the entities, it will make object management and deletion easier in the future.

Good Luck

-ddn

#4 Gyzmo   Members   -  Reputation: 162

Like
Likes
Like

Posted 01 January 2001 - 06:58 AM

I''m still considering wether to make it thread-safe, I might though and make the functions that create/modify lock access to all functions (both reading and writing). And I will implement reference counting. I was thinking of creating a DLL/SO-template that creates a pointer to an object of the common base-type(which at least has functions for retrieving it''s type-ID and creating itself) which are stored in my container factory so new classes can be added dynamically (and without recompiling).

Also what I might do is instead of creating an actual factory is that each type-ID has a handle to the DLL/SO and let a function contained in the DLL create the objects. That wouldn''t require separate factory-objects inside the container factory...

Gyzmo
=======================
Meddle not in the affairs of dragons for you are crunchy and go well with toast.

#5 Shannon Barber   Moderators   -  Reputation: 1361

Like
Likes
Like

Posted 09 January 2001 - 01:39 PM

''Megafactory''
''Omnifactory''
''Borgactory''?
ah here we go, Monolith

May as well do reference counting & garbage collection.
And thread-safe seems the way to go, you wouldn''t need such a monolith in a single thread app would you?

Magmai Kai Holmlor
- The disgruntled & disillusioned


#6 Gyzmo   Members   -  Reputation: 162

Like
Likes
Like

Posted 10 January 2001 - 06:56 AM

Well the reason I just might implement thread safety is because it is slow. Since I''ll use STL as container for all data it IS thread safe in a per-object manner (i.e. it is thread safe as long as I don''t access the SAME container at the same time). I have some ideas for a perfectly thread safe queue without using any synchronisation. Using this queue I could make a seperate container-access-thread which would handle all accesses to a container(in a request based manner, i.e. a request is made to the thread (added to queue) and the container-access-thread handles each request sequentially, both input and output).

As for a name, how about Überfactory

Gyzmo
=======================
Meddle not in the affairs of dragons for you are crunchy and go well with toast.

#7 Shannon Barber   Moderators   -  Reputation: 1361

Like
Likes
Like

Posted 15 January 2001 - 03:20 PM

quote:

As for a name, how about Überfactory


LMAO

crictical sections are not all that slow, as least not realy so bad as mutex etc...

My understanding was that STL contained no syncronization whatsoever (it would a serious portability issue if it did.)
What if a read was placed inline, right after a write - I think it fail if the object requested was just added to the queue - and it could take up to 10ms before it would be available.

If you make it thread safe (maybe add a compiler directive to turn it off or on?), you should probably use cs''s in the data access routines...

#8 SHilbert   Members   -  Reputation: 647

Like
Likes
Like

Posted 28 January 2001 - 03:53 AM

Cool idea, Gyzmo. It sounds elegant and mod-able. In fact, the way that things are named could make networking easy... And yes, I think it's nice OO design and not evil


Visit my site!

Edited by - SHilbert on January 28, 2001 10:58:44 AM

#9 archetype   Members   -  Reputation: 122

Like
Likes
Like

Posted 28 January 2001 - 04:24 AM

Your design seems to be somewhat similar to mine.
Let me start off by saying that you might want to reconsider
making your factories global. There should always be a well defined place within the application where objects are created.
In my game, I have a creator agent, which receives requests, from objects to create things for them. The agent is the only object which has access to the factories. This insulates the game from creation methods, and makes it more flexible. Furthermore you can add creation conditions and rules later on, without recompiling, be replacing the agent with a derived agent.

Let me point you in the direction of a great CUJ(C/C++ Users Journal) article that helped me quite a bit. The November 2000 issue, contained an article called ''Better Object Factories'' by Early Ehlinger, which seems to cover what you are talking about. If you can''t get your hands on the issue, you can always downlaod the source from www.cuj.com and study it.

Hope this helps.



type entity
[
dynamic cmd_interface:
cmd c,
object o=0
[
if:c
call_remote[c,o];
]void;
]

#10 Gyzmo   Members   -  Reputation: 162

Like
Likes
Like

Posted 17 February 2001 - 01:22 AM

quote:
Original post by archetype

Your design seems to be somewhat similar to mine.
Let me start off by saying that you might want to reconsider
making your factories global. There should always be a well defined place within the application where objects are created.
In my game, I have a creator agent, which receives requests, from objects to create things for them. The agent is the only object which has access to the factories.


Well, that was sort of the idea, i.e. you call:
  
MyObject = UberFactory::GetInstance()->CreateNewObject("MyObject");


well, at least something like that, the thing will first check if there is a factory contained in the UberFactory which can create a "MyObject" and than let the factory do the rest, and wheteher factory is something simple, or something derived from the basic Factory is all up to the one who creates the factory.

Gyzmo
=======================


#11 Altair   Members   -  Reputation: 122

Like
Likes
Like

Posted 20 February 2001 - 07:18 AM

Hi Gyzmo,

It''s better to use abstract factory instead of global factory. Just instantiate desired factory in the beginning of the program and pass that to rest of the application.

Cheers, Altair


"Only two things are infinite, the universe and human stupidity, and I''m not sure about the former." - Albert Einstein


#12 Gyzmo   Members   -  Reputation: 162

Like
Likes
Like

Posted 22 February 2001 - 10:55 AM

As I said, the type of factory is completely hidden by an abstraction-layer of the UberFactory/Monolith/whatever. You could even have ''sub-uberfactories'' inside it, I don''t know why, but you could.

I should actually write this baby, but well, that''s my problem, full of ideas and too lazy to implement them.

(YES I KNOW, my sig is misspelled, misgrammered and missomethingeelsed)

Gyzmo
=======================


#13 Shannon Barber   Moderators   -  Reputation: 1361

Like
Likes
Like

Posted 22 February 2001 - 07:13 PM

This actually sounds alot like COM''s object creation method. I''ve been playing with COM lately at work (I''m designing a HAL for DAQ devices) and it''s pretty cool. It''s not exactly what you''re doing, but related. (COM doesn''t provide a container and serialize access to object instances like your Uberfactory.)

It''s fairly involved, and a major pita to setup the first time, but once you figure out how to register the .dll and write the neccessary functions it gets a bit easier.

This is what COM does that pertains to what you''re doing:
A GUID is generated and stored in the registry for every object interface specification and for each object implementation.

Any given object can support many interfaces and must implement IUnknown. For instance IUnknown, IDirectDraw3, IDirectDraw5, IDirectDraw7, etc... are all implemented in the CODirectDraw7 class.

In order to create an object you need to know it''s class GUID (aka reference uuid) and an interface it supports. Remember all COM objects support the IUnknown interface, so you really only need to know it''s refiid - though you''ll need another interface ID in order to do anything useful.

COM fully & clearly seperates the interface declaration from the class definition. There''s even a handy-dandy language called IDL, that is supported by VC, VB, & Delphi, to create your interface defintions with. The particular compiler then ''compiles'' the idl file and generates the correct header files for the given language.

COM further defines a binary specification for the interfaces - so the binary representation of the interfaces to the class object is also the same in RAM with all environments. That means you can create an object in any of the languages, and use it in any of the languages, pain free.

It''s ideal for plug-ins.

Magmai Kai Holmlor
- The disgruntled & disillusioned


#14 Gyzmo   Members   -  Reputation: 162

Like
Likes
Like

Posted 22 February 2001 - 08:54 PM

I know, I own a book about COM (DCOM actually) and that''s where part of my idea came from, the fact that I don''t want to use it in my Uberfactory is because first of all, it adds complexity for the client-programmer and secondly it doesn''t need a lot of features of COM, such as global access to objects in computer-space (as opposed to program-space) (I hope I''m explaining this well). And well, if I were to use it in a game, using ID''s for each registered object, compares of longs are a lot faster than GUIDs.

Maybe when I''m (IF I) implementing it, I''ll see that the use of COM might be useful, but we''ll see (or won''t)...

Gyzmo
=======================


#15 Altair   Members   -  Reputation: 122

Like
Likes
Like

Posted 25 February 2001 - 08:56 PM

Gyzmo,

I just don''t find it very good way to have a global instance of a factory, even if it''s actually a pointer to an abstract factory interface. Also, I don''t understand why it needs to be singleton.

I wouldn''t either use any key words for creating objects, but direct method calls dedicated to create certain type of objects. Like: factory->createThread(); ID''s, particularly string ID''s, are very error prone and inefficient way to create objects. Instead, if you have separate methods for creating different objects, you can provide different interfaces to access them. It''s not convenient to have Thread and Goblin sharing the same base interface, because to be able to use the object, you should perform some nasty downcasting.

If you have sub-factories, you can nicely split the creation of objects to several interfaces. It makes your code alot easier to follow and control. If you have first a factory, which creates only sub-factories, it''s better first create monsterFactory and then monsters from it.

Anyway, I don''t think that factory is proper way to create all objects. You should use factory to only create objects, which are platform dependant or require extremely good performance and I don''t find Goblin belonging into this group (: But Thread and Socket do, of course.

Cheers, Altair


"Only two things are infinite, the universe and human stupidity, and I''m not sure about the former." - Albert Einstein





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