From: pjb@... (Pascal J. Bourguignon) Date: 2009-01-31T18:50:04+09:00 Subject: Re: proper use of classes Tom Cloyd writes: > [...] My problem > was simply that as I was trying to introduce classes into my project > code, I didn't know when I really SHOULD create a class. I had gotten > the impression somewhere that major methods should virtually always be > reconceptualized as classes. I didn't arrive at that notion by thinking. > I'd given up on that, as I didn't have enough material to work with. > > But, that perception didn't really make a lot of sense. Still, I > couldn't find any explicit guidance anywhere regarding the fundamental > question I kept asking: WHEN is it the thing to do to make a class? I > did find those two sentences in Thomas (3rd ed) - but that's sparse > pickins, and I didn't find them until AFTER my weekend disaster in which > I spend a pile of time converting a complex method into a class, getting > completely exasperated with the experience, and converting it back. So, > I wasn't overthinking at all. I was mis-perceiving, in the presence of > an absence (ha!) - an absence of clear guidance about the > WHEN-do-classes issue. The best sense I could make of things was that > "big stuff oughta be classes" (bad idea). I didn't yet "get it" > (understatement). First you write a problem statement. Then you identify the important words in it. Nouns will become classes. Verbs will become methods. (approximatively). The idea is that what has nouns in natural language are the objects that have some stability in the real world, and what has verbs are the actions. Of course, you can have reification of the actions or the associations, when you start to speak about verbs (notice that "verb" is a noun, not a verb). For example, when you write: (def m(x) (2 * x) end) you actually instantiate an object of the class Method: (Object . method "m") --> # but you do that only when you're talking at a meta-level, here it's the level of the Ruby language, not that of your problem domain. Instead of reifying the "big stuff", you should rather try to reify the _stable_ stuff. A Person is something that is table, from her birth to her death. On the other hand, eating, sleeping, working, reproducing, breathing, are temporary actions. There even are actions that cannot be done during all the life time. For example, a baby Person has no walk method. This method is programmed during the first few years. Objects encapsulate state and methods. When your problem domain (cf the problem statement) considers a Person only in her relations with the surrounding world, then the methods of a Person will be Ruby methods. You won't need to reify these methods. On the other hand, if your problem statement is to implement a Person simulator, then it's possible that the methods of a Person need to be reifed, so you can add, change and remove these methods. Imagine having to write a Person simulator that starts in the baby state, and that should evolve a walk method. In this case, you could have a MotorMethod class, and a Walk subclass, as well as classes such as Muscle, Bone, Nerve, etc. But these kind of classes would be named in the problem statement (at least latently, sometimes problem statements are brief). -- __Pascal Bourguignon__