development

Raw number of methods as a limit?

December 8, 2005 8:10:01.315

Elliotte adds another post to the "Humane Interface" debate - the quote below follows on from an analogy about which remote is easier to use (an example Steve Jobs gave when introducing Front Row) - follow the link for the picture and analogy. Here's the meat, IMHO:

More buttons/methods does not make an object more powerful or more humane, quite the opposite in fact. Simplicity is a virtue. Smaller is better. Do you want to go all the way down to the absolutle theoretical minimum? For a list class that's probably about four public methods (new, insert, delete, get). Probably not. That's too few, but 78 is way too many. 10-12 is ideal purely from human-interface concerns. (I'd say 7-8 except I don't think most classes can really get that small. Maybe it is 7-8 if we count all overloaded variants as a single method though.) 25-30 is sort of the outside maximum: roughly the most signatures you can fit on a single piece of paper so that the programmer can see the whole class at once without scrolling their eyes. If that still doesn't convince you, tomorrow I'll take another look at the Array class that started this whole brouhaha and show exactly how pointless most of those 78 methods really are.

Well, I'm going to have to refer back to this post for part of the argument. Instead of dwelling on Ruby though (with which I'm less familiar), I'll look at Smalltalk, class OrderedCollection. In a base image, there are 55 instance methods in that class. There might be more with more packages loaded; have a look at this post on extensions to see how that's managed.

Now, I'm pretty sure that Elliotte would dislike 59 methods as much as he dislikes 78 :) Some of this is an Apples to Oranges comparison though. To wit: there are methods in the Smalltalk class implemented for polymorphic reasons that would not be done the same way in Java. For instance: #inspectorClass lets the collection tell the system how the development tools should look at the object. I'm fairly certain that Java IDE's approach that problem differently.

Additionally, exception raising has been factored out to individual methods. For instance:

 

notEnoughElementsError
	self error: (#errRemovedTooManyCollection << 
	       #dialogs >> 'attempt to remove more elements than are
in the collection')


That's an exception that gets raised if we try to access past the end of a collection (on either end). An example:


removeFirst: numElements
	"Remove the first numElements elements of the receiver,
	and answer an Array of them.  If the receiver has fewer
	than numElements elements, create an error
	notification."

	numElements > limit ifTrue: [^self notEnoughElementsError].
	^self privateRemoveIndex: 1 to: numElements returnElements: true

In Smalltalk, there's a strong bias to make the object responsible for its own actions. So when you try to index past the end, the object itself raises the exception - it's not handled by deep machinery in the VM.

Elliotte says that 10-12 methods are "enough" and that past that, we get into bloat. Well, looking at class OrderedCollection, I'm not sure what he'd want me to pull out. I suppose he might consider #add:before: fluff, but it's a useful method - it allows me to add some object before some other object in the collection. There's a ton of convenience methods of that sort in the class. Would it be better to simply have #add:, and then force developers to write their own versions of all the convenience protocol in their own classes? Recall that in Java, I can't extend a class, so these new methods will end up in some utility class. Clean OO, that's not.

Smalltalkers - and I think Rubyists - look at this problem very differently from Java folks. The Java people seem to like sparse classes, but they don't seem to realize that sparse classes combined with an inability to extend leads to everyone creating their own set of utility classes. In Smalltalk, the useful protocol that people add tends to migrate up to the vendor over time. For instance, in VisualWorks 3.0, OrderedCollection had 53 methods. More interestingly, the abstract Collection class (Collection) had 40 methods in VisualWorks 3.0 - and has 51 now. What we seem to have a two very different approaches to the class design problem. I think the Smalltalk/Ruby one is better, because it favors putting code where it belongs. The Java approach implicitly favors lots of utility classes.

Update: Charles Miller adds some useful commentary.

Comments

Or worse

[ Troy Brumley] December 8, 2005 9:12:44.935

Comment by Troy Brumley

It keeps people duplicating code in their applications, not their classes. Java enables OO programming, but doesn't seem to foster it.

Incomplete analogy

[ Terry] December 8, 2005 9:53:54.284

Comment by Terry

The analogy comparing human interfaces is quite incomplete. First, by the same logic, an IDE would be too big if it has more than 78 classes. Well, we know how well that would work.

Next, in interface design one tries to limit the number of field and buttons on a page, not the total available in the application. The total in an application is a function of what the application must provide the user. So, by analogy, a well designed IDE permits class lists and method lists to be organized so the size of a list the developer must deal with is a subset of the total available.

The VisualWorks IDE is a good example of how organization assists the developer. If one looks at the smalltalk collection classes you will find that they are divided into lists according to functional types, i.e. Sequenceable or Unordered. Next, when one looks at a class you will see that the methods are organized into protocols that describe the type of service a method would provide. This is a great assist when you are not sure what you are looking for.

Facade pattern not used enough in VW -- creates large interfaces

[Jim Thompson] December 8, 2005 10:05:49.582

I've thought that certain areas of VW are missing Facades. An example is the mess around Fonts. How often do newbies to VW ask about how to use fonts. No one can just look at the implementation and tell what to do. The basic functions should be pulled into a single class. Which by the way would have a large number of methods in its interface

Fonts

[ James Robertson] December 8, 2005 10:36:53.977

Comment by James Robertson

Fonts are one of the bad spot in VisualWorks, to be sure. It's one of the older frameworks, and it has its origins in the time before vendors (MS, Apple, Unix/X11) were providing UIs. Over time, it's been hacked to support that. It's one of the things slated to be redone.

[] December 8, 2005 11:12:31.918

Wow--what a rediculous strawman the remotes are. Thank goodness the universe doesn't work on Steve Job's principals

Jeff Raskin - The Humane Interface: New Directions for Designing Interactive Systems

[Isaac Gouy] December 8, 2005 12:26:37.017

More buttons/methods does not make an object more powerful or more humane, quite the opposite in fact.
iirc Jeff Raskin argued in his book "The Humane Interface: New Directions for Designing Interactive Systems" that more buttons can make an object more "humane".

Fonts

[Jim Thompson] December 8, 2005 12:27:37.568

James, I brought that up not so much as you need to redo it, but the fact that if you did it, you end up with a fairly large number of methods in that type of class. I think it is easier to deal with a few well defined classes than a lot of small classes. Having to know how lots of small classes work together is more difficult and is a maintenance headache.

Comparing iPod with a remote

[Jop] December 8, 2005 20:43:26.760

I wonder how someone who likes the minimalist approach would design a remote? To play press: 0-0-0-1 To stop press: 0-0-0-2 To pause press: 0-0-0-3 etc. Hmmm...

Minimalist remote

[George Paci] December 9, 2005 13:04:30.914

Actually, a minimalist remote would have one button:

To play, press "1".
To stop, press "11".
To pause, press "111".
...