Archive for the 'Java' Category

Producing and maintaining high-quality code

Wednesday, April 26th, 2006

So much bad and ugly code is being spewed out every day all over this planet that entire websites are dedicated to the preservation of the worst specimens. In this post, I will show you simple ways to produce and maintain high-quality code because, firstly, this is one way of achieving Internet stardom that you probably want to avoid and secondly and more importantly, you know how painful it is to have to maintain bad code.

I will start by a disclaimer, using Douglas Adams words:

The problem with designing something completely foolproof is to underestimate the ingenuity of a complete fool.

You can follow all the tips in this post and still end up with bad code, but you would have to be a very crafty fool!

1. Understand the problem

If this sounds like a duh-ism, that is because it is one. If you do not understand what the code is supposed to do, you will not get it right. Before you start coding, whether you face a blank sheet or whether you are maintaining code, sit down and think: what problem am I trying to solve here.

2. Write unit-tests

I could almost have numbered it 1bis. Unit tests show and validate how the code is supposed to be used. Write the tests first if possible — unless you can get your hands on a time-machine, this is not an option when doing some maintenance. The quality of your interfaces will improve dramatically because you will design them from their user’s point of view.

3. Talk to your cardboard friend

How many times were you stuck on a problem, decided to seek help from a nearby colleague, explain the situation and bingo! the solution became obvious. Your colleague hasn’t even had time to pronounce one word, he probably didn’t even understand the question. Articulating the problem solved it. My nearby colleague calls this the “cardboard friend” because people drawn on cardboard tend to have the property of listening without interrupting.

4. Enforce a coding standard

I previously wrote about this but just in case you missed it: you need a coding standard to make your code homogeneous because reading code is hard enough, you do not need the distraction of multiple coding styles. Once you have a coding standard, use tools to enforce it. In Java, checkstyle rocks and if you use eclipse, be sure to check out this plugin. There are similar tools in most languages, use them! At first configure them to be a complete and utter pain and then relax the rules you believe are damaging.

5. Use code analysis tools

Use any tool you can find to study and analyze your code. If the language you are using is compiled, turn on all warnings on the compiler: use -Wall when you use gcc, open the preferences in Eclipse and activate most warnings for the Java compiler (be pragmatic). Use any lint-clone you can put your hands on for your language. Here are the tools I recommend for Java: JDepend to measure the quality of my abstractions and to avoid cyclical dependencies, PMD to identify potential bugs and potential optimizations, FindBugs to (coincidentally) find bugs. I should mention Checkstyle again since it can also detect bug patterns. The situation is simple: the more code analysis tools you run on your code the more you will be able to fix problems before they bite you.

6. Use a continuous integration system

I will unleash my secret finishing move on the next guy who tells me: “but it works on my machine”. A continuous integration system is a referee. If the ref says the build fails because it is broken or because some test fails, it’s because it is. So, go fix it. The ref is always right even when “it works on my machine”. How does it do that? At regular intervals, it tries to build the latest version of your code and if anything goes wrong, it fires notifications — generally emails — to whoever is concerned. Receiving these notifications is not such a bad news: you have identified a problem in your code. Use your continuous integration system to run the code analysis tools and fail the build if these tools report problems. You can use CruiseControl, AntHill, DamageControl or write your own with cron+make+sendmail, but please use a continuous integration system.

7. Write less code

Aspire at writing code like a Zen master writes a Koan:

Monk: Does a dog have Buddha nature or not?
Zhaozhou: Wú.

There are two principles to assist you in your quest for minimalist code: KISS and DRY. “Keep It Simple Stupid”: do what is required and no more. Focus on a clean and simple implementation. “Don’t Repeat Yourself”: avoid duplicating code. Refactor mercilessly. This will decrease the size of your code-base, which is a Good-Thing™ because the less code you write, the less bugs you write.

8. Performance is overrated

I will probably have a contract on my head after this point, that’s what blogging is about, no? Writing fast code is a two step process:

  1. get the code to work,
  2. stop.

In case this was unclear: do not optimize the code. In the vast majority of cases, the code you are about to optimize is not a bottleneck. Use a profiler on a system running realistic data and identify the bottlenecks. Only then can you start working out how to eliminate them. Very often you will not have to change a single interface, only the implementation will require changes.

9. Read, read, read

Read books about software development. You must read the GoF book about Design Patterns and put it to good use. You must pick up Martin Fowler’s Refactoring, Code Complete by Steve McConnell. There are countless others. One of the first book to really open my eyes on developing good code was Writing Solid Code by Steve Maguire.
Read books about other programming languages too, you will frequently discover programming concepts that you might be able to port to your environment.

10. Use common sense

Common sense is your best friend to beat bad code and it’s free! Common sense is what dictates the previous nine points.

I hope you found these tips interesting and entertaining too! I am looking forward to your comments. I leave you with Zhaozhou to conclude this post: Wú!.

technorati tags:, ,

Advertisements

The Panda Principle

Wednesday, April 5th, 2006

A few years back, I read “The Collapse of Chaos: Discovering Simplicity in a Complex World” by Jack Cohen and Ian Stewart. As a popular science addict, I thoroughly enjoyed this book. I particularly remember it for introducing me to Stephen Jay Gould’s Panda principle. All of us have seen the Panda’s principle in action, yet few of us know of it. The following lines will, I hope, shed some light on this principle. I will start by exposing how it came to be discovered. Then I will look at a couple of typical examples to show that it reaches beyond biology. Finally I will explain why the Panda principle is relevant in the context of this blog — because for a couple of paragraphs, you will wonder.

The Panda’s Thumb: Survival of the Fit-ish

In “The Origin of the Species“, Charles Darwin popularized the concept of natural selection. Here it is, summed up by the man himself:

I have called this principle, by which each slight variation, if useful, is preserved, by the term of Natural Selection.

Contrary to popular belief, Darwin did not coin the phrase “Survival of the Fittest”, Herbert Spencer did when he applied Darwin’s theory to human societies. This phrase suggests that only the cream of the cream thrives, the rest being condemned to extinction.

Enter the panda.

Check out this thumb! How could such a poorly formed appendage be the result of millions of years of natural selection. Should it not be the best possible thumb to manipulate bamboo shoots? Stephen Jay Gould answers this question by observing that pandas might have evolved better thumbs but their current thumb is good enough — and sufficiently widespread among the panda population — to prevent improved thumbs from being a selective advantage. He named this the Panda Principle. As Cohen and Stewart put it:

Evolution leads to the occupation of niches by locally optimal creatures, not by globally optimal ones.

In effect, once locally optimal creatures get a foothold they prevent globally optimal ones from occupying the same niche.

The Panda Principle in action

The Panda Principle manifests itself in a wide range of domains. Stephen Jay Gould uses the example of keyboard layouts. Christopher Sholes, an early typewriter inventor, realized that his original design suffered from one problem: fast typists would frequently jam the type-bars. He had to slow them down. He came up with the QWERTY layout by trial and error in 1873. It is fair to say that QWERTY is a slow-ptimized layout! That hardly makes it the most efficient design for today’s usage where RSI sufferers’ fingers are the only thing that can actually jam.

In the 1930s, Dr. August Dvorak found that virtually any random layout leads to faster typing speed than the QWERTY layout — Sholes had worked hard to reach this (global) minimum. Dvorak invented the Dvorak layout — I am sure the amazing and unlikely coincidence is not lost on you. Throughout his life Dvorak fought unsuccessfully to get his layout adopted. He died a bitter man in 1975. Sadly, the man had a point: in every single comparative study, the Dvorak layout proved faster, more comfortable and less error-prone. There is still a community of Dvorak layout users, most of them programmers who have decided to use the fittest layout. But by all account, the QWERTY specimen is here to stay. It might well be the least fit specimen in the keyboard-layout-space but it will not be replaced any day soon. A perfect example of the Panda Principle in action.

At first, I thought the Betamax v. VHS war was another manifestation of the principle. I had it all typed and it looked promising: “despite Betamax being superior to VHS in technical terms — and being the Simpsons’ favourite videotape format — it lost the war”. Then I discovered that the original Betamax tapes were only one hour long, whereas VHS would stretch up to 3 hours long. In hindsight, this is a huge argument against Betamax’s fitness. As it turned out, in the videotape space, fitness is strongly correlated with the record-ability of hollywood movies. Hardly a good example to illustrate the Panda Principle.

Panda sighting #1: Smalltalk

Now, you must be wondering where I am going to with this principle and what is the link with this blog. Well, I have recently stumbled upon two manifestations, or so I believe, of the Panda Principle in the realm of software development.

The first one was a couple of weeks ago when I decided to pick up a Smalltalk book from Stéphane Ducasse’s collection and learn the language. Smalltalk is a fascinating and beautiful language. It was destined to be the next best thing. Then came Java. We all know what happened next.
The more I read about or play with Smalltalk, the more I wonder how Java won the match. It seems to me that Smalltalk had everything Java does and much more — yes, I am once again talking about metaprogramming, but there are so many other aspects. The two most common arguments to Java’s dominance are:

  • Java was an incremental step from C++. Whereas Smalltalk was influenced by the far less popular Simula and Sketchpad. It was therefore easier for Java to gather momentum as it appealled to a larger audience
  • Sun made the JDK available for free. Smalltalk development kits where expensive and more often than not incompatible.

Both arguments seem to forget that at the beginning, Sun envisaged Applets as being Java’s spearhead. Ironically, Java only really took off when people started using it on the server side.

What surprises me is the impressive list of contributions the Smalltalk community made to the Java community. Take Eclipse, arguably one of the most successful open-source Java project. Eclipse was originally derived from IBM’s VisualAge Micro Edition. VisualAge, up to the Micro Edition release, was Smalltalk based. As Joe Winchester puts it

From a technology point of view Eclipse has a lot of Smalltalk DNA in it.

Take the JUnit framework, written by Erich Gamma and Kent Beck. It has inspired countless testing frameworks in virtually any programming language. Well, JUnit actually had a precursor: SUnit, also written by Kent Beck.

Martin Fowler’s classic “Refactoring: Improving the Design of Existing Code“, although not a pure Java book, is on the bookshelf of most Java programmers (go buy it if is not!). The foundations of this book lie in Smalltalk as Fowler acknowledges in the preface.

It is hard to conceive that a language so ahead of its time and yet so simple failed to overcome the challenge of what seems a less evolved language. Moreover, Smalltalk had been preparing since 1971 for the advent of OOP‘s widespread acceptance. Java’s inception, on the other hand, only dates from 1990. When C++’s dominance came to pass, how did the fittest lose to the slightly fitter? Is this another manifestation of the Panda Principle?

Panda sighting #2: Mac/OS X

I have always been curious about Operating Systems and more particularly OSes for personal computers. I still remember my Pentium-75 triple-booting OS/2 WARP, Windows 95 and Linux. For quite a few years I have been a proponent of Linux and FreeBSD. I rarely use Windows, I get rashes and spots when exposed to it for more than a couple of minutes.

But lately, through the Ruby and Io community, I have been frequenting a bad bunch: Mac users. I heard so much about the Mac that I decided to have a closer look. I looked a bit too close. Here I am proud owner of a brand new iMac. I have been using it for less than a week and I have no doubt: this is the best machine I have ever had the pleasure to work with. My wife used to complain about my excessive usage of computers. Now, we are almost fighting about whose turn it is to use the Mac. I thought it would take me a while to get use to the Mac idiosyncrasies. After only a couple of hours, I feel pretty comfortable with the interface. Not only is it gorgeous, it is also far more comfortable and consistent than most systems I have used in the past.

A typical example of consistency is the key bindings. No matter what application I use I know command-F will let me search whatever this application manipulates. Compare that with Windows, ctrl-F is used by most applications but not all: see for yourself, try it in IE. It actually opens a side panel to let you search the web. If you look in the main menu, you will discover that ctrl-F is indeed the binding for searching into the current page… and sometimes it does — let me know if there is a cartesian explanation for this infuriating behaviour. The problem also exists in Gnome and KDE. It tends to be related to non-native applications like X-based ones.

But let’s go back to the Panda Principle, nobody can dispute Windows dominance in terms of marketshare. It is however hard to fathom how Windows could be considered the fittest OS for personal computers. I am talking fitness in the market space, not fitness in my own little OS fanatic space. Since I work in computers, I tend to get called by other people to fix their computers. I am pretty sure this resonates with your own experience. Are these people masochistic? How much pain can they endure? That repeatedly? Microsoft is losing the trust of its own customers. This has been going on for quite a few years, and yet only few people switch to alternatives. And there are many viable alternatives! I think this is a typical manifestation of the Panda Principle. Windows might not be the fittest but the shear number of users virtually guarantees that it will keep its place.

That is fine by me. I am quite happy with my very own globally optimum machine!


A bit of help to spread the word on Digg or Reddit would be very much appreciated!

RubyBeans revisited

Monday, March 6th, 2006

I have refactored the Rubybeans, a short example of Ruby metaprogramming code to make better use of Ruby’s metaprogramming API. I would recommend reading the original post to get the background information (in short: developing JavaBeans is a repetitive task that would greatly benefit from metaprogramming, RubyBeans are an illustration of how this would be done in Ruby). Since this post is also intended for developers not familiar with Ruby, I have tried to be quite verbose while explaining the code.

Buckle your seatbelts! Here we go:

class RubyBean
  def initialize
    @listeners = []
  end

I have just declared the RubyBean class. The initialize method is called everytime a RubyBean is created. It initializes the listeners instance variable to be an empty array. In Ruby, instance variables are preceded with @. Note that, instead of using [], I could have used Array.new. The square bracket notation is more commonly used in Ruby. In case it isn’t obvious, the listeners array will contain the property change listeners registered on this RubyBean.

Now, I add two methods to manage the listeners: one to register a listener on this bean, one to unregister a previously registered bean.

  def register_listener(l)
    @listeners.push(l) unless @listeners.include?(l)
  end

  def unregister_listener(l)
    @listeners.delete(l)
  end

In register_listener method takes one parameter l, the listener to be registered. Its code is almost plain english: push the listener at this end of the list of registered listeners, unless it is already there. The unregister_listener method is even simpler: remove the given listener from the list of registered listeners.

The code so far hasn’t used any metaprogramming features. But things are about to change!

In what follows I define a property class method. It is intended to be used by RubyBean subclasses to define their properties. For every argument it receives, the property class method will add 2 methods to the current RubyBean subclass: a getter and a setter.

  def RubyBean.property(*properties)
    properties.each do |prop|

In Ruby, a class method is defined by using the prefixing the method name by the class name: def RubyBean.property (this is equivalent to Java’s static modifier when it is used before a method). The *properties notation lets me capture a variable number of arguments as an array. The first line of the body loops through each element of this array. The name between the pipe characters is the name of the variable used to hold the current element in the block. For the time being, you can consider a block to be akin to an anonymous inline function. Blocks in Ruby come in two flavours do |param, other_param|... end and { |param, other_param|... } (note that if no parameter is required by the block, there is no need to use the pipe characters).

      define_method(prop) {
        instance_variable_get("@#{prop}")
      }

We’ve just written our last ever getter! The accessors in Ruby do not follow the JavaBeans conventions: the getter for a property is simply the property name (getName() is name) and the related setter is the property name followed by equal (setName(...) is name=). The previous code defines a method named using the content of the prop variable. The body of this method is defined by the block between the curly braces (this block has no parameters, so no need for pipe characters this time). The block will return the value of the instance variable named prop. In a double quoted string, #{…} is replaced by the evaluation of its content, here prop. So if the value of proc is name, "@#{prop}" will be "@name".

The following code defines how we declare setter methods. It also uses the #{...} notation, this time to concatenate the property name to equal, to create method name of the setter.

      define_method("#{prop}=") do |value|
        old_value = instance_variable_get("@#{prop}")
        return if (value == old_value)

The block for the setter accepts one argument, the value, as indicated between the pipe characters. As per Java conventions, we first make sure that the new value is different from the current value. If the values are the same, no need to notify the listeners, so we simply return.

Otherwise, we loop on all the listeners and notify them of which property is changing from what value to what value:

        @listeners.each { |listener|
          listener.property_changed(prop,
                                   old_value,
                                   value)
        }
        instance_variable_set("@#{prop}", value)
      end

Once all listeners have been notified, we set that property to its new value.

And finally, a bit of tidying up:

    end # loop on properties
  end # end of property method
end # end of RubyBean class

I hope this has enlightened you! Let me know!

RubyBeans, a short example of Ruby metaprogramming

Wednesday, February 22nd, 2006

As I explained in my recent post about metaprogramming, implementing a JavaBean is a task that would greatly benefit from metaprogramming. Here, I illustrate how this would be done in Ruby. Note that the resulting code has little interest for Ruby as JavaBeans are a Java idiom. I hope however that it demonstrates my purpose. Let’s dive straight into the code:

class RubyBean

  def initialize
    @listeners = []
  end

  def register_listener(l)
    @listeners.push(l) unless @listeners.include?(l)
  end

  def unregister_listener(l)
    @listeners.delete(l)
  end

These methods implement the management of the property change listeners on the bean. It is a subset of what java.beans.PropertyChangeSupport provides. Now comes the most interesting part:

  def RubyBean.property(*properties)
    properties.each { |property|
      class_eval(%Q[
        def #{property}
          @#{property}
        end

        def #{property}=(value)
          old_value = @#{property}
          return if (value == old_value)
          @listeners.each { |listener|
            listener.property_changed(:#{property},
                                     old_value,
                                     value)
          }
          @#{property} = value
        end
      ])
    }
  end
end

I define property as a class method that takes a variable number of arguments. For each of its arguments, property dynamically creates and adds to the RubyBean class, a getter and a setter to the bean. This follows the Ruby conventions for accessors: the getter is simply the property name, the setter is the property name followed by the equal sign. The setter also notifies the registered property change listeners. Note that in Ruby, you would use the attr_accessor method to create these accessors.

Now, writing a bean is as simple as:

class TestBean < RubyBean
  property :name, :firstname
end

Simple, no? Finally, here is how this code could be used:

class LoggingPropertyChangeListener
  def property_changed(property, old_value, new_value)
    print property, " changed from ",
      old_value, " to ",
      new_value, "\n"
  end
end

test = TestBean.new
listener = LoggingPropertyChangeListener.new
test.register_listener(listener)
test.name = "Parker"
test.firstname = "Charlie"
test.firstname = "Maceo"
test.unregister_listener(listener)

and the output it generates:

name changed from nil to Parker
firstname changed from nil to Charlie
firstname changed from Charlie to Maceo

Do not hesitate to comment if you have any query, suggestion, critic or simply if you want to say Hi!

Metaprogramming, Java’s downfall

Monday, February 20th, 2006

I have been a Java developer for almost 10 years and I must admit I really enjoy coding in Java. When I first discovered it, I was amazed by its API, the quality of its documentation, its simplicity and most of all its portability. With experience came a better understanding of the Java philosophy and a deeper understanding of Object Oriented concepts. Lately though, I have found Java to be a limiting factor to my productivity. I have identified the main reason behind this: Java lacks metaprogramming. Briefly put,metaprogramming is writing programs that write programs (see metaprogramming on wikipedia).

Here is an illustration of the problem. Everytime I want to write a JavaBean object, I have to make the class serializable, make sure the class has a default constructor, write getters and/or setters for all properties, write methods to register and unregister listeners for the bound properties, etc. It has to be done for every single bean you ever write. Coupled to the fact that unit tests for getters and setters are rarely written, leads to a very error prone process. It is easy to see that there is a definite pattern to this extremely repeatitive task, and obviously there are ways to ease the pain. Code generating tools like xdoclet and eclipse for example, do a decent job in this case. However, these tools suffer because they each use their own templating language and their functionality is usually limited to a C/C++ macro style of behaviour, agnostic of the language itself. By contrast, in a metaprogramming language, this templating and the code it generates are implemented in one language only. It is therefore possible to extend the language itself, by adding new constructs, rather than just develop the object hierarchy.

LISP is probably the quintessential metaprogramming language. LISP’s macros are so powerful that it has been able to adapt and incorporate every new programming paradigm. To my knowledge (and wikipedia’s), LISP (1958) predates all OO languages, as the concept was only being born, and yet CLOS is implemented in LISP itself and supports some features that other OO languages can only dream of (multiple dispatch for example). When AOP came about, it did not take long for LISP to have its own implementation: AspectL.

People usually object that LISP is unreadable. I suppose we will all agree that parentheses, like everything in life, must be used in moderation. But metaprogramming does not have to be implemented in a heavy and unreadable way. In order of increasing readability, I will point you to Io and to Ruby. Ruby uses metaprogramming, for example, to define accessors. But Ruby’s killer-app, Rails pushes this usage even further to provide a DSL for web development. See for yourself, I doubt you will find that Rails’s productivity claims are exaggerated.

For more information on metaprogramming and DSLs, I would recommend listening to the latest Rails podcast with Glenn Vanderburg and to check out Glenn’s blog, starting by this post. I also found Jose Antonio Ortega Ruiz’s blog, programmings musings to be a goldmine, see particularly: this post and follow the link to this good introduction to metaprogramming.