[comp.object] Comments on Object Oriented Programming

plogan@mentor.com (Patrick Logan) (02/02/90)

In article <375@argosy.UUCP> kentb@argosy.UUCP (Kent Beck) writes:
 >  In response to the comment that when engineering groups switch to OOP
 >  "the rich get richer and the poor get poorer".  This was expressed quite
 >  strongly by Ragu Raghavan in a panel at OOPSLA '88.  Following that,
 >  Ward Cunningham and I have been developing a design method (cf. OOPSLA
 >  '89 proceedings) which contradicts that experience.  I have found that
 >  by stripping OO design of unproductive distractions all programmers I
 >  have tried the method with have been able to contribute their experience
 >  to an OO design.  Everyone is able to grasp the design that results as
 >  well.  Of course the programmers contribute to greater or lesser degree,
 >  and an experienced OO designer is required to act as a "scribe", but no
 >  one is totally lost.

 >   Kent Beck

Among other influences, I wonder how much this is all affected by (1)
the "mentors" a new OO programmer has nearby and (2) the language and
environment the programmer is using to learn OOP.

I don't think it can be generalized that with "object oriented
programming the rich get richer", etc. I think you have to say
something like "in transitioning from a typical C shop to a C++ shop
that is learning object oriented programming, some people catch on
more quickly than others."

Or something like that. That was just an example. The main point is
your mileage may vary.

-- 
Patrick Logan                | ...!{decwrl,sequent,tessi}!mntgfx!plogan 
Mentor Graphics Corporation  | plogan@pdx.MENTOR.COM                    
Beaverton, Oregon            |

jimad@microsoft.UUCP (JAMES ADCOCK) (02/03/90)

In article <4942@crdgw1.crd.ge.com> kornfein@england.crd.ge.com () writes:
X
XWe have used Object Oriented programming here for the last few years and have
Xfound pluses with it but also some minuses.
X ...
XThe difficulties we have had in OO programming mainly occur, using methods, in 
Xthe areas of maintenance and expansion of existing programs. Specifically here
Xare some examples:
X
X1. Inheritance while saving code, has the drawback that it is very hard
X   to follow flow of control of the system this makes tracing bugs often
X   difficult, especially if you didn't write the code to start with.
X
X2. Some of our first OO projects were done by people not very familiar with
X   OO concepts.  The code they produced is almost impossible to
X   decipher.  Our impression is that if not carefully done OO programming 
X   presents greater risks of producing "spaghetti code" than procedural
X   systems.  Dynamic binding of methods can be as misused as assigned goto's.
X ...
XAny comments??

IMHO, after just spending the last couple months looking at these problems
in some very well known Object Oriented code, a major error in what most
people are presently doing is *way too much* emphasis on OOP as a tool for
"code reuse" and "code sharing," and *way too little* emphasis on OOP as
a tool for encapsulating design decisions.  Unfortunately, I don't think
any present OOPL gives us what we really need in terms of strict design
encapsulation.

A common example of this problem is all those code libraries that take
a Smalltalk like approach of having Object depends on Class depends
on ABunchOfContainerClasses depends on TheWholeKnownWorldOfProgramming.
[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]

A symptom of this problem in Smalltalk-like languages is having mimimum
executable sizes of about a half megabyte.

A symptom of this problem in C++ is #including [directly or indirectly]
about 50Kbytes of .h files for each 1K .c file compiled ["How come it
takes me two hours to compile this little draw application?"]

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.

My claim is that the maximum number of other classes a class should depend
on, either through inheriting features, delegation, or just asking an
object of one of those classes to do something is about 6.  In C++ one
could interpret this as saying the max number of include files you should
ever need for a successful compilation is about six [*including* the .h
files that other .h files include]

My claim further is the "right" number of methods an object should support
is closer to 10-20 than 100-200.  Likewise instance variables.

Even with these restrictions, someone reading a given class has the potential
of getting exposed to maybe 100 different class+method functionalities.
I've seen many classes that do much, much worse.

If this sounds like motherhood and apple pie to any readers, I challenge
them to find examples of good "non-trivial" OOP code that meet these 
principles.

kurtl@fai.UUCP (Kurt Luoto) (02/10/90)

In article <10432@microsoft.UUCP> jimad@microsoft.UUCP (JAMES ADCOCK) writes:
>In article <4942@crdgw1.crd.ge.com> kornfein@england.crd.ge.com () writes:
>X
[...]
>
>IMHO, [...] a major error in what most
>people are presently doing is *way too much* emphasis on OOP as a tool for
>"code reuse" and "code sharing," and *way too little* emphasis on OOP as
>a tool for encapsulating design decisions.

Amen.

>Unfortunately, I don't think
>any present OOPL gives us what we really need in terms of strict design
>encapsulation.
>
[... criticism of Smalltalk omitted ...]
[... complaint about number of #includes in C++ omitted ...]
>
>My claim is that the maximum number of other classes a class should depend
>on, either through inheriting features, delegation, or just asking an
>object of one of those classes to do something is about 6.  In C++ one
>could interpret this as saying the max number of include files you should
>ever need for a successful compilation is about six [*including* the .h
>files that other .h files include]
>
>My claim further is the "right" number of methods an object should support
>is closer to 10-20 than 100-200.  Likewise instance variables.
[...]

I agree with the importance of encapsulation.  It is the #1 reason
why I consider OOP to be important.  I view inheritance as also
aiding the design process, in some cases supporting encapsulation.
I still can't understand why there is all this hype about "code reuse".

I agree that it is useful to try and find useful rules of thumb
(6 related classes; 6 other #includes; 10-20 methods or members; etc)
for guiding or testing our design process, especially when we
lack other more precise, objective guidelines.  Many of us use
these sorts of rules all the time (avoid 'goto' statements and
global variables; functions no more than 50-100 lines long; etc)
in non-OOP contexts, such as programming in C.  Some of these we
learn through experience, and some of them have been confirmed to
one degree or another by various "studies" done on software
productivity (comforting for those who have faith in "studies").

I am not aware of any such studies in OOP (not that I am widely
familiar with all the OOP literature -- any help out there? Ed Berard?).
Given the relative youth of OOP as a field, I would expect that
it will be some time before widely accepted useful rules of thumb
have been formulated and confirmed by experience.  Thanks for sharing
your experiences.

I hasten to point out that rules of thumb are just that.
A good designer will recognize those (hopefully rare) situations
that require breaking one or more of these rules to better meet
the higher criteria of good design (encapsulation, maintainability,
clarity, etc).  Pity the job shop that slavishly treats such rules
as inviolate dogma.

My major experience using OOP was in the design and coding of the
realtime firmware for a T1 multiplexer in C++.  I believe the design
was a good one. On the whole, classes were small, fitting within
the guides you gave.  But there was also an important set of classes,
corresponding to the option cards in the physical equipment, which
were rather large and complex.  There were ~30-50 member functions
per class, with perhaps an equal number of member items.  The code
implementing the member functions called on perhaps 20-30 include files,
including the nested ones.  

Now these large classes may sound unwieldy, but I believe the design
was pretty much correct because they reflected the inherent complexity
of the physical system; the option cards being modeled by the classes
were in fact very complex in their functionality, and that functionality
did not divide well into separate entities.  I consider it a blessing
that we were allowed to use C++, with the encapsulation that it provided.

Since this project was what we in our group used to cut our teeth
on in OOP, we also made our share of mistakes.  The one I remember best
was the tendency to "over-classify", to introduce classes even where
they were not strictly necessary or appropriate (after all, C++ is
not Smalltalk).  This is perhaps to be expected.  By analogy, I've
seen many young C programmers struggle to understand the concept of
pointers.  When it finally clicks, and they understand how pointers
work, then there next batch of code will be "pointer-crazy", using
pointers even where not appropriate.  Then over time, they learn
when it is wise to use them and when not to.  The same could be said
of many other programming techniques and language features.

So from my experience I offer these points:

	1. When first using OOP (in C++) beware the temptation
	   to "over-classify".

	2. Sometimes a complex application will require a set
	   of complex classes, which are "large".  Remember
	   Einstein's rule.

	3. Sometimes good encapsulation will increase the
	   number of other classes that interact with
	   a particular class.  At other times, it will
	   tend to deepen the inheritance tree (or forest)
	   of the classes in the application.  In either case,
	   there is an increase in the number of include files
	   that you have to use in certain files.  The ideal
	   solution is not to compromise the design, but to seek
	   tools (languages, compilers, environments) which
	   better support these kinds of designs.
-- 

----------------
Kurt W. Luoto     kurtl@fai.com   or   ...!sun!fai!kurtl