7.4. The Essence
So, Rails is not a toy, and it's not a gimmick. In my opinion, Rails represents a
significant advance in the state of the art. You've probably seen frameworks like
this one solve the database-with-UI problem in several different ways:
Object-oriented development frameworks are flexible and robust. They're
usually at a lower abstraction level, so they may not be as productive. You
can use them to create flexible, robust, and powerful applications, but you're
going to pay for it with productivity.
Quick compromise frameworks trade conventional wisdom and sound
design for implementation speed. PHP and Visual Basic, for example,
compromise by trading design wisdom (frameworks should encourage
separation of model and view logic) for development speed.
Code generation frameworks generate most of the code for such an
application at compile time. They trade the feedback cycle, easy
maintenance, and often, customization, for speed.
Customization point frameworks take a few parameters, like database tables
or models, and build default implementations with a few well-defined
anticipated customization points. These frameworks break down when the
inventor's imagination doesn't anticipate important hook points.
Rails is none of these. It uses macros to help you quickly generate code based on
the structure of the database and a few well-placed macros. Since you effectively
get generated code at runtime without tangled source code, you don't have to
maintain the added code. Rails avoids the trap of customization points through
Ruby's extensive hook points. You start with a clean design. You can then extend it
through subclassing, changing class definitions, or any of the other
metaprogramming techniques we discussed. You can even replace major Rails
components like Active Record.
Rails accelerates your development through meaningful conventions and defaults.
By guiding your naming strategies in the database, Rails can save you lots of
typing, and infer your intent by the consistent names that you provide.
relationships, and name mappings.
Rails may be the application that breaks the dam. Some of my mentors, like Stuart
Halloway and Glenn Vanderburg, speak often about the importance of these
techniques. By showing what's possible in Ruby, Rails may release a massive wave
of metaprogramming frameworks custom built for a given domain. If we do see
such a wave, it likely won't be in Java, because reflection is just too painful, and
the wild mix of primitives and objects simply makes it too cumbersome.
7.4.3. Final Thoughts on Ruby and Rails
To me, Ruby smells and feels like a good language, and Rails feels special. That
alone is not enough to make it succeed. In this industry, individuals often make the
difference, and the Davids (Thomas and Hansson) may be special enough to take
this language and framework into the mainstream. Dave Thomas is a tireless
promoter of all things pragmatic, and he seems to be focusing his publishing
business on Ruby. He's already locked down many of the top Ruby authors by
treating them well and providing a publishing experience that larger publishers
cannot duplicate. Printed books provide credibility and exposure that languages
need to succeed. David Heinemeier Hansson has a unique combination of a
technical vision, a flair for understanding the end user, and a zest for marketing
that you rarely find in one person. Rails is at once theoretically sound enough to
attract hard-core web developers, and approachable enough to attract the masses.
This kind of leadership often makes the difference between a successful
technology, and a good technology that failed or never hit the mainstream. You
don't often find technical passion and marketing vision wrapped up in a single
mind, but when you do, great things can happen. Bill Gates built Microsoft from a
BASIC shop operating out of a garage to the biggest software company in the
world. Steve Jobs made Apple cool, left, and came back to overhaul its image and
bring it back. Java, too, is full of technical visionaries. James Duncan Davidson
fought the bureaucracy in Sun to break servlets into the mainstream by open
sourcing Tomcat, and then did it again with Ant.
Java seems to be losing the visionaries and technologists that I respect the most.
the benefits, certain problems make it seem clunky and
awkward.
8.1.1. What You Want
Current web application servers might be powerful, but they're not convenient or
natural. So, what is convenient and natural? It shouldn't take too much effort to
figure that out. What if your controllers looked like this:
if (logon.show( ) = = true) {
mainPage.show( );
}
or this:
if (shoppingCart.verify( )) checkout.show( );
That's better. What you really want to do is encapsulate the presentation of one or
more web screens in a method. Then, more sophisticated page flows would not be
a problem. You could simply roll up more and more pages into higher-level
components. For example, you could take this code:
checkoutAddress.showForm( );
if(checkoutAddress.getSeparateBilling) checkoutBilling.showForm( );
creditCardNumber.showForm( );
and roll it up onto a method:
public static void showCheckoutWizard( ) {
checkoutAddress.showForm( );
if(checkoutAddress.getSeparateBilling) checkoutBilling.showForm( );
creditCardNumber.showForm( );
}
so the usage becomes:
cart.showCheckoutWizard( );
in its cleaner, refactored form. But you can't code that way, because your web
server won't let you. Creators of most web application servers will sell their soul to
keep things stateless and scalable.
8.1.2. Statelessness
unintuitive behavior. You've taken one more step back, away from the ideal. Once
again, this awkward Back button forces you to deal with things on a case-by-case
basis, and it just doesn't feel right.
8.1.4. Navigation
Web development in Java focuses an incredible amount of brain power around
navigation and flow . You'd think controlling flow from the server side would be
natural, but servers can't update clientsthey can only respond to requests. This
simple little truism forces servers to handle hundreds of little requests rather than a
couple dozen application flows. It's also hard to synchronize the user interface with
the model. You'd like to use a simple method call that controls the user interface
and model, but you can't. The web server just doesn't work that way. And you're
stepping back again, and you've got that sinking suspicion that there's a cliff behind
you somewhere.
8.1.5. Continuation Servers to the Rescue
A new class of web servers called continuation servers is starting to make some
real noise. A continuation server uses a programming construct called the
continuation to keep enough information about a request to be able to completely
reconstruct the context. In technical terms, a continuation saves the execution
environment, including the call stack. In practical terms, using continuations in a
web server lets the server maintain context for you, freeing you to program in a
more natural way.