Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!uxc.cso.uiuc.edu!uxc.cso.uiuc.edu!m.cs.uiuc.edu!p.cs.uiuc.edu!johnson From: johnson@p.cs.uiuc.edu Newsgroups: comp.lang.smalltalk Subject: Re: Processor objects vs. data objects Message-ID: <80500073@p.cs.uiuc.edu> Date: 4 Sep 89 04:10:00 GMT References: <57069@aerospace.AERO.ORG> Lines: 40 Nf-ID: #R:aerospace.AERO.ORG:57069:p.cs.uiuc.edu:80500073:000:2287 Nf-From: p.cs.uiuc.edu!johnson Sep 3 23:10:00 1989 Russ Abbot asks about classes that model procedures, not abstract data types. The best discussion I know on the topic is by Dan Halbert and Pat O'Brien in the September '87 edition of IEEE Software. It is called "Using Types and Inheritance in Object-Oriented Programs". One thing to note is that by "type" they mean class. In my opinion, a type is very different from a class, but that is about our only point of disagreement. In general, operations should be implemented as methods, not as classes. However, there are several places where it is reasonable to make them classes. One is where the operation is very complicated, were there are many ways to implement it, and where these implementations have a great deal of internal structure. For example, "compile" can be thought of as a method in class String that returns a compiled procedure, but nobody would ever do that. Compilers are complicated, and usually contain parsers, symbol tables, code generators, and many other parts. It is much more reasonable to make a Compiler class that represents an instance of an executing compiler. Smalltalk-80 does this. However, users almost never deal with the compiler directly, but instead ask classes to compile a string and install it as a method. The class will instantiate a compiler to do all the hard work, so we end up with both an elegant interface to the compiler and a nice design for the compiler. Another place where it is reasonable to implement an operation as a class is where you will want to reuse that operation for many classes, many of which are not closely related. For example, you might want to sort any kind of sequentiable collection, though contents of the collection have to have a comparison operation. Moreover, there are many different kinds of sorting algorithms, and it seems a bit odd to put every single one in the same class. It is probably better to define a Sorter class and to define the "sort" method as Sorter sort: self. If a particular sorting algorithm is needed then you can easily call it. Implementing operations as classes is the exception, not the rule. You should only do it when the alternative is worse. However, there are times when it is the best option. Ralph Johnson - University of Illinois at Urbana-Champaign