Becoming an Advanced Groovy Developer: Design Patterns

The following post is based on my upcoming presentation at Springone 2GX, entitled “Becoming an Advanced Groovy Developer”.

What are design patterns? They are simply solutions to development challenges we encounter daily. It is not a library we add, but more of a template to implement in given situations. Design patterns can be applied in a language such as Groovy. Groovy’s features make some of these easier to implement.

One issue that I learned early on is if you implement them in the wrong place you can make things more complicated than they need to be. When I first learned the Singleton pattern I tried to put it everywhere, many places it didn’t fit. On the whole they can help immensely when implemented correctly.

Design patterns are broken up into three categories:

  1. Structural
  2. Creational
  3. Behavioral

Using Structural patterns, we can make things work together in a better way. Creational patterns simply make it easy to create the objects we need. The last category of patterns is behavioral and they facilitate communications between our classes.

I think it is helpful for all developers to understand these solution templates to the daily challenges we run into. Perhaps you have read the Gang of Four design patterns book. I personally found that book a bit too abstract. Design patterns originated in building design and architecture and were brought to software development by Kent Beck and Ward Cunningham.

When developers discuss proposed solutions design patterns come in handy. We can quickly explain what type of solution we think would work best by using the names of the design patterns. Of course when we read through code using the name of the design pattern in the file name can be very helpful too. Who wants to read through lines of code just to decipher the solution.

One important note that I picked up from a talk that Venkat Subramaniam did on design patterns is that we should not force them in but rather let them come out as we develop the code. Like mentioned earlier I had an issue with this as I learned the singleton pattern and tried to force this into too many situations. It caused confusion and I spent a lot of time removing most of those. If you are in doubt it can be helpful to share with another developer and get their feedback.

Iterator Pattern

The iterator pattern is a behavioral design pattern that allows you to traverse a collection of objects in a consistent manner independent of the type of collection. Iterator Design Pattern You want to traverse a collection of objects in a consistent manner independent of the type of collection An external iterator allows you to control the actual traversal An internal iterator takes care of that—you provide code that needs to be executed for each element in the collection

// Iterator example – for in
for (item in container) { println item }

// Iterator example – eachWithIndex
colors.eachWithIndex{ item, pos ->
printlin “Position $pos contains ‘$item’”
}

// Iterator example – each
(1..3).each {
println “Number ${it}”

Groovy has the iterator pattern built right into many of its closure operators, Here is three examples, the each and eachWithIndex as well as the for .. in loop. Here we have examples of all three starting with the for in, eachWithIndex, and each.

Adapter Pattern

The Adapter Pattern is a structural pattern that (sometimes called the wrapper pattern) allows objects satisfying one interface to be used where another type of interface is expected. There are two typical flavors of the pattern: the delegation flavor and the inheritance flavor. The adapter pattern is a structural design pattern that allows you to repurpose a class with a different interface, allowing it to be used by a system which uses different calling methods.

// Adapter example
class SquarePegAdapter {
    def peg
    def getRadius() {
        Math.sqrt(((peg.width / 2) * * 2) * 2)
   }
   String toString() {
        “SquarePegAdapter with peg $peg.width and radius $radius”
     }
}

In this example of an adapter pattern, we have defined the getRadius and toString methods. This adapter is for the SquarePeg class. The adapter is sometimes referred to as a wrapper too. Think about how you might “wrap” functionality into an existing class.  There are many great examples of adapters in the real world. For instance, if you travel to many countries overseas you notice the power plugs are different so we need to get an adapter. In software development, this happens a lot when we call a vendor’s API. Perhaps we need add more parameters to call an LDAP service. Adapters can help encapsulate methods using an adapter. Using an adapter can make it so you can reuse code instead rewriting code.

Decorator Pattern

Next up we will talk about the decorator pattern, which like the adapter pattern is a structural design pattern. The decorator’s job is to add behavior to your object. It can enhance your normal behavior without changing the essential interface. We must make sure that the object that has the decorator pattern applied can be used in the same manner as the normal object. We should not need to modify the source code to do this.

Decorating a class is different than subclassing, where decorating adds functionality at runtime, subclassing works at compile time. The aim is to make it so that the new functions can be applied to one instance, and, at the same time, still be able to create an original instance that doesn’t have the new functions. This allows for mixing multiple decorators for one instance.

// Decorator example
class UpperLogger extends Logger {
   private Logger logger
   UpperLogger(logger) {
        this.logger = logger
   }
   def log(String message) {
        logger.log(message.toUpperCase())
   }
}

In this example of a decorator, we add functionality to the logger class. We simply build on the base functionality to make messages upper case in the log. You can easily see how you can enhance the logging more by adding perhaps a timestamp or additional machine information.

Singleton Pattern

Our last pattern we are going to cover this afternoon is the Singleton. Singleton is a creational design pattern that makes sure that you have one instance of a class during runtime and provides a point of access to the instance.

As I mentioned earlier in this presentation I learned this design pattern early in my career and tried to over apply this to many situations. We should use the Singleton pattern when we want to make sure one object of a class should be created. Be sure that this is the case, make sure you understand what solution is needed. Many years ago I created a help desk utility that I misunderstood the requirements of and used copious amounts of singletons.

This one object should coordinate actions across a system. Maybe there is a resource that cannot be shared so the singleton can control access to it. Other times it could be an issue where creating many objects can be wasteful. A few of the cons of the singleton are, they can be hard to test because of the static methods. Also, they can hinder reuse, inheritance for singletons can be very tricky.

// Decorator example
class VoteCollector {
   def votes = 0
   private static final INSTANCE = new VoteCollector()
   static getInstance() { return INSTANCE }
   private VoteCollector() { }
   def display() { println “Collector:${hashCode()}, Votes:$votes” }
}

In this example of a decorator it has a private constructor, so no VoteCollector objects can be created . This instance is private and cannot be modified. The vote collector instance is created once we reference this class even if not needed.

What Design Pattern would you add?
Are there any that you think are not needed?

Which one do you use most?

How do you help new members of the team deal with Design Patterns your codebase?

, ,

No comments yet.

Leave a Reply

Powered by WordPress. Designed by Woo Themes