« January 2007 | Main | April 2007 »

February 16, 2007

Chapter 7: Ruby on Rails

Rails feels like just what it is, a reflective inspection and auto build (aka code generation) of a well designed Model View Controller connected to a nice implementation of Martin Folwers Active Record design pattern. I think the lession here isn't how great Rails is, but how much can be gained by following well designed patterns...

[This chapter is littered with syntaxical errors, and appearently Rails scaffolding writes different code than when the book was writen. Read carefully and watch the purals and you'll get through it. This chapter is also the most fun so far. Take Rails for a test drive.]


  • Install Rails

    • Starting a Rails Project

      • Generating a Basic Application
      • Running the Ruby webserver


  • Install MySQL?

    • Create a sample database and table

  • Metaprogramming (Wire the app up to a MySQL? DB)

    • Config the database.yml (yaml) file to work with your MySQL? database
    • Restarting the server

  • Generating the Model
  • Using the Application Console
  • Generating the Controller
  • Managing Relationships
  • Generating Scaffolding
  • First look at WEBrick and ActiveRecord?

    • Automatic properties
    • Association Management

      • belongs_to
      • has_many

    • Componsition
    • Inheritance * Modifying the Views * Modifying the Controllers



[Rails feels like just what it is, a reflective inspection and auto build (aka code generation) of a well designed Model View Controller connected to a nice implementation of Martin Folwers Active Record design pattern. I think the lession here isn't how great Rails is, but how much can be gained by following well designed patterns. Imagine if they implement ten or twelve of the other classic patterns that fit the web app model. Good reflection and the dynamic nature of Ruby help them implement these, but Groovy or any other language can benefit from the same treatment.]

February 7, 2007

Transformation: Ruby Smells

I keep hearing people say they couldn’t possibly use Ruby because it lacks automatic refactoring tools.


Marting Fowler tells us that Refactoring is the art and science of turning smelly code into good code, in small, incremental steps. Provably correct, by construction. Algorithms for giving your code a makeover without breaking it in the process.




I keep hearing people say they couldn’t possibly use Ruby because it lacks automatic refactoring tools.


Marting Fowler tells us that Refactoring is the art and science of turning smelly code into good code, in small, incremental steps. Provably correct, by construction. Algorithms for giving your code a makeover without breaking it in the process.


Some of these “refactoring” techniques are automatable. It seems Fowler and friends have stumbled on something real, something as big as OOP, almost. Thank you, Fowler and friends!


Refactoring is one of the first programming books that talks about the almost mystical act of writing code. It takes the process, exposes all the insides, revels in it, walks you line by line through oh so many little decisions that affect code quality. Most people talk about “architecture”. Refactoring talks about the idioms in the code we write every day. Real now-code, not planned someday-code.


It’s remarkable, really, that nobody talks about this. They leave all the so-called style choices to the programmer. Refactoring rubs our noses in the implications of our line-by-line style choices. Beautiful. This guy sounds like Kevin Reynen (Sidewalk Theory), I love him!


Discovering Refactoring



“Factoring”, sure, that’s a dictionary word. You can factor numbers, or polynomials. Factoring I know. Don’t know why you’d re-do it, though. What’s “re”-factoring?


I open the book. It says local variables are the root of all evil. Perhaps not exactly those words, but it’s the first discussion I stumble across. Local variables!? I plop down in a squashy armchair, outraged, to read more. I want to know if this guy is actually insane, or merely an idiot.


Horror sets in: he’s right. His explanation makes chilling sense. One of my cherished programming practices — caching intermediate values in local variables, as an inline performance optimization — is clearly demonstrated, before my very eyes in the squashy armchair, to be Evil. It explains why I have certain methods in my code base that keep growing and growing, and for reasons I’ve never been quite able to grok, the methods are unsplittable.


These big methods, they’re the Bad Places. The areas of the code base where I loathe to tread. Dark caves that grow more evil every time I visit them. Because add functionality I must, but the locals have threaded their way impenetrably through each function, spiderwebs that catch me and hold me.


The book shows me why they’re unsplittable, then gives me axes to split them. Sharp and precise tools. And the techniques make sense, right then and there.


I move on. Turning pages faster, now. Interested.


The book next tells me: don’t comment my code. Insanity again! But once again, his explanation makes sense. I resolve to stop writing one-line comments, and to start making more descriptive function and parameter names.


But the book is a landmark, and it made me a better programmer overnight. How often does that happen?



[Having found that others he surveyed haven't read it he confesses.] I’m safe. I can study it, use it, not worry that everyone will know how foolish my code has been.


Refactoring Today



Everyone knows about Refactoring nowadays, because IDEs now have all of the automatable refactorings from the book, and a few extras to boot.


But despite its overnight popularity, most engineers have read Fowler’s book, not even a few chapters of it.


Reprise



I keep hearing people say they couldn’t possibly use Ruby because it lacks automatic refactoring tools. This, people say, is a show-stopper.


I wonder.


I read Fowler. I absorbed it. It’s the art and science of taking smelly code and turning it into better code, in small provable steps.


But he taught us something else, didn’t he?


Oh, but you wouldn’t know what that thing is, if you haven’t read his book. Have you? All of it? No skimming? C’mon now. Admit it. You skimmed.


Here’s the deal: to show us the paths from bad code to good, Fowler had to show us bad code. He showed us examples of what it looks like, and explained why it’s bad. He gave us a set of warning indicators and even called them “Code Smells”.


How did that code get smelly in the first place?


Well, we optimized prematurely. We stored too many intermediate values, for fear of recomputing them. We didn’t write small functions, for fear of virtual method-call overhead. We made bloated class heirarchies for the imagined benefits of reuse...


We were making dozens, hundreds of little mistakes that added up to some pretty smelly code. The book catalogued our mistakes, gave them names, elevated them to First-Class Mistakes.


[Understanding the basics of refactoring] you know what bad code smells like, and you know how it got that way. You’ve learned how to avoid writing it.


At what point did automated refactoring tools become the focus? The book’s original focus was about design, with tools for recovery. Now the focus is all on recovery, and specifically on the automatable subset of recovery techniques.


The implicit assumption here is that bad code just happens, inevitably. His book wasn’t just a catalog of 100-odd specific refactorings. It also presented themes. Once you get the core ideas, you can invent your own refactorings, and identify new code smells.


And now you know better how to write the code better the first time around.


Refactoring is zoomed way in. It’s focused on how you personally wrote this or that class or method, down at the level where you were making choices about local variables, control-flow constructs, and other micro-design decisions.


Refactoring can’t really be discussed in a vacuum; it’s interdependent with other modern development ideas, including “don’t repeat yourself”, “once and only once”, unit testing, and others.


Push-button Productivity




Automated code-refactoring tools work on big set of entities — objects, methods, names, anything patterned. All nearly identical. You have to change them all in a coordinated way, like a caterpillar’s crawl, moving all the legs or lines this way or that.


How did our code get that way to begin with? We wrote it badly. Refactoring to the rescue. Good design may be a lost cause, but we can recover, because we have automated servants to go fix all those little segments for us. They never get tired, and all we have to do is push buttons.


Well then. How could you possibly live without automated refactoring tools? How else could you coordinate the caterpillar-like motions of all Java’s identical tiny legs, its thousands of similar parts?


I’ll tell you how:


Ruby is a butterfly.

February 6, 2007

Beyond Javas: Chapter 6. Ruby in the Rough

Java's leadership run, at least for applications, might be drawing to an end. This book points out one language and two frameworks (one in Ruby and one in Smalltalk) that have something special to offer. One possible alternative language, Ruby. It improves on Java, but that doesn't mean that Ruby will succeed, or that it's the best possible alternative. Dynamic Languages...

Java's leadership run, at least for applications, might be drawing to an end. This book points out one language and two
frameworks (one in Ruby and one in Smalltalk) that have something special to offer. One possible alternative language, Ruby.
It improves on Java, but that doesn't mean that Ruby will succeed, or that it's the best possible alternative.

About Ruby


Ruby is a dynamic, fully object-oriented language that's usually grouped with scripting languages. The scripting term, for
languages like Ruby, Smalltalk, and Python, is a little too limited, so I'll use the term applications language .
Install it and type along. It comes with a primitive IDE, but the command line works well.


Ruby Is Fully OO


From here, you can evaluate Ruby statements. You'll frequently use irb to answer those tiny questions that come up often in
programming.


You don't have to worry about primitives or wrappers at all. More importantly, you don't have to deal with those cases in an
API. Ruby's reflection, persistence engines, and XML frameworks are all much simpler, because you don't have to deal with all
the edge cases related to primitives and arrays of primitives.


Typing


Try to do an assignment without a declaration:if it works that's a strong hint that Ruby is dynamically typed. The type in
Ruby is bound to the object, but not the thing that contains it. So Ruby is dynamically typed. But Ruby won't break its
typing rules by coercing one type to another. That means Ruby is strongly typed. Actually, strongly typed is an
oversimplification. Since you can change Ruby types indiscriminately, some might consider Ruby to have weaker typing.
You've read that dynamic typing lets you focus on the right part of the problem at the right time. It eases your refactoring
burden, and reduces the amount of code that you have to write and maintain.

Conditionals


Ruby's conditionals will remind you more of C than Java. Ruby also has a few conventions that you should know about. ? and !
are both valid in method names. By convention, methods ending in ? are tests. For example, nil? would test to see if a value
is Nil. Methods ending in ! are potentially dangerous, because they have side effects. Ruby has an if statement. Ruby also
supports an unless statement that works the same way. You can use if or unless in block form, as you do in Java. You can also
tack them onto the end of a line, to conditionally execute a single line of code.


Looping


Ruby has two conditional loops. The loop continued until I entered the end-of-file character. Until, the other looping construct.


Ranges


Ruby supports first-class range support. Ranges introduce = = =, another type of comparison. Also third type of comparison,
called match, which you'll use with regular expressions .

Regular Expressions


Ruby builds regular expressions into the syntax. Some like regular expressions and others do not. They're a critical part of
dealing with strings. In Ruby, you'll define a regular expression between slashes.
Ruby returns the index of the character at the match. Ruby regular expressions are pattern matching, such as regular
expressions and ranges.

Containers


Ruby containers are like Java's collections. Everything in an array is also an object. Ruby uses a Hash. Like Java's HashMaps, a Ruby Hash is an object. Unlike Java's HashMap.


Like Java collections, Ruby containers hold objects, and they need not be homogeneous.


  • Since there's no distinction between primitives and other objects, you can put literally anything into any given container, and you can nest them easily.
  • Since everything inherits from object, everything has a hash code.
  • The language gives you the same syntactic sugar for hashes as for arrays.
  • Code blocks make iteration tighter and easier.

Similarly, you can use Hash whenever you need a set, dictionary, or any type of unordered collection. You'll find yourself
doing more with collections, and less customized iteration.

Files


Using Ruby Grep.rb you're effectively using a library that specifies everything on the outside of a control loop that
iterates through a file. Ruby does the repetitive dirty work for you, and you customize the inside of the control loop with a
code block.


Why Should You Care?


By now, you should be getting a feel for the power and simplicity of Ruby. You can probably see how the lines of code go down
and the abstraction goes up.

  • You still have to understand anything that your tools generate.
  • The more code you have, the more bugs it can hide. Unit testing can take you only so far.
  • Writing code is not the only cost, training, maintaining, and extending your code factor in also.
  • Each code generation technique that you use limits your flexibility.
  • Java developers rely increasingly on XML for configuration. Remember, configuration is still code. Developers from other languages often find Java's over-reliance on XML configuration annoying. Meanwhile, configuration in Ruby is usually clean

and comfortable.


With Ruby, you wind up building the iteration strategies into your containers and reusing that logic.
In dynamic languages like Ruby and Smalltalk, this programming strategy gives you tremendous intellectual freedom, both in
the frameworks that you use and in the frameworks that you build.

Applying Some Structure


Both Ruby and Java are object-oriented languages. Both support object models with single inheritance. Still, you're going to
see some differences between Ruby and Java:

  • In Java, the smallest application is a class. In Ruby, everything is an object, so you can evaluate primitives, expressions, code blocks, and scripts. They all are objects, and all are valid Ruby.
  • In Java, class definitions are static. In Ruby, you can modify your classes on the fly. When you see a class definition, if the class already exists, the new definition will modify the class that's already there.
  • Ruby supports mixins and Java does not. Think of a mixin as an interface, plus an implementation, that you can attach to a class.
  • In Ruby, everything returns some value, and that value is typed dynamically, so you won't see a return in the method definition.
  • In Ruby, method parameters and instance variables are not typed; but the instances themselves are typed.


David Heinemeier Hansson: Ruby - Creator of Ruby on Rails



David Heinemeier Hansson (DHH) is the programmer of Base-camp, Backpack, and Ta-da List under the commercial banner of


37signals,


  • Q: What are the three most important features in Ruby that you use in Rails?
  • DHH: First, meta-programming. You can manipulate a class while it's being defined. You can create domain-specific


languages, because you've got hooks everywhere into the life cycle of classes and objects... Second, open classes. Active


Record consists of around 10 layers that are all applied to the base class... Third, everything is an object, with


exceptions. You can work procedurally on top of the object orientation, but that's the order of business. It makes for an


incredibly consistent experience that really makes "The Principle of Least Surprise" come true. You can guess the names and


behavior of Ruby classes more often than not.


Classes


Ruby is object-oriented. In Ruby, instance variables start with @, class variables start with @@, and global variable start


with $. Ruby developers take advantage of open classes . You can change the class definition of an existing class. That's a


useful capability for debugging, iterative programming, and metaprogramming. Ruby also lets you subclass. To subclass, you


use the < operator. These concepts should look familiar to you. Classes package instance data and methods together. An


instance of a class is an object. All classes have single parents, and eventually inherit from Object, with the exception of


Object.


Using Mixins


To implement a mixin, Ruby uses a concept called a module. A module lets you group together methods and classes. You can't


instantiate a module, and a module doesn't stand alone. A module isn't a class, but it does have its own namespace. Modules


form the foundation of classes and mixins. Recall that a mixin is an interface with an implementation. That means you can


group together a set of methods that many classes may need to use. You can separate an aspect, or a capability, into a mixin.


What makes mixins so powerful is this: you can also access an objects class methods in your module. In fact, we used an
object propery in the module, before we had even defined the object.


Interceptors


With Ruby, interception is easy. You simply take a method, rename it, and put another method in its place


Aspect Oriented Programming (AOP)


AOP lets you add services to your POJOs without modifying any code. AOP helps you control the flow of your application, such
as adding custom methods at interesting points—for instance, before or after a method executes. In particular, you'll often
see AOP for:

  • Debugging or logging
  • Declarative services
  • Mixins

A standardized AOP framework has never really taken off in Ruby because the language itself already supports most of the
desirable functionality of AOP. The next version of Ruby will take this a step further by including AOP-like constructs right
in the language with pre, post, and wrap conditions. The meta-programming capabilities of Ruby lie so close to the surface
and are quite accessible to the average Ruby programmer. Most of the problems addressed by AOP are addressed by meta-programming in Ruby.
Of course, AOP is a much broader tool, and if it is successful, the typical use cases obviously will grow in scope and power.


For Ruby developers, AOP is not quite as urgent, because you've already got robust tools to deal with these kinds of concerns:


  • You can use interceptors. These let you add services to any object at any time. It's as easy as renaming one method and introducing another.
  • You can use mixins, even attaching them at runtime. You could easily make all of the methods on a domain model secure, for example.
  • You can use hooks . Ruby provides hooks so that you can inject custom code at certain well-defined locations. The next version of Ruby will support hooks called _ _before, _ _after, and _ _wrap.

In short, Ruby can already solve many AOP-like problems without AOP, and will add AOP-like features in the very near future.



Dependency Injection


The difference dependency injection in Java and Ruby is a little tougher to understand for Java developers. In Java,
dependency injection is rapidly changing the way that we build applications. It's a relatively simple concept:
A few things come up right off the bat when you look at dependency injection in Ruby. First, Java's not very good at
configuration, but Ruby lets you represent structured data quite well, often with far less invasive syntax than XML. You also
can solve many of the coupling problems by changing the definition of a class on the fly.
Some developers in Ruby seem to think dependency injection is important and that the idea will have a place in the Ruby
mainstream, given time. It should come as no surprise to you that Ruby has an outstanding dependency injection framework
called Needles.


Others tend to think that dependency injection should happen in spots, instead of with a single, general-purpose framework.
Since it's easy to change a class definition on the fly, you can easily inject the behavior that you need without adding
another layer of complexity, across the application. Most of the Ruby programming community seems to be converging on the
idea that Ruby's overall dynamic design makes dependency injection unnecessary for all but the most complex applications

Breaking It Down


Ruby makes some of the hard things in Java easy. More and more of the top independent consultants are looking for ways to make more money
working in Ruby, or other languages that are more dynamic. The Java community is spending an amazing amount of money and
brainpower on making Java more dynamic. Dependency injection and aspect-oriented programming are groundbreaking ideas for
Java, and they are only now getting serious commercial traction.

Collapsing Under the Weight of Abstraction?


As we stretch Java in increasingly unnatural directions,
there's a cost. AOP and dependency injection are near-trivial exercises in Ruby, but they force Java developers to learn new
programming models, deal with XML, and introduce increasingly complex syntax. With each new meta-programming concept that we
bake into Java, it's looking more and more like all of that complexity is trying to drive us somewhere. The net effect is to
push Java further and further into the enterprise niche, and make it less and less accessible to the average Joe. Contrast
that situation with Ruby, where dependency injection and AOP don't consume your focus; you're free to apply those ideas in
spots right where you need them.

Scott Gu's Blog: ASP.NET AJAX 1.0 Released

Microsoft extends the Common Type Library to the client-side. This provides cross platform, cross browser support for a core JavaScript type-system, JSON-based network serialization stack, JavaScript component/control model (Observer Pattern), as well as common client JavaScript helper classes.

Microsoft extends the Common Type Library to the client-side. This provides cross platform, cross browser support for a core JavaScript type-system, JSON-based network serialization stack, JavaScript component/control model (Observer Pattern), as well as common client JavaScript helper classes.


The majority of controls within the ASP.NET AJAX Control Toolkit leverage the "Control Extender" pattern that the core ASP.NET AJAX library introduces, and which delivers a super powerful way to easily enable specific AJAX scenarios on a site with minimal effort.


They have released the source code and I'm guessing if they have done anything novel here that the Ruby on Rails folks will stop it and release their equivalent functions.


They are promising that all of the ASP.NET AJAX 1.0 features will be integrated directly into the next release of ASP.NET (codename: "Orcas"). Visual Studio "Orcas" will also provide client-side JavaScript intellisense, JavaScript compilation checking, and rich JavaScript debugging support for ASP.NET AJAX scenarios. It is my opinion that this should have been included form the start of .Net Visual Studio .Net. I can't tell you how many times I've had to instruct people that you can get client-side debugging from Microsoft through its Script Debugger. So it's the typical "update to our latest stuff and you'll get some new stuff the open source people have been doing for the last 6 months, but this time it will be integrated and you'll have the pleasure of having to buy it, instead of it being free like it used to be.


[Whew! got a little ranty there!]


But this release will bring Ajax to the masses.

Sizing Up .Net 3.0 Windows Presentation Foundation (WPF)

Extensible Application Markup Language (XAML) by Microsoft is a declarative XML-based language used to define objects and their properties, relationships and interactions for Windows Presentation Foundation (WPF). ...


Personally, my thoughts are, "Microsoft released the .Net 2.0 framework about the same time Web 2.0 was really peaking and they COMPLETELY missed it"... It had to be a major embarrassment for them. Now it looks like they are...

Extensible Application Markup Language (XAML) by Microsoft is a declarative XML-based language used to define objects and their properties, relationships and interactions for Windows Presentation Foundation (WPF).


XAML is used extensively in the .NET Framework 3.0 technologies, where it is used as a user interface markup language to define UI elements, data binding, event binding, and other features, and in Windows Workflow Foundation (WF), in which workflows themselves can be defined using XAML.




Personally, my thoughts are, "Microsoft released the .Net 2.0 framework about the same time Web 2.0 was really peaking and they COMPLETELY missed it." Naysayers note: implementing call-backs wasn't enough. It had to be a major embarrassment for them. Now it looks like they are on the heals of the latest outmoded technology, XML configuration. While improving productivity, it shoots for but misses the power and productivity enhancements that UI and frameworks folks who are working with dynamic languages are already achieving or on the verge of achieving. Hopefully they are watching and will jump on the trend quickly. With the recent release of the ASP.Net AJAX I'm guessing they are keeping an eye on the moments in the Ruby on Rails space. Most of the people I've talked with have either moved to some vendor like Telerik or Component Art, AJAX.Net (which has this supreamly sweet reflection-to-client-event-automation thing going on), or some home brewed AJAX. I will use the Microsoft AJAX controls in solutions, but they have taken no steps to differentiate themselves or take a leadership role with this offering.

February 1, 2007

Chapter 5. Rules of the Game

The premise of the book: conditions are ripe for an alternative applications programming language to emerge, because Java is abandoning its base. I'm not going to pretend to know what's next. Hopefully, I'll lay out some interesting languages and frameworks that have promise. This chapter, then, suggests the characteristics that the language should have to have broad commercial success.

The premise of the book: conditions are ripe for an alternative applications programming language to emerge, because Java is abandoning its base. I'm not going to pretend to know what's next. Hopefully, I'll lay out some interesting languages and frameworks that have promise. This chapter, then, suggests the characteristics that the language should have to have broad commercial success.

5.1. Java Raises the Bar


Each new language is subject to the rules of its time. Changes in standards force the industry to retool. Every language leaves behind a legacy. Sometimes, changing languages embrace the legacy.

  • Portability - Java introduced a virtual machine. The next major applications language will almost certainly support a virtual machine.

    • Security
    • Portability
    • Extensibility
    • Interoperability



The next commercially successful language should have a version that runs in the JVM.


Dion Almaer: Why Java Will Be Hard to Replace... "You are saying I should bet my Fortune 500 enterprise on a Japanese Mormon named Matz?" ...Don't get me wrong... I want the industry to move to languages that are more dynamic. I think we need to...but I am skeptical.


  • *Internet Focus*- Enabling applications for the Internet has become the most important problem that a business solves...

The Internet has at least two dimensions: interfaces for computers, and interfaces for people. ...users are just beginning to understand that HTML is not enough... [its] broken in fundimental ways...

  • Interoperability - Interop on the Internet will undoubtedly play a critical role. I think that leads to three important capabilities:

    • XML and structured data - Java doesn't let you declare nested structured data very well. In Java, you see a proliferation of XML, even where it offers little tangible value. The next language should let you declare and express structured data, cleanly and natively.
    • Service-oriented architecture (SOA) - A common structured data format is not enough to bridge two languages. You also need a communications mechanism. Build loosely coupled services, available on the network, and let them communicate with simple messages, with an XML payload. It's a good strategy for interop, for many reasons:

      • SOA works best with coarse-grained architectures, or calling big chunks of code. Interop between languages is a coarse-grained problem.
      • SOA is hot. Since it's politically popular, support and mindshare will likely remain high.
      • SOA uses Internet standards. That means you can leverage existing infrastructure, like security and existing message protocols.



A lighter form of web services, called REST, may last unlike the current SOA implementation. REST stands for Representational State Transfer, and it promotes using services the way Internet sites have used them for years. Like the Internet, REST views the network as a collection of resources rather than a collection of methods

5.2. Enterprise Integration


The next major applications language will not initially have to have the full enterprise capabilities to succeed. That said, some enterprise capabilities will be very important.

  • Database Integration - Minimally, a new language should access relational databases in a natural, productive way. I

    • Embrace the relational database
    • Don't force structure on the relational database
    • Perform, and scale

  • * Transactions and Security* - Enterprise developers need the ability to define a business transaction

5.3. Generating the Buzz


Many languages have trumped Java technically, but they still failed. The biggest factor of the equation is social. Without a credible community, there can be no success. To a programmer, a language is an investment in a future, and even an identity. Call it marketing, or buzz, or even hype. If it's hip, or at least interesting, a language stands a fighting chance. If not, there's no chance at all.

  • Open Source - Unless it's a disruptive technology, it's hard to imagine the next major programming language coming from a larger commercial vendor. A new language will need an attractive community to succeed, and the open source community seems like a natural place for that to form.
  • Economics - You can't move away from Java without economic justification. The leading potential economic catalyst is clear—an overwhelming advantage in productivity.
  • Approachability - When you look at early adoption for all major successful languages, one of the key issues is approachability. New languages need to grab new users quickly. You should be able to get started quickly, and solve a problem that's important to you immediately.
  • The Killer App - Without some kind of catalyst, it's difficult to imagine how a successful community ever gets started, a catalyst. The killer app is a seductive idea, because it encapsulates so many important concepts:

    • The catalyst, with economic justification, often takes the form of a killer app .
    • Once a solution is technically viable, a killer app enables a rapid growth to critical mass.
    • The killer app often initiates the hype that's required to escape a niche. With the newly found hype, the language can explode from a small, focused niche to a more generally successful language.



5.4. Language Features


  • Dynamic Typing - To be sure, static typing does have its advantages:

    • Static typing enforces typing rules at compile time, when they are least expensive to fix.
    • Static interfaces make it easier to enforce a protocol across important boundaries.
    • Static typing catches some types of subtle errors at compile time, like the misspelling of a variable name.


Still, there's a related cost, usually in productivity.

  • Code Blocks and Continuations - The Java open source community now uses anonymous inner classes with greater and greater regularity. When you need lightweight callback-style functionality, in Java the best way is the anonymous inner class. Code block show up frequently. Continuations will also be important.
  • Rapid Feedback Loop - Think of a feedback loop as the time between making a change and seeing the impact in running code. New application development principles, like test-first development, work best with a fast feedback loop.
  • User Interface Focus - User interface development demands more than Java has to give. For most application developers, the framework should do much more for you.
  • Dynamic Class Model - Dynamic, and reflective.
  • Sound Foundations - Java's successor will probably be object-oriented, and will be theoretically purer than Java. Especially when you start to consider meta-programming, simplicity, learning curves, and increasing processing power. * Transparent persistence frameworks need only deal with objects and collections.

    • XML binding frameworks would have a cleaner API, and a much cleaner implementation.
    • Debugging frameworks like loggers could easily print values of any parameters.
    • Consistency is important, too. Languages with consistent naming and consistent behavior are far easier to learn.


A Few Potential Suitors


  • Perl - Perl is a scripting language, with a quirky syntax and a turbulent past.

    • Like - If raw productivity is your goal, perhaps Perl is a possible answer. It's dynamically typed, is highly productive, and has a small community established. It also has a fanatical following.
    • Don't like - A write-only language: with its cryptic syntax, you can easily produce code that's very difficult to understand and maintain. Perl's OOP syntax, is bolted on and awkward.

  • Python - A dynamic programming language with goof syntax and power, and it supports the language features that you'd want.

    • Like - Dynamic typing, a quick feedback loop, and a concise syntax. It's pretty fast, and it has a version that runs in the JVM.
    • Don't Like - Not object-oriented enough. Python depends too much on white-space. Python community aren't happy with the web development tools. At times, it's too academic and too defensive.

  • Ruby - Ruby is an object-oriented language. The Ruby community grew steadily, and gained popularity only in the last couple of years.

    • Like - Ruby has a terse and readable syntax. It's highly dynamic. Ruby has strong web frameworks, and good support for XML and web services. Ruby has a couple of popular emerging frameworks, like Ruby on Rails. Most importantly, Ruby may have the killer app in Rails.
    • Like - Ruby has an embarrassing lack of commercial backing. Its relatively small community shows in the dearth of niche frameworks. The JVM support is immature.

  • PHP - PHP is a scripting language. With PHP, you effectively start with HTML, and mark it up with tags that can tie your application to a database, or other back-end systems. The tags get interpreted on the server, which returns pure HTML to the client.

    • Like - PHP success seems to be ramping up sharplyit's very well suited for its "sweet spot," controlling database access from a web page. It's easy to understand and easy to learn.
    • Don't like - The model tightly couples the user interface and database together. PHP grew rapidly and haphazardly with a heavy Perl influence

  • C# - C# is effectively a Java clone. It has many of the same benefits and drawbacks. Microsoft will always have a core set of developers. That's effectively a closed ecosystem, though.
  • Smalltalk - A well-established, hard-luck object-oriented language. It's hugely productive, slightly awkward, and quirky to the extreme.


No Silver Bullet


You may have noticed that no language has all the characteristics we're seeking. That's not surprising. If one did, we'd be using it by now. Still, you can see that these languages do establish real strength in important areas.

Patterns Of Enterprise Applicaton Architecture (by Martin Fowler) Chaper 1 and 2

Chapter 1: Layering
Most common technique to break apart a complicated software system. Layers is the cake analogy for software. Each layer rests on a lower layer. Higher layers use services of the lower layers. Lower layers are unaware of the higher. Layers hide layers beneath them.

Chapter 2: Organizing Domain Logic
Simple logic doesn't require decomposition and can be done in a "Transaction Script". But complex logic is where objects come in, and handle this problem with a "Domain Model", primarily around the nouns of the domain. Logic for handling calculations and validations are placed in the model.


Chapter 1: Layering


Most common technique to break apart a complicated software system. Layers is the cake analogy for software. Each layer rests on a lower layer. Higher layers use services of the lower layers. Lower layers are unaware of the higher. Layers hide layers beneath them.


Benefits of Layers


  • Allows you to understand a layer as a coherent whole, indepentant of others
  • Layers are substitutable with altenative implementations
  • Layers provide good boundries for standardization
  • Layers minimize dependancies between them
  • Layers promote reuse by higher layers

Downside of Layers

  • Layer encapsulation misses some things
  • Extra layers harm performance

These make for some tough choices.

Evolution of Layers in Enterprise Applications


Domain logic: business rules, validation, calculations, and the like created the need for layers. Object Oriented languages allow for this. Creaing UI, domain logic, and data source layers. The web and java re-enforced that layers could run on various machines, and largely psuhed the domain logic of the client.

The Three Priciple Layers


  • presentation - handling interactions between the user and the software
  • domain - the work the application needs to do for the domain
  • data source - logic communicating with other systems that carry out tasks (databases - persist data)

Note: Alistair Cockburn presents a different model - the Hexagonal Architecture. (core surrounded by interfaces to externals)
How to separate the layers in the cake model depends on how complicated the applicaton is.

  • Layers

    • Classes

      • Packages



Layers will help you enforce dependancies. Domain logic can be difficult to recognize.

Choosing Where to Run Your Layers


Dividing a system into separate pieces helps reduce coupling. Even if they all run on one machine. Usually your chouce is between ease of maintenance and responsiveness.


Data almost always runs on a server, unless a duplicate is localized for mobility.


Interfaces requirements usually dictate the UI location. Generally Web if you can, Rich if you must. But people are quickly finding ways to do things on web interfaces that this will likely become a non-question in a few years.


Chapter 2: Organizing Domain Logic


Simple logic doesn't require decomposition and can be done in a "Transaction Script". But complex logic is where objects come in, and handle this problem with a "Domain Model", primarily around the nouns of the domain. Logic for handling calculations and validations are placed in the model. Each object in this model forwards part of the behavior to another until a strategy object creates the results.


Adding new logic, increasing complexity, and the Domain Model will stay well-organized. Complex logic will increase the complexity of your data mapping however. The Domain Model works with the "Data Mapper"


Another option is the "Table Model", it is designed to work with the "Record Set". It organizes domain logic around the tables. But limits flexiblity in OO handling in your applicaton.

Making a Choice


Depends on how complex your domain is. Others hit the wall of demished productivity as complexity rises. Domain Model however doesn't. Once the decission is made it is hard to change. The chouce need not be exclusive either.

Service Layer


Splitting the domain logic in two. "Service Layer" over a "Domain Model" or "Table Model". This provides a clear API and place to contain logic of tansactions and security. Behavior can be weighted as needed between the Service Layer and the Domain Model. Models with the weight split tend to be use-case controllers. Fowler recommends very thin facade Service Layers if they are used at all.