[Tutor] Flat is better than Nested

Mac Ryan quasipedia at gmail.com
Fri Sep 9 09:08:23 CEST 2011


On Thu, 8 Sep 2011 21:39:47 -0500
"Ryan Strunk" <ryan.strunk at gmail.com> wrote:

> By the time I write this all into a file, the end user will never
> even know this crazy hierarchy exists, but I will, and I don't like
> it. Do I just need to get over it and realize that sometimes nested
> is necessary, or is there a better way I might consider?

There are two different problem you should consider here.

The first is the MODEL STRUCTURE of your player. A model is a
representation of something, so you really can't change the model
structure that much from reality, as what you want is truly the
opposite: you want to have the model as close as possible to the
"something" you are representing. 

The other element to consider is the way you MANIPULATE your model, and
this is the level at which you can operate to make your life easier.

An example might clarify: suppose you are writing a very
detailed simulation of the universe, and in it you have to model a
neutron in your right big toe: your model could be something huge in
terms of nested levels:

Universe --> Milky way --> Aplha quadrant --> Solar system --> Planet
Earth --> Continent --> Country --> County --> City --> District -->
Building --> Floor --> Flat --> Room --> Person --> Limb --> Toe -->
Cell --> Molecule --> Atom --> Nucleus --> Neutron.

Now, if your simulation needs to know about stellar systems,
continents, and all the rest, you really WANT to maintain all the
levels of the hierarchy, because putting neutrons "flat" together with
galaxies would make truly hard to write sane code.

What you have to ask yourself is how  you are going to manipulate your
data. For example: when you are considering your neutron collisions with
nearby subatomic particles do you really need to know about what galaxy
your neutron is in? Probably not: all you need to know is about the
nucleus of your atom. And when you are calculating the time a planet
takes to go around it's star, do you really need to know about people
living on it? Again: probably not.

The trick for you would be to break down your hierarchy in sensible
chunks, attaching to each bit of it the parts of code that are relevant
at that resolution. So you could have a class "Nucleus", that
knows about its parent molecule and its children particles  and have
methods like "get_atomic_number()", "decay()" or "bond_with()". And
another class called "StellarSystem" knowing about its galaxy
quadrant, its star(s) and its planet(s), having methods like
"calculate_revolution()", "collapse()", etc...

This is really what OOP is all about: you creating semi-independent
objects which include only the information and methods needed at the
level you are using them.

Incidentally this won't only make things EASIER, it will also make them
more FLEXIBLE/EASY-TO-MAINTAIN. 

Still working with the universe example: say that at some point (after
you already wrote the code for planet Earth) you realise that other
planets indeed are not organised in countries/counties/cities... If
whenever you referred to an element in your simulation you included its
entire hierarchy, you will be in trouble: you will have to modify your
code everywhere you referred to something smaller than a planet. 

If you contrarily broke down your hierarchy and discover that on Alpha
Prime they don't have administrative regions but just cities, all you
will have to to is creating a new sister class "PlanetNoBorders"
for the one ("PlanetWithRegions") that you used for the Earth, then
you will be able to attach to it instantiations of the same City()
class that you already used for planet Earth.

In OOP this is called "programming to an interface", meaning that
your code should ignore the real STRUCTURE of your data (the MODEL) and
contrarily only know on how to MANIPULATE that data. Still using the
universe example: if you need to access the list of cities on planets,
you should make sure a "list_cities()" method is available both in
"PlanetOriginal()" and "PlanetNoAdminBorders()" classes, and that they
return data in the same format. You can then safely ignore if that
specifc planet has or doesn't have countries on it.

HTH,
/mac


More information about the Tutor mailing list