Style/Structuring question: One vs. multiple global objects

Henning Hasemann hhasemann at web.de
Sun Jul 1 11:32:54 PDT 2007


Deewiant <deewiant.doesnotlike.spam at gmail.com> schrieb (Sun, 01 Jul
2007 19:09:12 +0300):
> I'd start with making sure "lots of modules need game" == false, to
> the point that no modules need game. IMHO if you have a kind of "god
> object" (or module, I don't write objects for such things), nobody
> should know about its existence. Just like real-life religion. ;-)

Interesting strategy. But that would mean things like the main
character had to  be accessible in other ways, or?

> If you're really that paranoid about globals (I see no reason to be),
> try to make something which contains only the external interfaces to
> your object and put it in a separate module.

I think the paranoia about globals comes from some experiences with or
hints for other programming languages such as python etc... where
globals are generally considered bad style, though I must confess I
never understood why there is/was such a radical talking against them.

Thats one of the main reasons for my post: I'm always a little unsure
how to deal with globals stylistically.

What exactly do you mean with external interface?
The point is: the "game" class would need to know about scenes,
characters and so on. So it had to import the proper modules.
And, for example lots of modules deal somehow with the current scene or
the current main character so they had to import game...
Maybe you could give a simple code example of your strategy?

> After that, try to cleverly eliminate all circular imports in the
> rest of the program, which probably means creating new modules (i.e.
> instead of A <-> B, A -> C and B -> C) in addition to just moving
> stuff around. In general, I prefer creating modules, because it makes
> the code clear: the alternative is being forced to put something in a
> module where it clearly doesn't belong.

Fully agree here, nearly every class has its own module in my code.

> A possible problem with the above is that you may end up with several
> very short modules which only contain a few globals. When it looks
> like this is happening, and I can't find a justifiable way of merging
> them, I tend to just create a "globals.d".

That globals.d then would look like the following, describing the same
problem as game.d:

import mylib.scene;
import mylib.viewport;
import mylib.character;
//...

// globals
mylib.scene.Scene currentScene;
mylib.viewport.Viewport viewport;
mylib.character.Character mainCharacter;

My game.d atm is nearly the same with a "class Game { }" around it plus
some simple functions.

> For instance, in a game, you have a Tile object and an Entity object.
> A Tile needs to know of the Entities standing on it and the Entity
> needs to know where it's standing. There are, as far as I can think
> of, three ways to deal with this: 
> - Put Tile and Entity in the same module, which leads to a
> "tile_and_entity.d" with potentially thousands of lines of code. Not
> very nice.

Ack.

> 	- Succumb to the inevitable and use a circular import, which
> may lead to forward reference issues and makes the built-in code
> coverage analyser unusable.
> 	- Store Entity in Tile, and store x- and y-coordinates in
> Entity. They can then be used by modules higher up in the hierarchy
> to pull the Tile out from an array, or Map object, or whatever.

You mean:

class Tile {
 // ...
 class Entity {
  int x,y;
 }
}

? I guess you mean something different, but atm I just dont get it...

> In my experience, D's abandoning of header files might not have been
> such a good idea, since especially in games, as you have noticed,
> there tends to be a lot of coupling between seemingly unrelated
> things, which makes it very hard to program clean code in D without
> circular imports. Or then I've just missed something which does make
> it easy.

Seems so :-(

> Hopefully this helps.

Today at least a little. But I think if I sleep over it and look at it
tomorrow again it'll help more ;-)

Thanks so far!
Henning

-- 
GPG Public Key:
http://keyserver.ganneff.de:11371/pks/lookup?op=get&search=0xDDD6D36D41911851
Fingerprint: 344F 4072 F038 BB9E B35D  E6AB DDD6 D36D 4191 1851


More information about the Digitalmars-d-learn mailing list