Using Groovy is easy and fun. After getting your hands dirty with a few basics it is good to go deeper. In this session we will cover Design Patterns in Groovy, compilation configuration, mixing Java and Groovy, and calling other languages from Groovy. We will show you how to call Scala and Clojure from Groovy. So get ready to take it to the next level.
Good afternoon, my name is Tom Henricksen and Welcome to Becoming an Advanced Groovy Developer at Springone 2GX 2015. Thank you for coming to this session.
I have been a software developer for over fifteen years dealing with Java, Oracle Technologies, Groovy, and Grails and I live in West Des Moines Iowa.
First off, I just want to thank my employer Zirous for this opportunity. At Zirous we are an Oracle Platinum Partner, Hortonworks Partner, ForgeRock Partner and help many companies find technology solutions with Java, Groovy, Grails, Big Data, Identity, and other open source technologies.
Here is today’s agenda, we will start with Groovy Design Patterns in the first part of the presentation.
From there we will go into the second section and discuss the Mixing Java and Groovy.
If you have any comments just share them during the presentation.
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 every where, 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 time removing most of those. If you are in doubt it can be helpful to share with another developer and get their feedback.
https://www.youtube.com/watch?v=YSEcVlYiGIU
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
Groovy has the iterator pattern built right in to 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.
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.
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.
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.
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.
Our last pattern we our 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.
Could hinder reuse, inheritance for singletons can be very tricky
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.
Now it is your turn to talk, here are a few questions for you.
What Design Pattern would you add? (30 seconds)
Are there any that you think are not needed? (30 seconds)
Which one do you use most? (30 seconds)
How do you help new members of the team deal with Design Patterns your codebase? (30 seconds)