Thursday, June 12, 2008

mysterious smells

One of our problems at this company is the need to write, re-write, and edit a huge amount of the code base really fast. Since we have demos, releases and branches coming up in a few weeks (less now that I'm going to be going back to Japan soon), there is a feeling of muted urgency.


The good news: we're pretty good at doing what is needed very quickly.

The bad news: our code is starting to smell.


What do I mean by smell? A 'code smell' is a term I just learned the other day. Basically it's a combination of less-than-optimum coding practices, usually introduced by a lack of refactoring, or using procedural programming techniques (because they're more intuitive/easier to implement) when in the long run the code would be much easier to maintain and understand using object oriented principles.


Here is a list stolen from http://wiki.java.net/bin/view/People/SmellsToRefactorings
(which in turn was summarized from the classic book "Refactoring" by Kent beck.)















































SmellDescriptionRefactorings
Comments Should only be used to clarify "why" not "what".

Can quickly become verbose and reduce code clarity.
Extract Method

Rename Method

Introduce Assertion

Long Method The longer the method the harder it is to see what it’s doing.
Extract Method

Replace Temp with Query

Introduce Parameter Object

Preserve Whole Object

Replace Method with Method Object

Long Parameter List Don't pass in everything the method needs; pass in enough so that the method can get to everything it needs.
Replace Parameter with Method

Preserve Whole Object

Introduce Parameter Object

Duplicated Code
Extract Method

Pull Up Field

Form Template Method

Substitue Algorithm

Large Class A class that is trying to do too much can usually be identified by looking at how many instance variables it has. When a class has too many instance variables, duplicated code cannot be far behind.
Extract Class

Extract Subclass

Type Embedded in Name Avoid redundancy in naming. Prefer schedule.add(course) to schedule.addCourse(course)
Rename Method

Uncommunicative Name Choose names that communicate intent (pick the best name for the time, change it later if necessary).
Rename Method

Inconsistent Names Use names consistently.
Rename Method

Dead Code A variable, parameter, method, code fragment, class, etc is not used anywhere (perhaps other than in tests). Delete the code.
Speculative Generality Don't over-generalize your code in an attempt to predict future needs.
If you have abstract classes that aren't doing much use Collapse Hierarchy

Remove unnecessary delegation with Inline Class

Methods with unused parameters - Remove Parameter

Methods named with odd abstract names should be brought down to earth with Rename Method



There are more on that site, and even more in the book. I should really buy it. But it might just sit on the shelf like my 'Design Patterns' book. Oh well, at least my coworker found use for it and has been semi-permanently borrowing it.
But I digress.

Friday, May 16, 2008

Perly Java

So, if you have even a tiny bit of Java experience you know about the normal format of the if/then/else control flow.

if(something that might be true){
do this;
}else{
do that;
}

or alternatively,
if(something that might be true){
do this;
}else if(something else that might be true){
do that;
}else{
do the alternative.
}

Of course there are a number of ways to make these statements shorter, like ommitting closing curly braces if the 'do this' operation is one line, etc.
These shorter ways are a little harder to read, but make the code a little more compact which can be a good thing.
But there is an even SHORTER way! If you just have a simple if/then/else statement, nothing fancy, just one operation for the if and the else, then you can get it down to one line.

To make this even more cryptic, it is not even necessary to use the words 'if' or 'else' in there at all: in place of if is '?' and in place of else is ':'.
So the above code fragment would look like this:

(something that might be true)?do this:do that;

This is getting suspiciously like Perl, if you ask me. Java heresy! ;)

Friday, May 2, 2008

Singletons: I finally get it

When I was trying to make a map for a servlet that is created long before I can pass stuff to it, I realized I need a way to make a map of user's input from the GUI, give it to the servlet, and read that map from the server side. But it can't just be any old instantiation of a map object. It has to be the ONE instance that I actually put stuff in, so I know where to point on the server side from the servlet's data processing methods.

I had heard about singletons, and in fact had to study about them before. But I studied them in a kind of abstract way and never really had to use them - until now.

Here is a great great understandable explanation from "Using the Singleton Pattern"
by Budi Kurniawan (http://www.onjava.com/pub/a/onjava/2003/08/27/singleton.html).


How do you write a Singleton class? Simple: create a public static method that is solely responsible for creating the single instance of the class. This also means that the client of the class should not be able to invoke the Singleton class's constructor, either. Because the absence of a constructor will make the compiler create a no-argument public constructor, a class applying the Singleton pattern has a private or protected constructor. Because the constructor is private or protected, there is no way a client can create an instance of that class by calling its constructor. The constructor is not accessible from outside of the class!


If the only constructor cannot be accessed, how do we get an instance of that class? The answer lies in a static method in the class. As mentioned above, a Singleton class will have a static method that calls the constructor to create an instance of the class and return this instance to the caller of the static method. But isn't the constructor private? That's right. However, remember that the static method is also in the same class; therefore, it has access to all members of the class, including the private members of the class.


You might ask the following question: "You can't create an instance of a class by calling its constructor, so how do you call the static method (responsible for creating the single instance of the class) without having the class instance?" Note, though, that static members of a class can be invoked without having an instance of that class. To limit the number of instances to one, the static method has to check if an instance has been created before. If it has, it simply returns a reference to the previous created instance. If it has not, it calls the constructor to create one. It's as simple as that.



So to get my map, I create a singleton class to hold my data, create a static getInstance method, and instantiate it from the GUI with my data mapping. Then on the server, I call the getInstance method (which will pass me back the ONE object with my map), and voila!

Friday, March 28, 2008

Do-it-yourself equals and hash code methods

Usually you can depend on the Java Object uberclass to provide your class with adequate .equals (to determine two objects's equality) and hashCode() (to index your object within a hash).
But sometimes, you just need a little more. You can override these methods and give your own classes more specific instructions about what to do when they are being tested for equality or being indexed. I still have much to learn about this, but found a tasty looking link for further, later perusal.
http://www.geocities.com/technofundo/tech/java/equalhash.html

Friday, March 14, 2008

Data Facades

One of the signs you're moving from basic programming to more advanced stuff:
the use of Data Facades. I noticed this in some of the newer parts of our code base, where it's being refactored by a more competent programmer than I! :)
Here's a little blurb on it from the MSDN site:

"Consider using a data facade to wrap the most relevant data needed by the client. You can develop a wrapper object, with a coarse-grained interface, to encapsulate and coordinate the functionality of one or more objects that have not been designed for efficient remote access. It provides clients with single interface functionality for multiple business objects."

What does that mean? Say my server-side code has a few queries that have very little difference between them. Instead of making if/else statements to differentiate them, create a *DataFacade class for each of these states. These in turn should all implement an interface that has methods for getting a part of the query. The *DataFacade classes will in turn have the specifics for their method bodies.

Tuesday, January 22, 2008

GWT - UIServiceAsync timing

I've been working a lot with GWT (google web toolkit), and have been using the user interface 'client side' , tying in to the back end. (server side). This introduces a few problems, especially with database calls. GWT translates Java into Javascript for you, but it doesn't try to generate javascript for the code you keep hidden away on the server side (thank goodness, especially since GWT currently only supports Java 1.4!)
So how does it know when the calls to the server side are complete?


Using AsyncCallbacks. These have onSuccess and onFailure methods you write yourself, which tell your UI side what to do when your server side calls have finished.


I have found that the timing of these prove to be a pain. Your client side code, like the tide and time, waits for no man. It will merrily march on, after you have made a call to get some data from the database for instance, and not care whether or not it has completed to run the next line. So you can't really depend on the feedback from the server side on the next line, your data might very well be null.
..or the line after that. or the next one.

So how do you make sure that darn query's output can be properly shown to the user?


the answer lies in the onSuccess method.
You make a structure to contain whatever you need on the UI side, and draw itself (as empty for now, or with a 'loading, please wait' message) to the screen.
Then, pass that container to the Async call. In the onSuccess method, you tell it to write the output to that container and draw itself again.


This way the user will always see something, and you won't get null Pointer exceptions.

Wednesday, January 2, 2008

comparing objects with nulls

When trying to test an object to see if it's null or not (for good error handling purposes), it's good to know: a null object's .equal method doesn't measure up to a null. ie, you can't do this:



String s = null;
String r = null;

possiblySetMyString(r);

if(s.equals(null)){
System.out.println("string not set");
throw new RuntimeException();
}else{
System.out.println(s);
}

public void possiblySetMyString(String t){
s = t;
}



Nope! That won't work. you can't check if a string 'equals' null with the object's .equals method , because it's going to try to compare various String parameters to a null. Instead, replace the s.equals(null) with s==null.
Note: use == to check for primatives (int, char, bool, null etc), and use .equals to compare two objects. If you're comparing two different types, better convert before comparing.