Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Design patterns, the big picture, Part 2: Gang-of-four classics revisited

Learn the GoF design patterns in Java code, starting with Strategy and Visitor

  • Print
  • Feedback

Page 4 of 4

Evaluating expressions via visitors

I've created a downloadable expression evaluator application that creates an AST for the expression language. The following excerpt from the application's EE class parses an expression (identified by args[0]) into an AST:

Parser p = new Parser();
ASTNode n = p.parse(args[0]);

The created AST is then visited to print its node hierarchy and evaluate its expression. For example, the excerpt below creates a print visitor and passes it to the accept(Visitor) method of the AST's root node:

n.accept(new PrintVisitor());

The application simulates double dispatch in Java code as follows:

  1. Single dispatch causes the accept(Visitor) method of the appropriate ASTNode subclass instance (whose reference is stored in n) to be invoked with the PrintVisitor instance as its argument. (ASTNode is implemented as Java interface, but it could just as easily have been implemented as an abstract class.)
  2. Within accept(Visitor), v.visitx(this); is executed, where x depends on the accept(Visitor) method that is called. Single dispatch causes v.visitx(x); in the appropriate Visitor subclass instance (whose reference is stored in v) to be invoked with the current node's reference as its argument.

The various visitor methods continue to traverse the tree by making accept(Visitor) calls on child nodes. For example, the following PrintVisitor class excerpt shows how PrintVisitor's visitAddNode(AddNode n) method visits its left and right child nodes:

public void visitAddNode(AddNode n)
{
   depth++;
   n.left.accept(this);
   depth--;
   println(n.getName());
   depth++;
   n.right.accept(this);
   depth--;
}

Running the expression evaluator

The following command shows you how to use EE to evaluate the expression: 4.0+2.0*3.0:

java EE 4.0+2.0*3.0

When you run this command, you should observe the following output:

4.0
+
        2.0
    *
        3.0

4.0+2.0*3.0 = 10.000000

 

Design Patterns tips

Now that we've looked in detail at two of the GoF patterns, let's turn our attention to the book that started it all. This section and the next will be a guide for readers new to the Design Patterns book. Reading the Design patterns critique in the next section may be especially helpful for newer developers.

Design Patterns is essentially a catalog of 23 software design patterns. Despite presenting a short tutorial on each pattern along with a larger case study, the book is largely laid out as a reference manual. Following a simple study plan will help you get the most out of it.

If you're new to design patterns, I recommend that you start by reading the introduction in Chapter 1. You'll learn what constitutes a design pattern, discover how design patterns are described, find out how to select and use design patterns, and more. You might want to read this chapter a couple of times to let its concepts sink in. Next, read Chapter 2, which introduces several design patterns in a document editor case study.

Pattern Hatching -- a GoF supplement

A few years after Design Patterns debuted, one of its authors (the late John Vlissides) wrote a supplementary volume called Pattern Hatching. This book focuses on putting design patterns to work, extending some of the original GoF patterns, and helping those who want to write their own patterns. Read more about this book's aims in John Vlissides's own words by visiting the Portland Pattern Repository's Pattern Hatching page.

Chapters 3, 4, and 5 comprise the catalog of patterns. Each chapter begins with an overview of the type of pattern being discussed (creational, structural, or behavioral) and then presents the patterns in alphabetical order. You probably shouldn't attempt to read through these chapters sequentially because you'll quickly get bogged down and start forgetting important details.

Instead, try studying a single chapter to learn how to distinguish between patterns of a similar type. Alternatively, you might browse from pattern to pattern. I believe that an inexperienced object-oriented designer would be well-off first studying the following eight design patterns, which are some of the simplest and most commonly used of the 23 patterns in the book. (This advice is from the readers guide that precedes Chapter 1 of Design Patterns, by the way.)

  1. Abstract factory
  2. Adapter
  3. Composite
  4. Decorator
  5. Factory method
  6. Observer
  7. Strategy
  8. Template method

Another option is to follow the "simple followed by intermediate followed by advanced" pattern order proposed by Web developer Michael Mahemoff in "GoF Design Patterns: Rapid Learning Tips." Finally, for the Java developer looking for Java-based examples, I recommend David Geary's Java design patterns series on JavaWorld. Geary doesn't cover all 23 patterns, so you might want to also check out James Sugrue's DZone series, Design patterns uncovered.

Regardless of your approach to exploring the 23 patterns, consider summarizing and implementing each pattern (as I demonstrated with the Strategy pattern earlier in this article) for yourself. That will help you understand and retain the pattern, and will make the pattern your own, rather than letting it remain the product of someone else's work.

 

Design Patterns critiqued

The GoF's Design Patterns book has been praised by many, but it hasn't stood the test of time without some critique. One well-known critic is Mark Jason Dominus, who famously criticized GoF software design patterns in his "Design Patterns Aren't" slideshow presentation.

Dominus points out that pattern languages as introduced in Christopher Alexander's Pattern Language book (the architectural inspiration for software design patterns) help you decide what needs to be designed without telling you how to design it. You make up the patterns that you think will lead to good designs. In contrast, he sees the GoF's approach as discovering existing patterns and then implementing them habitually.

A participant in a StackOverflow topic addressing sources of design pattern criticism reinforced that viewpoint:

The feeling is that when we teach patterns we cause developers, especially junior developers, to try to cram all problems into the set of patterns that they have learned, which can create more obtuse and cumbersome problems.

Software developer Jeff Atwood has also critiqued the GoF patterns in a blog post entitled "Rethinking Design Patterns." Atwood says that the GoF patterns rely too heavily on boilerplate code: "[I]t's a sign that your language is fundamentally broken [when] you find yourself frequently writing a bunch of boilerplate design pattern code to deal with a 'recurring design problem,'" he writes. Atwood also finds design patterns as a whole overly complex, stating that developers should focus on simpler solutions before applying complex design pattern recipes.

Conclusion to Part 2

Software design patterns are part of a larger pattern universe. The final article in this series will broaden the usual discussion of design patterns by focusing on patterns relevant to software development, but not directly related to code. We'll look at interaction design patterns, architectural patterns, and communication and presentation patterns and discuss their relevance to contemporary software development.

In the meantime, what do you think about the Gang of Four book describing which pattern to use for a given software problem, versus the older idea that patterns should help us decide what needs to be designed, but not how to design it? Should introductory Java courses and books cover the GoF software design patterns, or are junior developers better off without them? What would help Java developers at every level better grasp when it's appropriate to use a software design pattern, and when it's not? Share your thoughts in the Comments section.

About the author

Jeff Friesen is a freelance tutor and software developer with an emphasis on Java and Android. In addition to writing Java and Android books for Apress, Jeff has written numerous articles on Java and other technologies for JavaWorld, informIT, Java.net, and DevSource. Jeff can be contacted via his website at TutorTutor.ca.

Read more about Enterprise Java in JavaWorld's Enterprise Java section.

  • Print
  • Feedback

Resources

David Geary's Java design patterns series on JavaWorld: Learn more of the Gang of Four patterns in Java code: