Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!unisoft!fai!kurtl From: kurtl@fai.UUCP (Kurt Luoto) Newsgroups: comp.object Subject: Re: Comments on Object Oriented Programming Summary: Be careful of rules of thumb Message-ID: <2715@fai.UUCP> Date: 9 Feb 90 18:28:17 GMT References: <4942@crdgw1.crd.ge.com> <10432@microsoft.UUCP> Reply-To: kurtl@fai.fai.com (Kurt Luoto) Organization: Fujitsu America, Inc Lines: 112 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