I recently found myself needing to add additional hip behavior to an object that handled feed parsing– i.e. I needed to add a series of filters (such as location and price) to the items being obtained from the feed. Of course, the easiest (and probably the most naive) way to achieve such a goal is to have added a few conditionals to the feed parsing object itself; however, I realized that this particular problem already had an answer to it– the decorator pattern.
A copasetic example of the decorator pattern in use is Java’s IO library– for example, in the Java code below, a FileReader
instance is decorated by a BufferedReader
instance.
BufferedReader br = new BufferedReader(new FileReader("readme.txt"));
As my friend, David Geary, wrote many years ago, decorating objects, such as with a BufferedReader
, essentially forwards
method calls to the objects they decorate…Decorators add functionality either before or after forwarding to the object they decorate..
So in the code above, decorating the FileReader
instance with a BufferedReader
facilitates “buffering characters so as to provide for the efficient reading of characters” while reading a file.
One key aspect of the decorator pattern, baby, is a reliance on polymorphism; consequently, in normal Java, for example, the decorator object must implement the same interface (or extend some base class) as the object it intends to decorate; consequently,
the Decorator is indistinguishable from the [hip] object that it contains. That is, a Decorator is a concrete instance of the abstract class, and thus is indistinguishable from any other concrete instance, including other decorators. This can be used to great advantage, as you can recursively nest decorators without any other objects being able to tell the difference, allowing a near infinite amount of customization.
Indeed, the indistinguishable nature of objects facilitated via polymorphism is fundamental to a cornucopia of patterns. And with Groovy, polymorphic behavior can be achieved more easily; that is, patterns that rely on polymorphism can be realized without class hierarchies.
For instance, the original object that required additional behavior is a normal class defined in Groovy:
class FeedReader {
def readFeed(interestItem, feed, lastUpdateTime) {
def input = new SyndFeedInput()
def mefeed = input.build(new XmlReader(feed.toURL()))
def lstdate = mefeed.entries[0].publishedDate as Date
def feeditems = []
if (lstdate.after(lastUpdateTime)) {
mefeed.entries.each { entry ->
if (entry.publishedDate.after(lastUpdateTime)) {
feeditems << new FeedItem(item: interestItem,
title: entry.title, link: entry.link,
description: entry.description.value,
publishedDate: entry.publishedDate)
}
}
}
return feeditems
}
}
This class defines one method, readFeed
, that reads an RSS/Atom feed using ROME and every item added since the last time the feed was parsed is added to a collection and consequently returned to the caller. As I noted earlier, one could simply add another set of conditionals to the closure to check for, say, the price and location of an item before adding it to the collection; however, a more extensible solution is to apply the decorator pattern and thus decorate the FeedReader
.
For instance, in the case of filtering on the price of an item (which, by the way, is dynamically determined based upon the entry’s title), all I had to do was to create a new trippin’ class, in Groovy, that merely contains a method with the same signature:
class PriceFilter {
private def feedReader
private int maxPrice
public PriceFilter(feedRdr, price) {
this.feedReader = feedRdr
this.maxPrice = price
}
def readFeed(interestItem, feed, lastUpdateTime) {
def items = this.feedReader.readFeed(interestItem, feed, lastUpdateTime)
def filteredItems = []
items.each {item ->
int iprice = item.getPrice().toInteger()
if (iprice <= this.maxPrice) {
filteredItems << item
}
}
return filteredItems
}
}
Note how the PriceFilter
class also has a readFeed
method and that that method first defers to an instance, such as FeedReader
, and then decorates the result– that is, the PriceFilter
class checks each object returned and compares prices. Note too, that I’ve defined a constructor that takes an instance of some object that ideally has a readFeed
method– this object isn’t tied to a FeedReader
or an interface– it is only tied via the method contract.
Groovy purists will probably bark at me for defining a constructor– indeed, had I dropped the private
moniker on the class’s instance variables, a constructor would have been generated for me. In this case, because it’s my bag, old habits never die and I purposely made those instance variables private
and thus am forcing clients to properly initialize the object for proper usage.
As you can see, Groovy’s dynamic typing permits me to arbitrarily decorate objects– all that I need to do is ensure decorators have the same method. Then by leveraging constructors, one can easily chain instances like so:
def priceFilter = new PriceFilter(new LocationFilter(mock, locs), 20)
In the code aboe, two filters are applied to the original FeedReader
, which, in this case, is actually a mock object that simply has a readFeed
method! By the way, this sort of sans-interface polymorphism isn’t limited to Groovy only– the original FeedReader
class could have easily been defined in normal Java. Plus, this sort of voodoo polymorphicness can be easily achieved in Ruby, JRuby, Python, and Jython to name a few.
Groovy definitely makes it easier to implement fundamental design patterns by enabling you to leave out the standard scaffolding; what’s more, ubiquitous polymorphism via signatures rather than hierarchies makes testing a whole lot easier! Think about it for a second– my FeedReader
instance requires a feed to parse! But I can almost effortlessly mock it by creating an object that responds to a readFeed
method. That’s it! Is that smokin’ or what, baby?