Sunday, May 25, 2008

Swing Does Components Better Than Component Libraries Do

I'm currently trying to get a handle on Macromedia Adobe Flex using the free, open-source Flex SDK. Flex is a set of tools to create flash-based "applications" using XML UI definition and Actionscript for everything else.

It seems that Adobe has adopted some Microsoft conventions for programmatic UI creation and management. In particular, components in Flex have a long and convoluted lifecycle. In Web Forms, I never understood why I shouldn't create child controls in my Control's constructor; Flex's UIComponent has a createChildren() method. I still don't know why I shouldn't create child controls in the constructor.

In my Swing programming, on the other hand, I don't seem to run across these problems. As far as I know, a Swing component has one and only one step in its initialization process - the constructor. That certainly makes things simpler. I don't have to wonder "What happens if I put this here?" or, more commonly, "Why does this thing not work? Oh, somebody messed up the initialization code."

Actually, most of my frustration here is directed to ASP.NET 1.1. Things may have gotten better in later versions (though I doubt it), and I don't really know how good or bad it is in Flex land. Still, this dredged up bad memories for me. Thick base classes suck!

Wednesday, May 14, 2008

Why Inheritance Is Bad

3D graphics programmers, if there are any that read this blog, are familiar with gimbal lock. The Wikipedia article makes an analogy to compass directions. If you tell somebody at the north pole to face south, which direction are they facing? You have no way of knowing, because south loses its meaning at the north pole. At any other place on the planet, your location and direction are completely independent. At the poles, direction has no meaning in the cartographic coordinate system. Two previously independent variables have now become linked.

In programming, when you derive from a base class, the classes are in a state of gimbal lock. We can vary the subclass as much as we want without affecting the base class. However, a change to the base class will not only affect our subclass, but every other subclass out there. Suppose that our base class provides some core data processing functionality, and its various subclasses encapsulate different data sources. So far, so good. We've managed to avoid duplication. If we come up with a new data source, we can simply create a new subclass. However, what happens if we want an existing data source to send data to a different set of processing rules? A class would need to have more than one base class, except in a way different from normal multiple inheritance. No programming language that I've seen can support this scenario.

A hallmark of good object-oriented design is that classes have one and only one responsibility. Why is this important? It makes the code simple, it makes the code testable, it decreases coupling, it might increase cohesion, and it's just plain nicer to read. When you derive from a base class, your class has all of its explicit responsibilities, and the responsibilities of each of its ancestor classes. In our example, each subclass is itself responsible for knowing the ins and outs of a particular data source. Since they all derive from a common base class, they are also responsible for knowing how to process the data. This example only deals with 2 responsibilities, but real systems deal with hundreds.

Remember that inheritance is often used to represent taxonomies. You might have classes such as Animal > Mammal > Giraffe or Widget > Button > Pushbutton. You might say that things on the right are defined in terms of things on the left, but that's not exactly true. A giraffe doesn't have lungs because it's a mammal; we call it a mammal because it has lungs. Using inheritance to describe something (using, for example, interface inheritance) makes a lot of sense. Using inheritance to define something doesn't.

Adventures with the Scriptaculous Ajax.Autocompleter

I had a chance to use the Scriptaculous autocompleter control at work the other day. Since we are using Ruby on Rails, it was easy enough to use text_field_with_auto_complete() to generate the relevant HTML.

The client noted that it was difficult to enter a new word if it was too close to an existing word. For example, he would type "expensive", and the system would suggest "not expensive". When he would hit Enter, it would replace what he had typed with "not expensive". This is because the Scriptaculous control doesn't support the case where no item is selected - one item is always selected, and it defaults to being the first item.

I decided to have a peek at the source code. In maybe 15 minutes, I had managed to convince it that "nothing selected" is a valid case. Unfortunately, I didn't refactor the code in any way - now every autocompleter behaves this way.

Scriptaculous uses prototype's Class.create() to generate 2 classes: Autocompleter.Base and its sole subclass: Ajax.Autocompleter. From the source code:

Autocompleter.Base handles all the autocompletion functionality that's independent of the data source for autocompletion. This includes drawing the autocompletion menu, observing keyboard and mouse events, and similar.

I appreciate their desire to re-use code. Unfortunately, the use of inheritance has caused the whole mess to suffer some sort of object-oriented gimbal lock. It's easy to create a new Autocompleter that gets its data from a different source; it's much more work to create an Ajax autocompleter with different behavior.

If I have some time (that is, when I'm not busy complaining about something), I might see if I can refactor the scriptaculous source to further separate the data source of an autocompleter from its interaction controller, using some method other than inheritance.

Tuesday, May 06, 2008

Ruby in LISP clothing

As it turns out, Ruby's syntax is somewhat flexible. As an example, parentheses are sometimes optional when calling a method.
puts "Oh hai!"
puts("Oh hai!")

link_to_remote "Go there", :url => { :controller => :there, :action => :go }
link_to_remote("Go there", { :url => { :controller => :there, :action => :go } })
The only time the parentheses are needed is when the invocation would otherwise be ambiguous:
link_to_remote h text, :url => { ... }
(h is the HTML escaping function. link_to_remote may actually automatically escape the HTML, but I'm not sure.)

Ruby can't tell what the user is trying to do. The normal way to fix this is to add some parentheses to the call:
link_to_remote(h(text), :url => { ... })
link_to_remote(h text, :url => { ... })
however, it is also possible to use LISP-like parentheses with the same result:
link_to_remote (h text), :url => {...}
(link_to_remote (h text), :url => {...})
Which is better? Certainly one of the first pair is more conventional. For some reason, though, I found myself migrating to the second pair. I suspect it's a combination of
  • I try to avoid using parentheses in method calls in Ruby as much as possible
  • LISP is awesome
  • I have done some Objective-C programming, in which you [object send:message]

Thursday, May 01, 2008

Consistency on Rails

The Ruby on Rails crowd makes a big deal about consistency. They claim that Rails is easy and fast for development partially because it favors convention over configuration. I guess the thought is that you don't need to write any configuration. Plus, once you've worked on a few Rails apps, you pretty much know where everything is.

So far, I've found a lot of that to be pretty much true. Migrations, routes, controllers, views, database configuration - there's a place for all of them, and they're pretty much exactly where I would expect them. However, I've often found myself struggling when actually writing the code. I'm either going to the documentation constantly, or even peeking in the Rails source. (It turns out that some options to methods aren't documented, and the rails plugins that we are using have poorer documentation than the core).

I only have 2 small examples at hand, but I could write about many more annoyances.
  • link_to and link_to_remote both seem similar on the surface. One will generate a normal hyperlink that will navigate the browser; the other will generate an AJAX link that will interpret the resultant response as either HTML to be embedded or Javascript to be executed.

    Both allow you to specify the url using :controller and :action. However, they have very different signatures, and it trips me up everytime.
    link_to "Help", { :controller => :help, :action => :sample }
    link_to_remote "Help", :url => { :action => :help, :action => :sample }
    Did you see that? The only difference between the two is that one requires the URL-related options to be packaged in a hash named :url, while the other disallows the hash
  • When using the form helper methods such as text_field and text_field_tag, you must be careful. Here is an example:
    text_field :post, :name <input id="foo_bar" name="foo[bar]" size="30" type="text" />
    text_field_tag 'post[name]' <input id="foo[bar]" name="foo[bar]" type="text" />
    As you can see, if you change from one to the other, you might need to also update you RJS files (or remember to set an explicit ID). This would have all been avoided if text_field had simply generated id and name attributes with the same value.
Rails certainly has its good points, but the small details are sometimes infuriating.