Send As SMS

2006-06-24

Moved

Java Bar & Grill has moved. Please update your links.

2006-05-24

FindBugs and More

I discovered FindBugs today and just for fun, I ran it against our current project. Among many, many other things, BugFinder flagged code that created new instances of Boolean rather than use Boolean.TRUE or Boolean.FALSE. This method was tagged as one of the offenders:
public Boolean validateMinLength(String value, int length) {
try {
if (value == null || value.length() == 0) {
return new Boolean(true);
}
if (value != null && value.length() >= length) {
return new Boolean(true);
}
} catch (Throwable e) {
}
return new Boolean(false);
}
I quickly fixed the offending code:
public Boolean validateMinLength(String value, int length) {
try {
if (value == null || value.length() == 0) {
return Boolean.TRUE;
}
if (value != null && value.length() >= length) {
return Boolean.TRUE;
}
} catch (Throwable e) {
}
return Boolean.FALSE;
}
There were still several problems. In fact, it reeked with code smells. A healthy dose of refactoring was in order. Most blatant was the unnecessary and ill-advised try-catch block that silently ignored an unchecked exception. All I can say here is, "huh?"
public Boolean validateMinLength(String value, int length) {
if (value == null || value.length() == 0) {
return Boolean.TRUE;
}
if (value != null && value.length() >= length) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
Poorly named methods and method parameters are a pet peeve of mine mostly because I use code completion not only to minimize keystrokes but also to jog my memory about the parameters needed by methods. "arg0" and "arg1" don't cut it. "value" was a bit too generic, as was "length." The method name, "validateMinLength," implied that the method validated the length parameter instead of checking if the string was a certain length or longer. Eclipse made renaming a breeze:
public Boolean isMinimumLength(String anyString, int minimumLength) {
if (anyString == null || anyString.length() == 0) {
return Boolean.TRUE;
}
if (anyString != null && anyString.length() >= minimumLength) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
It wasn't perfect, but the method's purpose was significantly clearer. An important function of refactoring is separating the intent from the implementation or, in other words, the "what" from the "how." Without looking at the code, I now had a better idea what the method did but still not how it worked. So let's take a closer look at the "how."

Is the intent of the first if statement really to return true when the String parameter is null or an empty string? That's what the code said, but I was inclined to think it was a bug; logically, null has no length, so how could it meet a minimum length? Not too long ago, I would have added a reassuring comment along the lines of, "// return true if value is null or nill." I reason that the second if statement actually checked if the string had at least "minimumLength" number of characters but I shouldn't have to guess. Since I'm a better programmer than I was six months ago :-) I extracted new methods to make it more "human readable":
public Boolean isMinimumLength(String anyString, int minimumLength) {
if (isNullOrNill(anyString)) {
return Boolean.TRUE;
}
if (meetsMinimumLength(anyString, minimumLength) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}

private boolean isNullOrNill(final String anyString) {
return anyString == null || anyString.length() == 0;
}

private boolean meetsMinimumLength(final String anyString, final int minimumLength) {
return anyString != null && anyString.length() >= minimumLength;
}
Now there's no question that the method really should return true for a null or empty string and when the string has at least minimumLength characters.

Next, using multiple returns violated my rule of one entry point and one exit point for a method. I've been in arguments with others who think it's silly to worry about one exit point, but had the rule been followed, only two Boolean objects would have been instantiated instead of three.
public Boolean isMinimumLength(String anyString, int minimumLength) {
boolean b = false;
if (isNullOrNill(anyString)) {
b = true;
}
if (meetsMinimumLength(anyString, minimumLength) {
b = true;
}
return Boolean.valueOf(b);
}
One last step: while this method was not very complex, there's no reason it couldn't be simplified. Also, whenever possible I prefer to avoid using a default return value. Here's my final refactoring:
public Boolean isMinimumLength(String anyString, int minimumLength) {
boolean b = isNullOrNill(anyString) || meetsMinimumLength(anyString, minimumLength)
return Boolean.valueOf(b);
}

private boolean isNullOrNill(final String anyString) {
return anyString == null || anyString.length() == 0;
}

private boolean meetsMinimumLength(final String anyString, final int minimumLength) {
return anyString != null && anyString.length() >= minimumLength;
}
The public method is readable, even by a non-programmer. It's faster to gleam the method's purpose. How the funcionality is implemented is only one method declaration away. This will all come in handy if someone not familiar with the code has to dig in and find out what it does. Lines of code (not counting method signatures) have been reduced from 10 to 4 so bugs are less likely and easier to fix should they occur.

One method down, oh so many to go.

2006-04-02

NoFluffJustStuff Conference Takes Omaha by Storm

Unsurpassed Quality
NoFluffJustStuff just concluded the Greater Nebraska Software Symposium, its first-ever stopover in Omaha, NE. It couldn't have turned out better, despite the stormy weather. The presenters are all first rate--they don't just talk about this stuff; most all have invaluable real-world experience they are willing to share. There is honestly not a dud in the bunch. I'm invigorated (if not a little brain-sore) and anxious to implement some of the techniques and ideas that I walked away with. Seriously, if you are a Java web developer, you owe it to yourself to attend one of these conferences, even if you have to foot the bill yourself.

Test First
The first Saturday of the month the city tests its tornado warning system. This happened while I was in a session given by Venkat Subramaniam. Hearing the siren, Venkat asked what the noise was. We told him it was the tornado warning. The look on Venkat's face was priceless as he looked to duck and cover. "Don't worry, it's just a test," we told him. Without skipping a beat he said, "You should say, 'test' first!"

Happy News
One of the highlights was definately the announcement that they'll be back in Omaha next year. Hoo-rah, I'm going to No Fluff!

2006-03-08

Bar and Grill Lab Notes: Groovlets

It seems whenever I read discussions about JSF, Struts, etc., someone invariably claims they’re happiest foregoing frameworks and writing Servlets by hand. I have an inexplicable aversion to HTML code in println() statements so I’ve hand-coded a grand total of one simple “Hello World!” Servlet. I even once wrote a Java tool that converted the pointy-bracket output from a WYSIWYG HTML editor to all those PrintWriter.println() statements. JSPs put a quick and merciful end to that project.

There are some valid points to the Servlet-by-hand approach, not the least of which is avoiding the unnecessary overhead of a bloated framework, which can presumably translate to better performance. For small and even some medium-size web apps, an industrial strength framework might very well be overkill.

With all that in mind, I looked at Groovy’s version of Servlets: Groovlets. The sample on Groovy’s site is markedly minimal, so I decided to write my own to explore the capabilities of a Groovlet. The following example, IMHO, better demonstrates the power of Groovlets. Without further adieu, here is my 1.0-jsr-05 Groovlet, which displays historical stock quotes for a given ticker symbol, in two parts (to break up the monotony):

Part 1
import groovy.xml.MarkupBuilder;

def symbol = request.getParameter('symbol')
if (symbol == null) {
symbol = '^DJI'
}
def today = new Date()
def end = new GregorianCalendar()
end.setTime(today)
def beg = new GregorianCalendar()
beg.setTime(today.minus(7))

// this line broken up for clarity
def url = "http://ichart.finance.yahoo.com/table.csv?s=${symbol}&a=${beg.get(Calendar.MONTH)}
&b=${beg.get(Calendar.DAY_OF_MONTH)}&c=${beg.get(Calendar.YEAR)}
&d=${end.get(Calendar.MONTH)}&e=${end.get(Calendar.DAY_OF_MONTH)}
&f=${end.get(Calendar.YEAR)}&g=d&ignore=.csv".toURL()

def text = url.getText()
def list = text.tokenize("\n")
Things of note:
Part 2
html.html {
head {
title('Groovlet Example')
}
body {
form (method:'get', action:'index.groovy') {
div {
label (for:'symbol', 'Symbol: ')
input (type:'text', name:'symbol', value:symbol, size:'5', maxlength:'5', '')
input(type:'submit', value:'Submit', '')
}
}
table (cellpadding:'10') {
tr {
list[0].tokenize(",").each {
th(it)
}
}
list[1..5].each {row ->
tr (align:'right') {
row.tokenize(",").each {
td(it)
}
}
}
}
}
}
Things of note:
Groovlets definately won't take over the JSP/Servlet stack any time soon, but they do provide an easy technology for quick solutions to small and perhaps even some mid-size projects.

2006-03-05

Why JavaServer Faces will Dominate

Javalobby Readers’ Choice: Top Java Books consists of 112 books with a total of 72,079 pages. Rick Ross, founder of Javalobby, writes,
…if you read fifty pages per day every day, then you would finish reading this collection sometime in the middle of January, 2013! Of course, there’s some question whether all of this material would still be relevant by then, and there’s also the small issue of whether you’d really want to fork over the $5,238.66 this library would cost if you paid full price for every title.
For those reasons, one would be inclined to derive some means by which to pare down the list. It’s a good bet the top five or ten are excellent reads and should be on every developer’s shelf. Word of mouth from a trusted colleague or by recommendation from an industry expert might also be good reasons to consider ownership of one or more of these books. Whatever the choice, it is most certainly not based on personal experience, but somewhat arbitrary.

The same can be said for adopting a technology. (A Google search on java web development frameworks turns up over 22,000,000 hits--admitedly unscientific, but telling none-the-less.) There are simply too many frameworks, tools, and techniques to absorb enough knowledge to make an intelligent decision when it comes to selecting technology for a development team. Some may be so overwhelmed by the staggaring number of choices, they stick with the tried and true. Most, I suspect, will decide to adopt the latest, especially for new projects. The decision to select one technology over the others most likely will be based on whatever will be around for at least the typical life span of a system. So a great guessing game ensues and inevitably the answer is, “whatever the industry leaders are pushing.”

Thus, JSF will be, if it isn’t already, the dominate web development framework for at least the next 5 years. Not because it’s a superior framework, or that it cuts development time or increases quality, or even because it’s (arguably) innovative, but because it’s a standard and Sun is behind it.

Sorry, Tapestry fans, but it’s Betamax v. VHS all over again, and you’re behind Betamax.

2006-01-16

Crazy Shirt Folding - Google Video

Wish I'd have known about this in boot camp.

Crazy Shirt Folding - Google Video

Link

2005-12-11

Well Done Software

Not long ago, a friend told me about the excellent food at a frou-frou steakhouse that recently opened downtown. I tend to favor frugality, but he assured me the bacon-wrapped filet medallions were worth the second mortgage. My wife, Barbara, and I did a cost-benefit analysis and decided the budget could take the hit if we postponed our Branson vacation until next summer. I made dinner reservations for two.

I, for one, believe a steak done well is a steak well done. Many a waiter has reminded me this is atypical, so I was not surprised when I ordered my filet medallions well done, our waiter leaned in close, and whispered, “Are you sure?” I wanted to say, “Look pal, I’ve eaten enough steak to know I don’t like it bleeding all over my plate,” but Barbara has me conditioned to smile and nod confirmation.

At this point, our dining experience took a detour to the twilight zone. The chef himself burst through the kitchen doors and made a bee-line to our table. In no uncertain terms, he chided me for making him ruin a perfectly succulent cut of meat and urged me to reconsider my preferences. It seems his rigorous training, years of experience, and meticulous reading of trade journals made him better qualified to know how I wanted my steak. He only backed down when I threatened to take my vacation money elsewhere.

I stewed about the chef’s arrogance for days, and the incident was still fresh in my memory when I read this from Technology Review:

"Users are tremendously non-self-aware," Myhrvold adds. At Microsoft, he says, corporate customers often demanded that the company simultaneously add new features and stop adding new features. "Literally, I've heard it in a single breath, a single sentence. ‘We're not sure why we should upgrade to this new release-it has all this stuff we don't want-and when are you going to put in these three things?' And you say, ‘Whaaat?'" Myhrvold's sardonic summary: "Software sucks because users demand it to."

Myhrvold believes his rigorous training, years of experience, and meticulous reading of trade journals make him better qualified to know what users want in their software. Like the chef, Myhrvold thinks the end product is his and users should recognize their non-self-awareness and listen to the experts. In fact, software exists to fulfill users’ needs, not developers’.

My own sardonic summary: “Software sucks when developers demand it to.”

This page is powered by Blogger. Isn't yours?