Victor works on the Angular team at Google. He is interested in functional programming, the Web platform, and client-side applications. Being a language nerd he spends a lot of my time playing with Smalltalk, JS, Dart, Scala, Haskell, Clojure, Ruby, and Ioke. Victor is a DZone MVB and is not an employee of DZone and has posted 45 posts at DZone. You can read more from them at their website. View Full User Profile

Groovy Coding Style

02.18.2011
| 10419 views |
  • submit to reddit

I’ve been using Groovy for about 4 years. The code that I used to write 3 years ago looks very different from the 1 year old code and from the code I am writing these days. Why is that?

Sure, one part of it is that I’ve been becoming more and more familiar with Groovy over the years and Groovy has been becoming more powerful; such features as @Delegate and especially @Mixin change the way I write code.

However, the main reasons are different. When I begin using Groovy I was a Java developer. And that is why during the first few month my code looked more like Java with closures and fancy collections literals; I believe, this is the case for many Groovy developers.

Then I was doing a lot of Ruby development and it had changed my habits and my style of coding. Just a few examples: there are no interfaces in Ruby. They just don’t make any sense in Ruby world. You don’t specify a type when you define a variable in Ruby. We specify def in groovy if we don’t want to specify the exact type of the variable.

Compare these two chunks of code:

class SqlPersonRepository
...
def find_by_name name
...
end
...
end

class SqlPersonRepository {
...
def findByName(name){
...
}
...
}

They are almost identical. What kind of code will a Java developer will write when he begins using Groovy?

class SqlPersonRepository implements PersonRepository {
...
Person findByName(String name){
...
}
...
}

I’m not talking which one is better, this is not the point. The point is that they are so different and Groovy allows using both and it can be confusing.

And I was confused, confused by two different cultures (Java and Ruby) and I couldn’t decide for a long time which style I preferred. To make it simple for myself I tried to formalize it, to find out a few simple rules that I would always look at when I don’t know which style should be used.

Before mentioning the rules I’d like to write about three main things influencing the way I write Groovy code.

  1. Interoperability with Java. Quite often your Groovy classes have to extends Java classes or implement some interfaces. Or Java classes have to use you Groovy classes. In both cases you don’t have a choice but using types and interfaces everywhere. If you don’t do it your Java code becomes ugly.

  2. IDE support. Everything is very simple for Ruby guys, IDEs don’t help you a lot. Even RubyMine from JetBrains(!!) doesn’t impress so much. In opposite, Groovy IDEs really rock. Especially, Groovy support in IDEA, it provides advanced autocompletion and refactoring. When you have all these features you don’t want to lose them, so you specify types to have autocompletion.

  3. Using dynamic capabilities. Though Groovy has extremely powerful dynamic capabilities allowing to do all (maybe almost all) the crazy stuff I used to do in Ruby I don’t use all these capabilities so often. It is just not part of Groovy culture. If you write even a small library in Ruby it is common to add some methods to base classes. We don’t do it in Groovy. Except Grails and a few more libs. Of course, the situation is different when you are developing a domain specific language. But let’s be honest, we don’t do it every day.

Based on these points I’ve framed some rules that I’m trying to follow to keep my style of coding consistent.

Rule 1

Everything that is public has to have specified type unless the type is Object. It means that I will write a public method this way:

Person findByName(String name){
...
}

If an argument or a return type is Object I don’t specify anything:

def transformObject(obj){
...
}
Rule 2

I usually don’t specify types in private method unless it really helps to understand it. Also I can specify a parameter type when I invoke a lot of methods and I really need autocompletion. I never specify return types for private methods. Very often IDEA can infer those types from the code and I have my autocompletion anyway.

Person findByName(String name){
internalMethod name
}

private internalMethod(name){
...
}

Why am I doing it? Personally for me, specifying types in all private methods adds a lot of noise to the code. If you have a 50 line class everything is clear from the context. You don’t have to repeat yourself all the times.

Person findByName(String name){
def prefixedName = getFirstName(name)
}

private getFirstName(name){
...
}

It is clear that name is a String and that the return type is String too. Why should I write it?

Rule 3

All properties types have to be specified.

class Person {
String name
int age
}
Rule 4

Don’t specify types for local variables. I don’t do it because IDEA can infer types and I have my autocompletion.

def greeting = sayHi('john')

private sayHi(name){
"Hi $name"
}

IDEA knows that greeting is a GString.

Rule 5

If something can be done at compile time it should be done at compile time. If I need to delegate method calls to another object I’d rather use @Delegatethan methodMissing.

Rule 6

Use interfaces for public APIs. It is much easier for other developers to understand what needs to be implemented if interfaces are used. If you require something like:

class ConditionBuilder {
void addCondition(condition)
}

it might take some time to understand what condition is.

Rule 7

Provide constructors for public classes.

class Person {
String name
int age

Person(String name, int age){
...
}
}

Very often I don’t provide constructors for my internal utility classes. You might say that the contact of construction is not clear in this case. Personally for me new Person(name: 'John', age: 50) looks better than new Person('John', 50) and usually my internal code is tested very well so I don’t have issues with null values.

These are seven simple rules helping me with making decisions about my code style. A few of them are dictated by the fact that IDE support is getting better and specifying types in all methods is not necessary anymore.

 

From http://vsavkin.tumblr.com/post/3191162772/groovy-coding-style

Published at DZone with permission of Victor Savkin, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

John Rellis replied on Fri, 2011/02/18 - 8:31am

We pretty much came to the same decisions when deciding our Groovy coding standards. Sure it would be nice to do everything 100% 'typeless' but for the sake of our sanity we decided we had to type in strategic places! Some might say this is watering down Groovy a little but you can't win them all!

Mark Unknown replied on Fri, 2011/02/18 - 11:55am

I am starting to use Groovy. Here are my observations so far: 1. If you are not a good typist, it is more difficult because intellisense does not work as well even when using Types. 2. Reminds a lot of what i had to deal with in VB when not using Option Explicit if I don't use Types - and that is not good. 3. Debugging is not as good as Java which makes me have to type more (println) Sure, I am just getting started, but over all I feel much less productive than if I just used Java. I really do like some things in Groovy like SQL and how i can use the names of fields with just dot notation. If i keep things small or if i don't use custom objects it think it will be better than doing it in Java. YMMV. Note: I know this is really a tooling issue. I do hope it continues to get better for Groovy. I know my typing skills will not. :)

Victor Savkin replied on Sat, 2011/02/26 - 12:11pm in response to: Mark Unknown

I totally agree that when you just start using a new tool it will always be less productive for a while. From my experience, autocompletion works in 80% of all cases if you use IDEA. Eclipse is still far behind though it is getting better. Debugging works not as perfect but, to be honest, I don't use debugging very often. I am sure that it sounds trite but good test coverage helps to identify problems without debugging.

Victor Savkin replied on Sat, 2011/02/26 - 12:24pm in response to: John Rellis

Thanks for your feedback. I agree, using types is useful because of many reasons besides IDE support. The main one is helping you to formalize your class's contract. For instance, parse_file(file). Should I pass a file object or just a file path? parse(File file) looks better for me. Multimethods are one more reason why using types can be useful.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.