24 Mar, 2010, David Haley wrote in the 81st comment:
Votes: 0
I guess I meant that "thinking about builders and building" seems to be wholly separate from what we were talking about: I was just trying to make sure I hadn't missed something somewhere. It looked like you were responding directly to what Deimos said, which confused me.
24 Mar, 2010, flumpy wrote in the 82nd comment:
Votes: 0
David Haley said:
I guess I meant that "thinking about builders and building" seems to be wholly separate from what we were talking about: I was just trying to make sure I hadn't missed something somewhere. It looked like you were responding directly to what Deimos said, which confused me.


Well, I was responding directly, but I what I was trying to do was to point out that although what he was saying was essentially correct, the use of the two syntaxes were valid in different problem domains. It appeared to me that he was delineating between their usage as pure semantics, which is not entirely the case.
24 Mar, 2010, David Haley wrote in the 83rd comment:
Votes: 0
IMHO what constitutes good programming design changes considerably on what you're trying to do with it. Something could be utterly appropriate when creating a DSL for building/scripting, yet the exact same thing could be completely inappropriate from the overall system builder's perspective. I realize that this is more or less what you said ("valid in different problem domains"), but I think that at present it is somewhat of a red herring to be discussing other problem domains. (It's an interesting, but at present unrelated, topic.)
24 Mar, 2010, flumpy wrote in the 84th comment:
Votes: 0
I thought it was worth pointing out, because then it can actually be dismissed from the entire discussion. It seemed like it kept cropping up as a valid solution.

Also I wasn't aware that slightly tangential topics were taboo, someone needs to call the forum police I guess.
24 Mar, 2010, David Haley wrote in the 85th comment:
Votes: 0
I didn't say they were taboo, I was saying they were confusing or misleading in this case. :tongue:
24 Mar, 2010, flumpy wrote in the 86th comment:
Votes: 0
David Haley said:
IMHO what constitutes good programming design changes considerably on what you're trying to do with it. Something could be utterly appropriate when creating a DSL for building/scripting, yet the exact same thing could be completely inappropriate from the overall system builder's perspective. I realize that this is more or less what you said ("valid in different problem domains"), but I think that at present it is somewhat of a red herring to be discussing other problem domains. (It's an interesting, but at present unrelated, topic.)


Also, while we're at it, isn't it a valid point to make wrt the system builder too? I mean, he has to be aware of such a problem in order to design the system for such a scenario? I think it's perfectly related. But, whatever.
25 Mar, 2010, shasarak wrote in the 87th comment:
Votes: 0
Deimos said:
1) User issues command
2) Server receives user input
3) Server passes input to CommandInterpreter
4) CommandInterpreter parses command into an understandable action (<user> wants to cast <spell>)
5) CommandInterpreter tells World (or SpellManager, or whatever…) that <user> is trying to cast <spell>
6) World does error-checking to see if <user> can cast <spell> (this most likely involves several other TBD objects responding to World's requests)
7) If it's allowable, World then creates a Spell object, inserting it into its own User/Spells collection
8) Each tick, casting time is decremented (however you handle this kind of thing)
9) When the spell is finished casting, the Spell object does whatever <spell> is designed to do and World removes it from its collection

The main criticism there is that "World" clearly shouldn't be doing step 6; something more specialised like a "SpellManager" would be reasonable. Otherwise you're okay.

I might be tempted to wrap step 6 into the object that you suggest creating in step 7, so that you have a class that models the entire spell-casting process, including determining its success or failiure; but you could argue that one either way.
25 Mar, 2010, Deimos wrote in the 88th comment:
Votes: 0
shasarak said:
The main criticism there is that "World" clearly shouldn't be doing step 6; something more specialised like a "SpellManager" would be reasonable. Otherwise you're okay.

Yeah, I got that much from your past posts, but you still haven't given a reason yet for why you think this is the case. I see it as a purely cosmetic separation. There's behavioral/functional reasons for everything else I separate, but this would have none that I can think of.
25 Mar, 2010, David Haley wrote in the 89th comment:
Votes: 0
I'm also curious, because it doesn't seem to me that Deimos's solution is going against the entire OO paradigm whereas you seem to think it is – I'd like to hear why. (I'm also not sure if you still believe that, because your most recent post indicates that he might be okay after all. And no, I'm not trying to rub this in or anything: I'm trying to get useful information to think about and perhaps learn from.)
25 Mar, 2010, flumpy wrote in the 90th comment:
Votes: 0
My own personal feeling is that 6 should be done by the SpellManager object rather than the World object, even if SpellManager is a delegate of World.

A main tenet of OO is high cohesion, which this sort of operation if perfformed by a World object, could in effect lower. You are in effect mixing conceptually different data and behaviour together.

This of course assumes that World deals with only abstract world operations. This should always be a goal, because it can make refactoring code easier in the long run.

It's a bit like data normalisation in a db, 1st and second normal form are all well and good until they become a problem as the system grows, which is why it's always good to try to aim for 3rd.
25 Mar, 2010, flumpy wrote in the 91st comment:
Votes: 0
Also, the high cohesion principle can help sometimes with security. If I put the methods for casting a spell in the same object that deals with shutting down the mud, it is harder for me to control access to that functionality with sandboxing techniques. This isn't always such an issue if you do not intend to use sandboxing, of course.

That aside, it's also easier to confuse others about the purpose of your object, which can lead to programming errors (like misunderstanding the meaning of a method name, for example) - I understand in this context it is an unlikely error, but as a general rule the principal of high cohesion is a good one because of the above and I'm sure a few other reasons too that have not come to mind.

Edit did I say anything about object reuse? Object reusage is also a benefit of high cohesion. There.

I'm knackered from being on call so sorry if I seem a little rambly..
25 Mar, 2010, Deimos wrote in the 92nd comment:
Votes: 0
flumpy said:
It's a bit like data normalisation in a db, 1st and second normal form are all well and good until they become a problem as the system grows, which is why it's always good to try to aim for 3rd.

It's funny you should mention that, since I viewed this separation like vertically partitioning a table, which would actually be de-normalization.

So, then, what does World do, if not conceptually world-based tasks? Should we also have a CharacterManager, MovementManager, CraftingManager, and so on? It really starts to get rather ridiculous after a while.
25 Mar, 2010, David Haley wrote in the 93rd comment:
Votes: 0
discussionManager.instance().manage(new Discussion())
25 Mar, 2010, Deimos wrote in the 94th comment:
Votes: 0
world = new ManagerManager();

:tongue:
26 Mar, 2010, donky wrote in the 95th comment:
Votes: 0
Deimos said:
world = new ManagerManager();

:tongue:

Are you making fun of my codebase and its ServiceService?? :lol:
26 Mar, 2010, Davion wrote in the 96th comment:
Votes: 0
Heh. It reminds of me of the SPL

$fileSPLObjects =  new RecursiveIteratorIterator( new RecursiveDirectoryIterator($directory), RecursiveIteratorIterator::CHILD_FIRST );


*shudder*
26 Mar, 2010, flumpy wrote in the 97th comment:
Votes: 0
Sigh
26 Mar, 2010, flumpy wrote in the 98th comment:
Votes: 0
Basiy what it boils down to is is-a over has-a again. If you put the spell logic and data into world you are saying that World is-a spell manager.

Someone link to the is-a vs has-a thread I can't be bothered.
26 Mar, 2010, shasarak wrote in the 99th comment:
Votes: 0
Deimos said:
Should we also have a CharacterManager, MovementManager, CraftingManager, and so on?

Yes.
26 Mar, 2010, flumpy wrote in the 100th comment:
Votes: 0
Deimos said:
flumpy said:
It's a bit like data normalisation in a db, 1st and second normal form are all well and good until they become a problem as the system grows, which is why it's always good to try to aim for 3rd.

It's funny you should mention that, since I viewed this separation like vertically partitioning a table, which would actually be de-normalization.


Normalisation groups data together logically (account data in one table and address data in another) joined by keys. There is no other reason for doing this at 3rd normal form other than the logical grouping of information: if you go further than 3rd or 4th normal form you could end up partitioning vertically, but I do not understand why this is wrong, only applicable under different circumstances.

Deimos said:
So, then, what does World do, if not conceptually world-based tasks? Should we also have a CharacterManager, MovementManager, CraftingManager, and so on? It really starts to get rather ridiculous after a while.


Yes, you "should" (in quotes, because "it depends"). It is far harder to re-factor code and can become much more difficult to understand what the object is actually doing if you are mixing functionality together like this in a single class. IMHO it is more ridiculous for a World object to deal with spells than a SpellManager delegate, because logically the methods and data have nothing to do with pure World functions.

But that's not to say it isn't a hard and fast rule, you should use composition when you feel like your objects are becoming too multifaceted or when you require object reuse. I often build objects that initially perform most tasks themselves, and when I hit a scenario where I have to reuse the code only then move the methods and data into a second.
80.0/163