[comp.object] Comments on OOP style

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