Hi Stephen, "Stephen White" <steve / deaf.org> wrote: > The main problem [with OO] was the way inheritance strung my code out, so I would > end up with a class derived from another class derived from another class, > then discover that I needed the information in one class to be available > to another class. Modifying class structures involves so much re-writing > that it just became far far too painful. The last game I released was called Wartorn. It was a 3D RTS. There was a base class called Object, and derived classes called Moveable, Static, and more classes called Owned : Moveable (even though some things can be owned and not moveable), Human : Owned (although some humans were not really owned, but all Humans were Moveable), Vehicle : Moveable, Tank : Vehicle, Plane : Vehicle (although you cannot land a Tank, and path-finding for tanks and planes are different), etc. It was all compounded by the fact that some things were 'Armed' or not (that is, they can target and have ammo), or were 'Repairable' or not. It was OO at its worst. Yes, it could have been organised better *in hindsight*, but only incrementally so. The Real World is not a taxonomy, it is 200,000 lines of abtruse code. These were smart and talented guys, just doing what they knew about OO as best they could. The only reason I knew better was because of a game called KKND (also a RTS) that I wrote earlier, where I also tried to play the OO game. It hurt. It may have seemed OK for the Wartorn guys at the time, when things were small and manageable. But when I came onto the project (to 'fix' it), I was (not unexpectedly) confronted with this horrible class hierarchy that was the main cause for the problems facing the project. There was a lot of code that looked like this: void Moveable::onSomeAction() { switch (getType()) { case PLANE: Plane *plane = (Plane *)this; // code that is awkward to find and modify break; } } Now, it could be argued that this is demonstrative of bad design. But I've seen it again and again. At some point you have to stop blaming the messenger. They certainly hoped to provide some small subset of virtual functions that would encapsulate all the necessary behaviour. I'm sure it worked at first, before any cruft and before Real Work had to be done. IMHO, better is: // some_action.h void onSomeAction(Moveable *); void onSomeAction(Plane *) ; At least it is explicit. You will get told by the compiler if you try to land a tank, or refuel a human. No, I wouldn't write code exactly like this (there is no notion of const for a start), although I prefer 'global' (namespaced) functions that represent actions overloaded by type than methods that are within scope of a class. > Trying to get around this involved reams of kludge code that would use > both types and copy from one to the other. Not really very nice. Tell me about it :) > I visualise this form of code as being like mould growing on a spider web. > If you need to re-arrange a bit of code, pulling on it will yank on the web, > pulling all the other bits of code out of place and creating a domino effect > that requires more and more re-writing. This is telling, because it demonstrates the real-world problem that you don't know everything in advance. But by then, you are already stuck with a rigid and brittle class hierarchy that seemed like a Good Idea at the time. > If I'd gotten the structure right, it would have been great code. I always > get it wrong. It's that God's eye view thing again. To quote Good Will Hunting, "It's not your fault". It is the fault of ppl and institutions (like DDJ and associated pop-trash) trying to propose The New Thing as the Only Thing. And being the hapless schmucks that we are, we believed them. > The lack of static typing totally changes the picture. OOP just becomes > a way to have private namespaces. Communication occurs between methods, > not along type boundaries. I can organise my code the way I want, as > everything's just a function call. Objects are just namespace context. I'll even use caps. STATIC TYPING IS IMPORTANT. I'm not yelling at you, Stephen. You /can/ have encapsulation without classes. Assuming you have something other than just Objects, that is. It's called a namespace (no, C++ namespaces are not well executed). > I visualise this as being clumps of code floating around, which I can > pick up, move around, create associations, and do pretty much anything > without disturbing any other code. That's called generic programming with models. A model in this context is an interface contract that attempts to guarantee *both* syntacic and semantic conformance, without the constraint of commonality of type. begin() gives you the start, and end() gives you the end. > If I modify an object, then of course I have to change the code that > required the old behaviour, but at least it's a direct correlation > without any cascading changes. To modify an object's behavior, you should modify the behaviour as-it-relates-to-that-type, not *necessarily* the type itself. This is what I mean by functional programming. Of course, some things are class-specific, such as copy and compare. > You need to grok Ruby on its own terms, rather than viewing it as a > cut down version of C++. I don't view it as anything of the sort. I am not dismissive of Ruby. I can seperate my professional interest in Ruby (as a scripting language for non-programmers to use) from my personal interest in Ruby (as something that may or may not offer some important new concepts). > steve / deaf.org Christian.