Monday, July 2, 2012

Writing clean code

When I interview developers, one question I always ask is "What do you think makes code well written?" Almost without fail, I get the answer "It has a lot of comments." While I'm not saying that good code shouldn't have any comments, usually have a lot of comments is indicative of code that is hard to read. Take this simple example of a method that checks if a number if an even number less than 100 or an odd number greater than 200.
boolean isValidNumber(int number) {
   // number is valid if it is even and less than 100 or odd and greater than 200
   return (number %2 == 0 && number < 100 ) ||(number % 2 != 0 && number > 200)
}
Sure, with a little bit of thought I can understand what this does or by reading the comments (if I trust them, I'll get to that shortly). This version of the code
boolean isValidNumber(int number) {
  return (isEven(number) && number < 100) || (isOdd(number) && number > 200)
}
With just this simple change the code just reads better and without the documentation. While the documentation is valid in the first case and reading it does make the code just as easy to understand as the second version, what if I realized there was a change in the validation method and now my code looks like
boolean isValidNumber(int number) {
   // number is valid if it is even and less than 100 or odd and greater than 200
   return (number %2 == 0 && number < 100 ) ||(number % 2 != 0 && number > 201)
}
Now the documentation doesn't match the code. Six months later, I'm reading this code, and now I have a question - which is correct? Writing cleaner code makes the code easier to read and removes the potential for ambiguity. Code should be written to be read by people, the computer doesn't care what it looks like.

I started off by saying that I think good code can still have comments, but comments that are internal to methods should say why the code does what it does, not what it does. The code should be easy enough to read what it does. On a side note, I do think that documentation that says what the code does is appropriate for the javadocs public methods (or even on private methods since IDEs typically show the documentation when hovering over a method).

Talking about writing clean code is easy, doing it is much more difficult (which is why so few of us actually do). Practice and think about it consciously while writing code until it becomes second nature. I also recommend that all developers read Clean Code by Bob Martin (http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882) at least once.

Monday, May 21, 2012

Automated provisioning of development environment

It's pretty common to use automated scripting tools (chef, puppet, etc) for provisioning your servers, but what about your development environment tools? It's far too common that developers are developing and testing with different versions of the software that is used in production. This also leads to each developer having different versions of tools, which often leads to "It works on my machine."

I've split this problem into two parts - IDE and tooling. Most of our developers use Eclipse, so I've geared my automation efforts toward Eclipse. Using the Eclipse p2 director, it is easy to script the installation of common plugins, settings, etc. Rather than mandating that developers download a pre-packaged distribution of Eclipse (which we then need to maintain), they can download whichever one they want (though most of developers use the Java EE version).

Using the p2 director application, we have a simple groovy script that does the following:
${eclipseExecutable} -application org.eclipse.equinox.p2.director -repository ${repoString} -installIU ${featuresString} -tag InstallInitialPlugins -destination ${eclipsePath} -profile ${profile}
Hopefully the variable names are self explanatory.

For tooling standardization (maven, java, etc), I've setup some simple puppet scripts to pull in those tools (I'm currently working in Windows, and Puppet seems to work better than Chef on Windows). This does not connect to a puppet server, rather we just have a directory on our server that has the necessary files. The script just installs a couple of executables and copies some zipfile distributions. Since our toolsets are not changing all that frequently, the script is run on demand, but it could be setup with a Puppet server on a polling interval if desired. For more complex environments, a virtual machine could be configured with vagrant/chef.

Sunday, October 2, 2011

Final variables in groovy with dynamic constructors and @TupleConstructor

Up until groovy 1.8, it was not possible to declare variables in final as groovy when using the named constructor. Frequently with simple groovy objects, I would have a class that looks like this:

class Person {
String name
int age
}

It always bothered me that name and age could not be final. While I could declare an explicit constructor, such as

class Person {
final String name
final int age
public class Person(String name, int age) {
this.name = name
this.age = age
}
}

the explicit constructor is something the groovy helps eliminate the need for, and I always felt like it was a hassle to declare.

However, declaring variables final is generally recommended when you won't be modifying the variable, so I was torn. final ensures the variable is not set again when you didn't want it to be. When working with multiple threads, final fields guarantee visibility across threads when the object is constructed.

So in groovy 1.7, the options were to not make the variables final or to declare the explicit constructor.

Groovy 1.8 introduced the @TupleConstructor annotation. By annotating a class, another constructor is created that uses default values for all of the values.

@TupleConstructor
class Person {
final String name
final int age
}

So in this case, a constructor

Person(String name, int age)

is created.

Now both groovy and java classes can use this constructor, and the fields can be marked as final.

Note that the constructor fields are in the order the properties are declared, so be careful when reorganizing classes (and test, test and test some more).

Monday, May 2, 2011

Implementing the Decorator pattern using Groovy's @Delegate

Let's say we want to write a decorator around a List to add a creation time to the list. We've all written something like this before, and it usually looks something like:

public class ListDecorator implements List {

private final List delegate;
private final Date creationTime = new Date();

public ListDecorator(List delegate) {
this.delegate = delegate;
}

public Date getCreationTime() { return createTime; }

public void add(...) {
delegate.add(...);
}

public int indexOf(...) {
return delegate.indexOf(...);
}

// wrap all of the list methods
}


This is very tedious, and we still need to write tests to make sure we actually delegated to the right method.

Enter the groovy @Decorator annotation

// notice we don't need to implement the List interface here
// since we can take advantage of duck typing
class GroovyListDecorator
{
// all of the calls to the list methods will be delegated to this list
@Delegate final List delegate

private final Date creationTime = new Date()

GroovyListDecorator(List delegate) {
this.delegate = delegate;
}

Date getCreationTime() {
creationTime
}
}

And now we can use it like this:
def list = new GroovyListDecorator(new LinkedList())
// these methods delegate to the LinkedList delegate
list.add("abc")
list.add("def")
println list.size() // 2
println list.creationTime // Mon May 02 19:49:55 EDT 2011


And it's as easy as that.

Wednesday, December 8, 2010

Eclipse Hot Swap Debugging

Maybe this is a well known feature, but it was news to me. The Eclipse debugger supports swapping code out at runtime when debugging (JVM 1.4 and later). Ensure Build Automatically is enabled, then run your application in debug mode. When stopped at a breakpoint, change the code you want to change and save the file. The code will be automatically swapped into your application without restarting - pretty cool.

This article http://www.ibm.com/developerworks/library/os-ecbug/ gives some more details regarding debugging with Eclipse.

Tuesday, June 1, 2010

Anti-Patterns

While most good software development teams have knowledge of software patterns, I still don't hear teams frequently talking about anti-patterns. I'm not really sure why that is. It seems logical to me that if patterns are a way of communicating common ways of doing things, anti-patterns should be in a programmer's language to communicate how not to do things, and to identify problematic areas of code. Anti-patterns do also extend beyond code into management, organization, etc, but I will just focus on coding anti-patterns.

One that I see so frequently is copy-paste-mutate. That is, when a developer copies a block of code, pastes it somewhere else, and changes it slightly. Most of it is duplicated and now mistakes are duplicates and testing must be duplicated (if you are testing). If you find yourself copying and pasting, stop. Should the functionality be in an abstract class? Should it be in a utility class? Regardless of where it needs to go, it shouldn't be copied and pasted.

Another recurring anti-pattern is see deals with poor exception handling. It's way too common to see e.printStackTrace() or LOGGER.error(e) (or even worse, an empty catch block) as a solution to error handling. If you can "handle" the exception by just printing it out, maybe it shouldn't be an exception at all. Exceptions should indicate errors (i.e. exceptional cases) and your program generally shouldn't be able to continue to operate normally when one occurs without proper handling.

Wikipedia has a large list of anti-patterns here http://en.wikipedia.org/wiki/Anti-pattern#Software_design_anti-patterns. Take a look and see which of these traps you're falling into.

Monday, April 26, 2010

Eclipse Templates

You may notice in Eclipse when pressing ctrl+space to auto-complete that you get suggestions that are not necessarily code. For example, you can select main to auto create a public static void main(String[] args) method. You can also define your own custom templates (and view all the existing ones) by going to Window > Preferences > Java > Editor > Templates.

This is a nice feature if you haven't used it before. I particularly like being able to define a println template for System.out.println to make it easy to switch between groovy and java. Another common one I define is a logger template to create a logger variable. If you find yourself defining the same lines of code in many places, a template may be of use to you.

If you already use templates, it would be nice to share some common ones you use.