Archive for September, 2005

h1

The Fall of the Java Empire

September 24, 2005

Encapsulation is one of the first things a neophyte learns about object oriented programming. Defined here as “the concept that an object should totally separate its interface from its implementation,” it is one of the three pillars of object oriented programming, inheritance and polymorphism being the other two. Encapsulation freshly imprinted in his mind, the neophyte is then assigned to write a Java program, with the minimum possible number of lines, which prints “Hello World.” A quick search on the Internet and he finds several examples he can use. For the sake of completeness, I provide another one here:

public class HelloWorld {
public static void main(String[] args) {
     System.out.println("Hello World.");
}
}

The neophyte, possessing an inordinate curiosity, endeavors to actually understand this code. Knowing that methods always end with a set of parentheses, he is confused about the syntax of the particular line of code that does all the work. What is System? Doesn’t convention dictate that object names start with a small letter? Shouldn’t it be system? And what is out? It’s not a method because it lacks the mandatory parentheses. Ah, something finally familiar: println() is a method and “Hello World.” is its parameter. Feeling a bit ignorant, he sheepishly asks his instructor to elaborate.

The instructor explains, “Focus on the one important line, System.out.println(“Hello World.”). System is a special class that contains useful class fields and methods and can’t be instantiated. Further, out is a static PrintStream variable that is set by calling nullPrintStream(), which returns either null or throws a NullPointerException.”

Pressed by the student for more explanation, the flustered instructor invariably says, “That’s the beauty of encapsulation: you don’t have to know how it works, just that it works. We’ll get into it more later on, but for now, let’s move on to polymorphism.” :-|

Our neophyte, put off by the apparent complexity of Java, considers a different career path, but hearing a lot of buzz about Ruby, he decides to have a look-see. Imagine his pleasant surprise when he finds this snippet:

puts “Hello World.”

Wait, that’s not a snippet, that’s the whole code. Simple, clean, intuitive. He doesn’t give a whit whether or not the comparisons between Java and Ruby are fair or valid, he sees that he can accomplish the same result with less code. For him, Java’s weakness is its complexity; Ruby’s strength is its concise productivity. He’ll later learn Ruby’s limitations but well after he’s invested time to get his brain around it and adopted it as his language of choice.

How can Java answer this challenge? Comparisons break down here because Ruby is scripted and Java is compiled (at least to byte code). Java (arguably) needs all the public static void main business so it can’t simplify to Ruby’s extent, but life should be a little easier in the Java stack. In this case, incorporate encapsulation and provide a println() method on Object:

public class Object {
//
public void println(String s) {
     System.out.println(s);
}
}

Now our neophyte’s Hello World program looks a little better:

public class HelloWorld {
public static void main(String[] args) {
     println("Hello World.");
}
}

It’s not quite as clean as the Ruby version, but it demonstrates a not-so-subtle but profound idea: embrace the concepts of object oriented programming and encapsulate the language’s implementation. (Why is Object so sparce?)

Iterators are another example. Iterators are internal to a Ruby collection and the programmer merely provides the block of code executed by the collection’s method.

The neophyte’s next assignment: Create and print an array of strings. Here it is in Ruby:

name = %w[Last First MI]
name.each {|name| puts name}

Looping through the array is the responsibility of the each method. In Java, even with Tiger, it’s cumbersome (admittedly a relative term) because a for construct is still required:

List<String> list = new ArrayList<String>();
list.add("Last");
list.add("First");
list.add("MI");
for (String name:list) {
     System.out.println(name);
}

It’s amazing that Java still necessitates typing the declaration (String name) even though the expression (list) is parameterized. The so-called “advantage” of Generics is that casting from Object to String is unnecessary in the code block.

The Java Empire has a huge code base and is not soon to crumble. But there are cracks in the foundation and the barbarians are at the gate. Unless (maybe regardless if) repairs are made, collapse is inevitable. Consider this: eventually, our neophyte becomes a journeyman or even a master. If he can convince his boss or client that his language of choice (be it Ruby or any other) is faster, sleeker, sexier than Java, which will be selected for that grand new project?

h1

Gunfight at the Software Development Corral

September 20, 2005

Scene: The local saloon. B. Duf, the aging gun-slinger, sits with his chair tilted back, his gun rests on the table, barrel pointed toward the swinging doors. He waits. Enter the up-and-coming, XP Kid. He pauses just inside the doors, letting his eyes adjust to the change in light. B. Duf sets his chair down on all fours and puts his hands on the table.

B. Duf: You lookin’ fer me?

XP Kid: Depends.

B.Duf: Well, let me tell you how it is, boy. You’re looking to prove yourself. You reckon by taking me on, you can establish your reputation real quick-like. You’ll challenge me and I’ll accept. You prob’ly got a girl somewhere, try to talk you out of it but we’ll meet at the appointed time and place, high noon in front of the corral. You just might be a little quicker, but I just might be a little smarter. I been around longer, have a few more tricks up my sleeve. You know you’re not supposed to let ‘em see you sweat, but I actually know how. We’ll face off, stare each other down. You’ll be thinking, “Has he slowed down at all?” I’ll be thinking, “Is he really good enough to gun me down?” We’ll exchange words, none of ‘em pleasant. Soon enough, one of us will draw. Prob’ly you—you got more to lose. I’ll be faster than you thought, you’ll be smarter than I thought. It’ll be quite the spectacle. They’ll write books about it.

XP Kid: What if I just came in here for a drink?

B. Duf: Well, then I’d have to change my requirements.

Joel is Plain Wrong about XP

h1

Software for the Ages

September 16, 2005

When Alexander the Great marched into Egypt, the pyramids were as ancient to him as he is to us. Built to last an eternity, there are few signs the pyramids won’t outlast mankind.

No one is certain how the Egyptians constructed the pyramids, but there can be little doubt they accomplished wondrous feats with primitive tools. Among the devices used must have been instruments of measurement (probably a rope with knots), not only to calculate where to place a block of stone, but also, once set, to ensure it had been situated according to plan. Woe to the architect who had to tell Pharaoh his pet project was delayed because the foundation was off by half a cubit in each direction.

Software systems aren’t eternal, but inexpensive metric tools are widely available to help ensure adherence to accepted best practices. Simple, easy-to-understand metrics can spare us Pharaoh’s wrath. The voluminous output of some tools, however, can overwhelm, especially if most of the terms and acronyms are unfamiliar. The trick is to winnow out the superfluous and focus on a few meaningful numbers.

Andrew Glover, who recently presented the essentials of his Using Code Metrics for Targeted Code Refactoring session to my local Java User’s Group, favors cyclomatic complexity (cc) to measure code complexity. A high cc indicates complex code and reveals possible refactoring targets. Reducing the complexity of code lowers maintenance costs, reduces defect count, and keeps Pharaoh happy.

Andrew suggests a healthy dose of common sense when metrics, in particular cc, determine refactoring candidates. A cc of 15 in one system may not need the same tender loving care as a cc of 10 in another, but if Pharaoh likes the objectivity of a calculation and wants a 10, I’m not going to tell him he gets a 15.

Metrics affirm a sound base, confirm a house of cards, or uncover cracks in the foundation. In any case, metric tools are an excellent source of the applied knowledge required by software for the ages.

Code Improvement Through Cyclomatic Complexity

h1

Test Your Privates with JUnit-addons

September 15, 2005

After posting a solution to testing private methods on my original blog, I learned about JUnit-addons, which helped simplify the test code.

In the snippets below, my original technique used reflection to invoke an object’s private method. Using PrivateAccessor from JUnit-addons simplifies the code.

Original technique:

Method m = AddonsExample.class.getDeclaredMethod(
  "getMyObject",
  new Class[]{});
m.setAccessible(true);
AddonsExample ae = (AddonsExample) m.invoke(
  myObject,
  new Object[]{});
assertNotNull(ae);

With JUnit-addons:

AddonsExample ae = (AddonsExample) PrivateAccessor.invoke(
  myObject,
  "getMyObject",
  new Class[] {},
  new Object[] {});
assertNotNull(ae);

It may not seem like a big difference, but it’s another available option that eliminates the direct dependency on reflection and improves code readability. Thanks, Vladimir.

JUnit-addons

h1

How Much is Free?

September 11, 2005

The other day a neighbor asked to borrow a hammer. For reasons I won’t go into here, I had two identical, golden hammers, so I offered to give him one.

“How much do you want for it,” he asked.

“You can have it for free,” I said.

“Well,” he said, “it’s not really free.”

After evaluating my puzzled expression, he explained (or attempted to explain) his reason.

Intuitively, we know that a hammer has two parts, a handle and a head. We could also guess, if pressed, that one part isn’t much good without the other. But what if, my neighbor suggested, the hammer didn’t suit his liking? The hammer I offered was a claw hammer and he needed (I suspect, “preferred”) a ball-peen. He’d have to take the hammer apart to replace the head. A perfectly sound hammer, disassembled and reassembled by an amateur (my neighbor), does not retain its factory-assembled strength. Therefore, it could not be satisfactorily reconfigured to his preference. Since he couldn’t take it apart and play with it as he saw fit, it was not free.

I’m not the dimmest bulb in the chandelier, but I must confess I’d never before heard this definition. Rather than stand slack-jawed, I reasoned that if he wouldn’t take it for free—pardon me, at no cost—perhaps he would rather purchase the heretofore complimentary hammer. “But I want it for free,” he said.

“How about I rent it to you,” I asked. No, that wasn’t free either. “I guess you have a choice,” I said. “Either you take my hammer, for free, or you do without.”

If we had truly needed it, you and I would have taken the hammer but you and I would never have had this conversation in the first place. He decided to do without until he could make his own hammer, complete with interchangeable parts.

In his best interest and mine, I hope he never asks to borrow my chainsaw.

Free But Shackled – The Java Trap

h1

Whither Java?

September 10, 2005

It’s a tragic comedy to see the white-knuckled attempts of middle-aged people vainly hanging on to their evaporating youth. Men buy convertibles and join Hair Clubs. Women establish first-name relationships with plastic surgeons. They go to great effort and expense to avoid or delay the inevitable.

So it is with Java. It’s been the dominant programming language longer than any other in the history of computing. And it’s badly showing its age. Its latest attempt to maintain vitality, Tiger, was akin to Grecian Formula and an ineffectual comb-over.

Tiger may have been the only change to the language since 1995 but if developers have managed without a for/in construct for ten years they can do without it for the next ten. Java 5 is not innovation; it is contact lenses and a toupee.

Sadly, there is no Fountain of Youth. Java 6, code-named Mustang, does little to conceal Java’s wrinkles and gray hair. It either deals with annoyances that have pestered developers for years or “improves” existing features. Ground-breaking innovation could prolong Java’s viability, but sexy, emerging languages (like Ruby) and Sun’s apparent obsession with minor tweaks doom Java to its eventual demise.

Of course, the middle-aged are just that—middle-aged. If they focus on substance rather than appearance, they can lead full, productive lives. So it is with Java. We can no longer expect evolutionary changes in Java, rather we need to utilize its strengths and prepare ourselves for the day when it is no longer needed.

Links of interest:

Core Java Technology Features in Mustang

Desktop Java Features in Mustang