Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!unmvax!gatech!hubcap!billwolf%hazel.cs.clemson.edu From: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe,2847,) Newsgroups: comp.sw.components Subject: Re: Inheritance vs. component efficienc Message-ID: <5731@hubcap.clemson.edu> Date: 10 Jun 89 03:49:42 GMT References: <130200002@p.cs.uiuc.edu> Sender: news@hubcap.clemson.edu Reply-To: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu Lines: 136 From article <130200002@p.cs.uiuc.edu>, by johnson@p.cs.uiuc.edu: > First, inheritance is NOT primarily a way to reuse specifications. > It is primarily a way to reuse code. The real question is, > "what is the kind of code that is being reused?" It turns out > that it can not only be code that describes an implementation, > but a textual description (i.e., a code) that describes a design. Be specific. What precisely are you referring to? (BTW, I didn't assert that inheritance was primarily a way to reuse specifications; in fact, my comments centered around the inheritance of the associated implementations...) > There are at least three reasonable ways of using inheritance. > One is inheritance to specialize a component. This is the kind > that is talked about the most. I presume that by this you refer to the practice of defining a subtype, which has all the functionality of the original type but is restricted in some way, such as having a restricted carrier space (range of possible values). If not, be precise. This practice does not lead to unacceptable inefficiencies. > The second is similar to taking an existing program and editing it > into shape. In other words, you subclass the original class and > redefine methods until it does what you want. (Note for readers unfamiliar with the terminology: "class" is New-Speak for "type", and "method" is New-Speak for "procedure or function"...) > This style of programming results in ugly class hierarchies and > can lead to the inefficiencies that Bill Wolfe complained about. > However, it is very valuable during rapid-prototyping and helps > lead to families of interchangeable components. My comments specifically indicated that the tactic may be useful in isolated areas in which development costs were important and utilization costs were not; however, this does not characterize the software components marketplace. Families of interchangeable components can be achieved by simply defining inter-type compatibilities, and does not require inheritance. > The third way of using inheritance is to inherit from an abstract > class, also called a deferred class. This is the most elegant use > of inheritance, and is essentially using the superclass as a template > to generate new classes. By this I presume you mean the inheritance of specifications; if not, be precise. > [...] it is frequently the case that the addition of even a single > operation has a dramatic impact on the nature of the best solution to > the implementation problem; since the implementation of the inherited > operations and the implementation of the non-inherited operations are > mutually independent, the efficiencies which would have been realized > had the designer implemented all the operations together are sacrificed, > resulting again in time and space penalties. > > All I can say is that this doesn't happen much in practice. This can > certainly happen during rapid-prototyping, but it is easy to fix and > is unlikely to happen in a mature class library with a lot of abstract > classes. Assuming that an "abstract class" consists of a specification and not an implementation, this is blatantly obvious. Since my comments focused upon the inheritance of implementations, we must consider the impact of adding operations upon the efficiency of the implementation; generally, the impact is very dramatic. The representation that served us well when we were supporting a standard queue abstraction becomes disastrous when our standard queue becomes a priority queue. It is this immediate and total obsolescence of implementation which leads to problems when one attempts to inherit implementations. > Since the basic rationale behind software components is the exploitation > of economies of scale, it makes economic sense to seek an extremely good > (or perhaps optimal) implementation with little regard to development > costs; these costs are spread over thousands or millions of applications > and are generally trivially recoverable. Inheritance is a mechanism which > seeks to minimize development costs at the probable expense of utilization > costs, and is therefore something which is of little value to the developer > of software components, who seeks to sell his product into a market whose > economic characteristics are essentially those of a commodity market. > > This statement completely flies in the face of reality. The problem with > software today is not that it is too slow, but that it is too expensive > to construct. This is the problem with *application* software. One of the best ways to speed up the development of application software is to make extensive use of highly efficient standardized software components. When one is building a software component which is to be reused millions of times, the cost of construction will be amortized over millions of applications. The economics of the situation demand that the efficiency of the component be maximized instead. > 95% of the time, the people who are worrying about efficiency are > worrying about the wrong thing. We don't need to make our software > faster, we need to make it more reliable, And the best way to do this is to rely upon proven software components... > easier to use, By incorporating human factors specialists into the design team... > easier to change. By constructing software in a modular manner. > In fact, most software that is written is run on only a few machines. > Few programmers are writing software that will run on thousands of machines. Oh, but I beg to differ. A large and rapidly growing number of programmers are writing software in Ada, a language which is rigorously standardized, allowing one to write software which will run on any machine having a validated Ada compiler. This amounts to millions of machines. In fact, without this level of standardization, it is difficult to imagine a viable software components industry. > [..] inheritance is very important, and should not be casually discarded. Perhaps in the rare situations in which component development costs are more important than utilization costs, such as research situations; however, for the commoditized software components industry, in which standardized software components are reused thousands or millions of times in many different applications, inheritance (as currently defined) is simply an inappropriate development mechanism. Bill Wolfe, wtwolfe@hubcap.clemson.edu