johnson@p.cs.uiuc.edu (02/05/90)
jimad@microsoft.UUCP said >[The Smalltalk philosophy being to "ignore" design encapsulation and > to give users fast response tools to allow one to keep hacking until the > code works] This is completely untrue. Design encapsulation is important in Smalltalk just as in any other language. It is true that there is a different style that is used in Smalltalk when one is rapid-prototyping than when one is designing reusable code, but this does not seem to be the topic under discussion. Instead jimad@microsoft seems to be claiming that the Smalltalk philosphy is to ignore maintainance, elegant design, etc. In fact, I think that good Smalltalk worry about elegant reusable design more than any other kind of programmers. >A symptom of this problem in Smalltalk-like languages is having mimimum >executable sizes of about a half megabyte. The minimum executable in Smalltalk-80 is actually 50K or smaller. One of my students was able to make a version of the system tracer and get it that small. My guess is that more work could have made it smaller. My response really didn't address the point of this complaint, though, which was that one class really shouldn't access very many other classes. The statement that one class should never access more than six other classes is clearly false in Smalltalk, since Number, Boolean, Block, String, Character, Collection, and Stream are used by most classes, so imposing a limit of six classes would mean that no new classes could be used. A argument against my point of view might be that these classes don't count, that they are really part of the language and not part of the application and thus shouldn't be counted. Smalltalk is a wierd language, some would say, because things that are usually built into the language are implemented by class libraries. However, Smalltalk programmers not only consider the above mentioned classes to be "part of the language", they consider the graphics and the user interface classes to be standard. If a company has a standard set of classes then programmers start to treat them as part of the language, too. The great thing about OOP is that it makes languages extensible, and once a class library has become standard then people don't have to think about it any more. Whether he knew it or not, jima@microsoft probably suggested six as the right number of class interfaces in a system because the human short term memory can only remember 5 to 9 things at a time. However, classes that become standard become part of the long term memory, and there is no limit (or at least a much larger limit) on long term memory. Thus, once classes become standard then they shouldn't be counted in the cognitive size of a system. This is one of the reasons that Smalltalk seems too complex to beginners but is so productive to experts. Beginners have to stuff 20 or 30 things in short term memory before they can understand a program, and this is nearly impossible. However, almost all these interfaces are standard, so from the point of view of an expert there are only two or three new interfaces in the application and it is quite simple and easy to understand. So, I think that the recommendation that no C++ class should access more than 6 .h files is wrong. It doesn't matter how many standard classes are accessed, it is only the non-standard classes that count. I would give a similar argument against the requirement to limit the number of methods in a class to 10-20. In a standard class, it doesn't really matter how many methods there are as long as they are easy to understand. (Carried to extremes, of course, this is not true.) In a new class, it is only the interface that needs to be small, i.e. you should have no more than 10-20 public methods. However, it doesn't matter how many private methods you have, as long as they are all easy to understand and useful. >So my recommendation is to place first and very much foremost design >encapsulation as the most important OOP *good* property -- yes, even >much more important than inheritence. The problem with this recommendation is that it has nothing to do with OOP. Design encapsulation is an extremely important property of good design, regardless of the programming style. I agree---place first and very much foremost design encapsulation as the most important property of good design of reusable software. However, I expect that you could achieve this property in non-OOP languages. Ralph Johnson
kitchel@iuvax.cs.indiana.edu (Sid Kitchel) (02/06/90)
johnson@p.cs.uiuc.edu writes: >My response really didn't address the point of this complaint, though, >which was that one class really shouldn't access very many other classes. >The statement that one class should never access more than six other >classes is clearly false in Smalltalk, since Number, Boolean, Block, >String, Character, Collection, and Stream are used by most classes, so >imposing a limit of six classes would mean that no new classes could >be used. This sounds like some theorem of Software Science, which I was hoping was confined now to West Lafayette, Ind. exclusively. From my point of view OO design (especially for OODBS) should emphasize a natural capture of what is going on in the REAL situation. If you are modeling a real-world system as a database design often must, the system itself determines the associates of any class and the particular relationships that a class will have. It also determines the number and nature of the needed methods. Making arbitrary dicta a priori about "good" vs. "bad" OO design seems futile at best, if not down right silly. My point also strongly applies to the debate over reusability. It too should occur NATURALLY. You should not bend the design to obtain it. If it occurs, let it be. But as a designer your main job is to design the present system you are working on. Of course, I am not saying ignore reusability -- I am only saying that the software IC metaphor is just a metaphor, not an end in itself. --Sid -- Sid Kitchel...........WARNING: allergic to smileys and hearts....... Computer Science Department kitchel@iuvax.cs.indiana.edu Indiana University skitchel@ucs.indiana.edu Bloomington, Indiana 47405-4101...............skitchel@iubacs.BITNET
johnson@p.cs.uiuc.edu (02/07/90)
Rereading in the morning the message I sent last night, it is clear that I was harder on jimad@microsoft than I intended to be. He raises important points about good designs being changeable and that one class shouldn't access too many other classes. I disagreed with his numbers because of the fact that standard and often used classes are almost invisible to the expert. Thus, accurate design rules will be much more complex than the ones that he was proposing. However, the general idea is certainly valid. Ralph Johnson -- University of Illinois at Urbana-Champaign
jimad@microsoft.UUCP (JAMES ADCOCK) (02/10/90)
In article <135300028@p.cs.uiuc.edu> johnson@p.cs.uiuc.edu writes: > >Rereading in the morning the message I sent last night, it is clear that >I was harder on jimad@microsoft than I intended to be. He raises important >points about good designs being changeable and that one class shouldn't >access too many other classes. I disagreed with his numbers because of >the fact that standard and often used classes are almost invisible to >the expert. Thus, accurate design rules will be much more complex than >the ones that he was proposing. However, the general idea is certainly >valid. > Well, let me make it perfectly clear that I don't claim there are any "hard" numbers, and I don't know all the answers here. In the classes I've seen, if they are dependent on a couple dozen other classes, they are a disaster. Likewise if they have about 100 methods, they are a disaster. My first test nowadays of the "goodness" of a set of classes is to try to draw a dependency chart of the classes: 1) If you can't draw a dependency chart [because the design is so obscure, or so convoluted], the design is bad. 2) If the resulting graph looks bad, the design is bad [I claim.] A bowl of spaghetti is a bowl of spaghetti, whether implemented via control flaw [sic] or class declarations. 3) If you include dependencies on global classes, or global decisions in general, the graph is going to look bad. There are maybe two answers to this a) take global classes, global decisions [global whatevers] as a given and leave them off the chart or b) decide globals of any kind are bad, and try to program to avoid them. BUT: We are all use to taking a few globally used primitive types are a given, and use them throughout our programming: ints, chars, 32bit-floats, 64bit-floats, strings?, etc. Is this good or bad? Should these "primitive" types count on our dependencies chart? Or could it be that the continued global use of primitive types is an indication of our immaturity in OOP? --And that when we become more competent in OOP we will develop more powerful classes to do our jobs, and leave the primitives behind? I don't know. I think I may claim the later. Q: What does it take to make a good looking interdependencies graph? A: A given class must typically not depend on more than a half dozen other classes. Q: When does a class "depend" on another class? A: I don't know a single right answer for this. If C depends on B depends on A, but B's dependence on A is strictly encapsulated, then C should not be considered directly dependent on A. Presumably C can be understood without referring to A's code. But in a final executable executing C *is* going to be dependent on A. And, at least in C++ [and presumably in some other OOPLs] compiling C is going to require the compiler first to read in parts of the definition of B and A. Ideally, in a well designed language, if B strictly encapsulated its dependency on A [made it private] then compilation of C would only require knowledge of the definition of B, not also of A. In short, one can come up with several different dependency charts depending on what definition of "dependency" one is interested in. And they could all be valid ways of looking at *differing* problems of interdependency.
davidm@uunet.UU.NET (David S. Masterson) (02/11/90)
In article <10527@microsoft.UUCP> jimad@microsoft.UUCP (JAMES ADCOCK) writes:
In short, one can come up with several different dependency charts
depending on what definition of "dependency" one is interested in. And
they could all be valid ways of looking at *differing* problems of
interdependency.
Is it my imagination or is this beginning to sound like the methods one would
apply to developing a relational data model? In fact, is this not true with
most any OOD methodology as it starts with objects (entities?) to be dealt
with, then addresses their "sphere of influence" (attributes), then their
interrelationships (public interface), and their internal functionality?
Perhaps its time to address the "other" design methodologies and what they
lack that OO can provide or how they apply to OO.
For instance, someone mentioned how an OO methodology is not a top-down
methodology. However, I suspect a lot of people approaching a new application
to apply an OO methodology would start by finding the largest objects in the
application to talk about. From there, they would break it down into simpler
and simpler concepts by identifying the simpler objects that the more complex
objects deal with. Is this not a top-down methodology? What makes it not an
OO methodology?
--
===================================================================
David Masterson Consilium, Inc.
uunet!cimshop!davidm Mt. View, CA 94043
===================================================================
"If someone thinks they know what I said, then I didn't say it!"
tce@ann.MN.ORG (Thomas C. Evans) (02/12/90)
My approach to OOD has been touched on in various ways by this discussion. One aspect of it I have termed "Middle Out" design, rather than top down or bottom up. The point is that that while the top level function may be described (don't we all like one line specs) the top level DESIGN is not. I also start with the assumption that many small reusable parts are available (reinventing wheels when your job is to build cars is counter productive) so I don't start at the bottom. The image I use is the Lunar Lander. Its external shape could not have been determined ahead of time, and was not designed. Its external shape was a product of lower levels of design requirements. At the lowest level individual components reflected the contents of parts catalog and real-world constraints, rather than Lunar Lander constraints. My favorite design paper, in support of OOD & encapsulation is still: D. L. Parnas, "On the Criteria to Be Used in Decomposing Systems into Modules," CACM 5:12 December *1972* P.S. OOD was applied to COBOL, its called Ada: the common defense oriented language also designed by a committee and forced as a standard :-) -- Thomas C. Evans self is like insanity, tce@ann.MN.ORG Minneapolis MN. its hereditary and you {umn-cs,amdahl,hpda}... (612)448-4848 x285 get it from your children ...!bungia!ann!tce