Design Patterns For Dummies

339

description

You don’t have to tell me how naive these books can be, but they’re pretty good starting points for the complete beginner, which is kind of the audience I am trying to target anyway. I suppose the biggest takeaway from this book is going to be the ability to learn how to use design patterns, and use them so that you can reduce the amount of code you’re writing. That is a pretty big feat for many new programmers. It’s practical and gets straight to the point, that’s what I like about this book. http://codecondo.com/best-design-pattern-books/

Transcript of Design Patterns For Dummies

Page 1: Design Patterns For Dummies
Page 2: Design Patterns For Dummies

by Steve Holzner, PhD

Design PatternsFOR

DUMmIES‰

01_798541 ffirs.qxp 3/27/06 2:19 PM Page iii

Page 3: Design Patterns For Dummies

01_798541 ffirs.qxp 3/27/06 2:19 PM Page ii

Page 4: Design Patterns For Dummies

Design PatternsFOR

DUMmIES‰

01_798541 ffirs.qxp 3/27/06 2:19 PM Page i

Page 5: Design Patterns For Dummies

01_798541 ffirs.qxp 3/27/06 2:19 PM Page ii

Page 6: Design Patterns For Dummies

by Steve Holzner, PhD

Design PatternsFOR

DUMmIES‰

01_798541 ffirs.qxp 3/27/06 2:19 PM Page iii

Page 7: Design Patterns For Dummies

Design Patterns For Dummies®

Published byWiley Publishing, Inc.111 River StreetHoboken, NJ 07030-5774

www.wiley.com

Copyright © 2006 by Wiley Publishing, Inc., Indianapolis, Indiana

Gamma/Helm/Johnson/Vlissides, DESIGN PATTERNS: ELEMENTS OF REUSABLE OBJECT-ORIENTEDSOFTWARE, © 1995 Pearson Education, Inc. Reprinted by permission of Pearson Education, Inc. Publishingas Pearson Addison Wesley.

Published by Wiley Publishing, Inc., Indianapolis, Indiana

Published simultaneously in Canada

No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form orby any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permit-ted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior writtenpermission of the Publisher, or authorization through payment of the appropriate per-copy fee to theCopyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600.Requests to the Publisher for permission should be addressed to the Legal Department, Wiley Publishing,Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, (317) 572-3447, fax (317) 572-4355, or online athttp://www.wiley.com/go/permissions.

Trademarks: Wiley, the Wiley Publishing logo, For Dummies, the Dummies Man logo, A Reference for theRest of Us!, The Dummies Way, Dummies Daily, The Fun and Easy Way, Dummies.com, and related tradedress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates in the UnitedStates and other countries, and may not be used without written permission. All other trademarks are theproperty of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendormentioned in this book.

LIMIT OF LIABILITY/DISCLAIMER OF WARRANTY: THE PUBLISHER AND THE AUTHOR MAKE NO REP-RESENTATIONS OR WARRANTIES WITH RESPECT TO THE ACCURACY OR COMPLETENESS OF THE CON-TENTS OF THIS WORK AND SPECIFICALLY DISCLAIM ALL WARRANTIES, INCLUDING WITHOUTLIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE. NO WARRANTY MAY BE CRE-ATED OR EXTENDED BY SALES OR PROMOTIONAL MATERIALS. THE ADVICE AND STRATEGIES CON-TAINED HEREIN MAY NOT BE SUITABLE FOR EVERY SITUATION. THIS WORK IS SOLD WITH THEUNDERSTANDING THAT THE PUBLISHER IS NOT ENGAGED IN RENDERING LEGAL, ACCOUNTING, OROTHER PROFESSIONAL SERVICES. IF PROFESSIONAL ASSISTANCE IS REQUIRED, THE SERVICES OF ACOMPETENT PROFESSIONAL PERSON SHOULD BE SOUGHT. NEITHER THE PUBLISHER NOR THEAUTHOR SHALL BE LIABLE FOR DAMAGES ARISING HEREFROM. THE FACT THAT AN ORGANIZATIONOR WEBSITE IS REFERRED TO IN THIS WORK AS A CITATION AND/OR A POTENTIAL SOURCE OF FUR-THER INFORMATION DOES NOT MEAN THAT THE AUTHOR OR THE PUBLISHER ENDORSES THE INFOR-MATION THE ORGANIZATION OR WEBSITE MAY PROVIDE OR RECOMMENDATIONS IT MAY MAKE.FURTHER, READERS SHOULD BE AWARE THAT INTERNET WEBSITES LISTED IN THIS WORK MAY HAVECHANGED OR DISAPPEARED BETWEEN WHEN THIS WORK WAS WRITTEN AND WHEN IT IS READ.

For general information on our other products and services, please contact our Customer CareDepartment within the U.S. at 800-762-2974, outside the U.S. at 317-572-3993, or fax 317-572-4002.

For technical support, please visit www.wiley.com/techsupport.

Wiley also publishes its books in a variety of electronic formats. Some content that appears in print maynot be available in electronic books.

Library of Congress Control Number: 2006920631

ISBN-13: 978-0-471-79854-5

ISBN-10: 0-471-79854-1

Manufactured in the United States of America

10 9 8 7 6 5 4 3 2 1

1B/RX/QU/QW/IN

01_798541 ffirs.qxp 3/27/06 2:19 PM Page iv

Page 8: Design Patterns For Dummies

About the AuthorSteve Holzner is the award-winning author of 100 books on computing. He’s a former contributing editor for PC Magazine, and has been on the faculty of Cornell University and MIT. In addition to his busy writing sched-ule, he gives programming classes to corporate programmers aroundthe country and runs his own training company, which you can find athttp://www.onsiteglobal.com/.

01_798541 ffirs.qxp 3/27/06 2:19 PM Page v

Page 9: Design Patterns For Dummies

01_798541 ffirs.qxp 3/27/06 2:19 PM Page vi

Page 10: Design Patterns For Dummies

DedicationTo Nancy, as always and forever.

01_798541 ffirs.qxp 3/27/06 2:19 PM Page vii

Page 11: Design Patterns For Dummies

01_798541 ffirs.qxp 3/27/06 2:19 PM Page viii

Page 12: Design Patterns For Dummies

Author’s AcknowledgmentsThe book you hold in your hands is the result of many peoples’ work. I wouldparticularly like to thank Mark Enochs, editor extraordinaire, and KatieFeltman, my acquisitions editor, who helped get this book off the ground andkeep it in flight the rest of the way. Thanks also to my copy editor, HeidiUnger, for dotting the I’s and crossing the T’s.

01_798541 ffirs.qxp 3/27/06 2:19 PM Page ix

Page 13: Design Patterns For Dummies

Publisher’s AcknowledgmentsWe’re proud of this book; please send us your comments through our online registration formlocated at www.dummies.com/register/.

Some of the people who helped bring this book to market include the following:

Acquisitions, Editorial, and Media Development

Project Editor: Mark Enochs

Acquisitions Editor: Katie Feltman

Copy Editor: Heidi Unger

Technical Editor: John Purdum

Editorial Manager: Leah Cameron

Media Development Coordinator:Laura Atkinson

Media Project Supervisor: Laura Moss

Media Development Manager: Laura VanWinkle

Editorial Assistant: Amanda Foxworth

Cartoons: Rich Tennant(www.the5thwave.com)

Composition

Project Coordinator: Tera Knapp

Layout and Graphics: Carl Byers, Andrea Dahl,Lauren Goddard, Heather Ryan

Proofreaders: Debbye Butler, Christine Pingleton

Indexer: Techbooks

Publishing and Editorial for Technology Dummies

Richard Swadley, Vice President and Executive Group Publisher

Andy Cummings, Vice President and Publisher

Mary Bednarek, Executive Acquisitions Director

Mary C. Corder, Editorial Director

Publishing for Consumer Dummies

Diane Graves Steele, Vice President and Publisher

Joyce Pepple, Acquisitions Director

Composition Services

Gerry Fahey, Vice President of Production Services

Debbie Stailey, Director of Composition Services

01_798541 ffirs.qxp 3/27/06 2:19 PM Page x

Page 14: Design Patterns For Dummies

Contents at a GlanceIntroduction .................................................................1

Part I: Getting to Know Patterns....................................5Chapter 1: Congratulations, Your Problem Has Already Been Solved.........................7Chapter 2: Putting Plans into Action with the Strategy Pattern.................................17Chapter 3: Creating and Extending Objects with the Decorator and

Factory Patterns.............................................................................................................39Chapter 4: Watch What’s Going On with the Observer and

Chain of Responsibility Patterns .................................................................................65Chapter 5: From One to Many: The Singleton and Flyweight Patterns......................91

Part II: Becoming an OOP Master ..............................117Chapter 6: Fitting Round Pegs into Square Holes with the Adapter and

Facade Patterns............................................................................................................119Chapter 7: Mass Producing Objects with the Template Method and

Builder Patterns ..........................................................................................................145Chapter 8: Handling Collections with the Iterator and Composite Patterns .........177Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns ...207Chapter 10: Coordinating Your Objects with the Command and Mediator

Patterns .........................................................................................................................233

Part III: The Part of Tens...........................................257Chapter 11: Ten More Design Patterns .......................................................................259Chapter 12: Ten Easy Steps to Create Your Own Patterns ........................................281

Index .......................................................................295

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xi

Page 15: Design Patterns For Dummies

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xii

Page 16: Design Patterns For Dummies

Table of ContentsIntroduction..................................................................1

About This Book...............................................................................................1Foolish Assumptions .......................................................................................2Conventions Used in This Book .....................................................................2How This Book Is Organized...........................................................................3

Part I: Getting to Know Patterns...........................................................3Part II: Becoming an OOP Master .........................................................3Part III: The Part of Tens........................................................................4

Icons Used in This Book..................................................................................4Where to Go from Here....................................................................................4

Part I: Getting to Know Patterns ....................................5

Chapter 1: Congratulations, Your Problem Has Already Been Solved . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7

Just Find the Pattern that Fits ........................................................................8Enter the Gang of Four Book...........................................................................9Getting Started: The Mediator Pattern........................................................10Adapting to the Adapter Pattern..................................................................11Standing In for Other Objects with the Proxy Pattern ..............................12Taking a Look at the Observer Pattern .......................................................13

Chapter 2: Putting Plans into Action with the Strategy Pattern . . . . .17Extending Object-Oriented Programming...................................................18

The big four OOP building blocks ......................................................19Abstraction is the good kind of breakdown............................19Encapsulating all that junk ........................................................20Mighty polymorphism rangers .................................................20Inheritance without the pesky taxes........................................22

Composition versus inheritance: A first attempt at designing the new cars ................................................................23

Handling Change with “has-a” Instead of “is-a”..........................................27Drawing Up Your Plans..................................................................................29

Creating your algorithms.....................................................................29Using your algorithms .........................................................................30Selecting algorithms at runtime .........................................................33

Making Your Move with the Strategy Pattern.............................................35

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xiii

Page 17: Design Patterns For Dummies

Design Patterns For Dummies xivChapter 3: Creating and Extending Objects with the Decorator and Factory Patterns . . . . . . . . . . . . . . . . . . . . . . . .39

Closed for Modification, Open for Extension .............................................41Enter the Decorator Pattern .........................................................................42Putting the Decorator Pattern to Work .......................................................45

Creating a decorator ............................................................................45Adding a disk ........................................................................................46Adding a CD...........................................................................................47Adding a monitor..................................................................................47Testing it out .........................................................................................48

Improving the New Operator with the Factory Pattern ............................50Building Your First Factory...........................................................................52

Creating the factory .............................................................................53Creating the abstract Connection class ............................................54Creating the concrete connection classes ........................................55Testing it out .........................................................................................56

Creating a Factory the GoF Way...................................................................59Creating an abstract factory ...............................................................59Creating a concrete factory.................................................................60Creating the secure connection classes ............................................61Testing it out .........................................................................................62

Chapter 4: Watch What’s Going On with the Observer and Chain of Responsibility Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . .65

Notifying Observers with the Observer Pattern........................................66Creating a subject interface ................................................................69Creating an observer interface ...........................................................70Creating a subject.................................................................................70Creating observers...............................................................................73Testing the Database observers.........................................................75

Using Java’s Observer Interface and Observable Class............................78Watching with the Observer interface...............................................78Notifying with the Observable class..................................................79Creating the Observable object..........................................................80Creating the Observer objects............................................................82Testing the Observable code ..............................................................84

Using the Chain of Responsibility Pattern ..................................................86Creating a help interface .....................................................................87Creating chainable objects..................................................................87Testing the Help system ......................................................................89

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xiv

Page 18: Design Patterns For Dummies

Chapter 5: From One to Many: The Singleton and Flyweight Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91

Instantiating Just One Object with the Singleton Pattern.........................92Creating a Singleton-based database .................................................94Testing the Singleton pattern..............................................................98Uh oh, don’t forget about multithreading .........................................99Putting the synchronized solution to work ....................................100Handling threading better .................................................................103Putting the pre-thread solution to work..........................................104

The Flyweight Pattern Makes One Look like Many..................................106Creating a student ..............................................................................109Testing the Flyweight pattern ...........................................................110Handling threading better .................................................................112

Part II: Becoming an OOP Master ...............................117

Chapter 6: Fitting Round Pegs into Square Holes with the Adapter and Facade Patterns . . . . . . . . . . . . . . . . . . . . . . . . .119

The Adapter Scenario..................................................................................119Fixing Connection Problems with Adapters .............................................121

Creating Ace objects ..........................................................................123Creating Acme objects.......................................................................124Creating an Ace-to-Acme object adapter.........................................125Testing the adapter ............................................................................127Inheriting class adapters ...................................................................128

Simplifying Life with Facades .....................................................................134Dealing with a difficult object ...........................................................137Creating a simplifying facade ...........................................................140Testing the facade ..............................................................................143

Chapter 7: Mass Producing Objects with the Template Method and Builder Patterns . . . . . . . . . . . . . . . . . . . . . . . .145

Creating the First Robot ..............................................................................146Creating Robots with the Template Method Pattern...............................149

Creating robots by template .............................................................150Testing the creation of robots ..........................................................155Built-in Template Methods in Java ...................................................156

xvTable of Contents

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xv

Page 19: Design Patterns For Dummies

Design Patterns For Dummies xviAdding a hook.....................................................................................158Testing the hook method ..................................................................160

Building Robots with the Builder Pattern.................................................161The client rules...................................................................................161Letting clients build robots...............................................................165Creating some buildable robots .......................................................168Testing the robot builder ..................................................................172

Chapter 8: Handling Collections with the Iterator and Composite Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .177

Accessing Objects with the Iterator Pattern ............................................178Accessing your objects with an iterator .........................................179Gathering the vice presidents into a collection .............................181Creating the iterator...........................................................................183Iterating over vice presidents...........................................................186More fun with for/in ...........................................................................190

Putting Together Composites.....................................................................191It all starts with an abstract class ....................................................193Creating the vice president leaves ...................................................194Creating the division branches.........................................................196Building your corporation.................................................................198

Tracking the Composite Pattern in the Wild ............................................203

Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207

Getting the State of Your Union with the State Pattern...........................208Using methods to hold state.............................................................209Using objects to encapsulate state ..................................................213Creating the state objects .................................................................218Putting the rental automat to the test .............................................223

Standing In for Other Objects with Proxies ..............................................224Can you hear me now? Creating the automat server ....................225Anyone there? Creating the automat proxy....................................228Using the proxy to connect around the world................................230

Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233

Taking Command with the Command Pattern .........................................234Aiming at the target: Creating your receiver objects.....................236Be the boss: Creating your commands............................................239Getting your commands to actually do something:

Creating the invoker .......................................................................241

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xvi

Page 20: Design Patterns For Dummies

Putting commands to the test ..........................................................242Supporting undo.................................................................................244Testing the undo.................................................................................247

Coordinating with the Mediator Pattern...................................................249Designing the Rutabagas-R-Us site ...................................................251Connecting it all up with the mediator............................................254Testing the Rutabagas-R-Us site .......................................................255

Part III: The Part of Tens ...........................................257

Chapter 11: Ten More Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . .259Creating a Factory Factory: The Abstract Factory Pattern ....................260Cloning when You Need It: The Prototype Pattern..................................261Decoupling Abstractions from Implementations

with the Bridge Pattern ...........................................................................262Creating Your Own Language: The Interpreter Pattern...........................264Forget Me Not: The Memento Pattern .......................................................264The Visitor Stops In for a Moment.............................................................266Going in Circles with Circular Buffers .......................................................268Doing Your Magic Off-Screen with the Double Buffer Pattern................274Getting Multiple-Use Objects Out of the

Recycle Bin Design Pattern .....................................................................277Entering the Big Time with the Model/View/Controller Pattern............278

Chapter 12: Ten Easy Steps to Create Your Own Patterns . . . . . . . . .281Following the Pattern Catalog Style...........................................................283Introducing the Veto Pattern ......................................................................283

1. Intent................................................................................................2842. Motivation .......................................................................................2853. Applicability....................................................................................2854. Structure..........................................................................................2855. Participants.....................................................................................2866. Collaborations ................................................................................2877. Consequences.................................................................................2878. Implementation/Sample Code ......................................................2889. Known Uses.....................................................................................29210. Related Patterns ...........................................................................293

Getting Your Pattern into a Pattern Catalog .............................................293

Index........................................................................295

xviiTable of Contents

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xvii

Page 21: Design Patterns For Dummies

Design Patterns For Dummies xviii

02_798541 ftoc.qxp 3/27/06 2:20 PM Page xviii

Page 22: Design Patterns For Dummies

Introduction

If you’re ever writing code and get the funny feeling that you’ve solved theproblem you’re working on before, you probably have. You may well have

come across the same type of situation in the past, puzzled about it, andcome up with the solution. And before that, you may have faced the sametype of situation and come up with the same type of solution. And evenbefore that . . . same thing.

Why keep reinventing the wheel? Why not just write down your solution andrefer back to it as needed? That’s what design patterns are all about. A designpattern represents a solution to a problem or class of problems that you canput to work at once in your own code.

In fact, design patterns go one step further — they also let you share in thesolutions found by other programmers, and expert programmers at that. Thedesign patterns you see in this book represent insightful solutions to dilem-mas that just about every programmer comes up against sooner or later, andknowing them is going to save you a lot of time and effort.

Got a problem? Most likely, there’s a design pattern for that. All you need toknow is that someone has already solved your problem for you, with a carefuleye towards good programming practices and efficiency. And all you haveto do is apply that solution to your own code. Once you know how, there’snothing to it.

The design patterns covered in this book are essential for any programmer toknow — and certainly for any professional programmer. There’s a lot of adhoc programming that goes on in the world, and that can lead to a lot oferrors in critical code. Why be the one sitting in front of the debugger all day?Put design patterns to work for you and just slip the solution into place.

About This BookThere are plenty of design patterns floating around the programming world,and in time, a particular set of 23 of them has become accepted as the stan-dard set. These patterns were first corralled in a book named Design Patterns:Elements of Reusable Object-Oriented Software (1995, Pearson Education, Inc.Publishing as Pearson Addison Wesley) by Erich Gamma, Richard Helm,Ralph Johnson, and John Vlissides — who have since been called the Gang ofFour, or GoF, for short. And those 23 design patterns became known as theGoF design patterns.

03_798541 intro.qxp 3/27/06 2:20 PM Page 1

Page 23: Design Patterns For Dummies

You see all 23 of those standard patterns in this book, and some additionalones as well. I explain what each pattern does and when you should use thepattern. You also see a programming problem that the design pattern solves,implemented in code. In other words, every design pattern is put to work ineasily understandable, runable code in this book.

In fact, some of the design patterns have already been put to work by thepeople who wrote the Java programming language. In such cases, I also dis-cuss the part of Java that implements the design pattern already — such asclosing windows in Swing or registering listeners with event-causing objects.Doing so gives you an immediate leg up with the design patterns covered —hey, you might find yourself saying: That looks familiar.

Foolish AssumptionsTo fully understand how each pattern can make your life easier, you need tosee it at work in a program, and this book uses the most widely used object-oriented programming language (Java) for its examples. For that reason, Iassume you know Java.

You don’t need to be a Java expert, though. If you can put together a programand work with objects, you’ll be okay. You don’t need to be a Java meister;the programming isn’t super-challenging. The idea is to show each pattern atwork with the easy-to-understand examples.

Besides Java, there’s no special knowledge or skill needed to read this book.You don’t have to know what patterns are or how they’re put to work. Allthat’s coming up in this book, from the most simple to the most powerful.

Conventions Used in This BookSome books have a dozen dizzying conventions that you need to know beforeyou can even start. Not this one. All you need to know is that new terms areshown in italics, like this, the first time they’re discussed. And when new linesof code are introduced, they’re displayed in bold, like this:

JButton button = new JButton(“Check Spelling”);JTextField text = new JTextField(30);

public void init(){

2 Design Patterns For Dummies

03_798541 intro.qxp 3/27/06 2:20 PM Page 2

Page 24: Design Patterns For Dummies

Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());...

button.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent event) {text.setText(“Good job.”);

}});

}

Note, also, that three vertical dots represent code that’s been omitted. That’sall there is to the notation in this book.

When I refer to something from the code, such as the name of an object orclass, I set it off using a monofont typeface like this: Call the draw method.

How This Book Is OrganizedHere are the various parts you see in this book:

Part I: Getting to Know PatternsPart I introduces patterns and how they make life easier. Chapter 1,“Congratulations, Your Problem Has Already Been Solved,” shows howpatterns fit into the scheme of things and how this book is going to makeyour programming problems easier to solve (no kidding). In the chaptersthat follow, you’re introduced to the Strategy, Factory, Observer, andSingleton patterns, and more as you get to know patterns and how towork with them.

Part II: Becoming an OOP MasterPatterns rely heavily on object-oriented programming (OOP), and in this part,you see how patterns let you take charge of object-oriented work. I show youhow to redefine steps of algorithms using subclasses with the TemplateMethod pattern, how to convert an object’s interface into a totally differentinterface with the Adapter pattern, how to handle object collections with theIterator and Composite patterns, how to coordinate objects with the Commandand Mediator patterns, and a great deal more in this part. After you read thispart, you’ll be an accomplished OOP meister.

3Introduction

03_798541 intro.qxp 3/27/06 2:20 PM Page 3

Page 25: Design Patterns For Dummies

Part III: The Part of TensChapter 11 tells you about the remainder of the standard patterns, some ofwhich are not in common use anymore, but all of which we cover in this book.Besides those standard patterns, you also see some newer patterns that havebeen added to the standard set of patterns, bringing us up to the modern day.Chapter 12 is all about joining the worldwide patterns community by creatingyour own pattern. You’re going to see how to abstract a pattern from a setof problem solutions in this chapter and what it takes to introduce your newpattern to the world.

Icons Used in This BookYou find a couple of icons in this book, and here’s what they mean:

This icon indicates something to remember, such as how you handle a partic-ularly tricky part of a pattern.

This icon gives you something more — a behind-the-scenes way of workingwith a pattern, for example.

This icon means that what follows is technical, insider stuff. You don’t haveto read it if you don’t want to, but if you want to become a pattern pro (andwho doesn’t?), take a look.

This icon tells you how not to fall into a pattern of trouble. Ignore this icon atyour peril.

Where to Go from HereAlright, you’re all set and ready to jump into Chapter 1. You don’t have tostart there; you can jump in anywhere you like — the book is written to allowyou to do just that. But if you want to get the full patterns story from thebeginning, jump into Chapter 1 first — that’s where all the action starts.

Also, for your convenience, all the code I provide in the book is available fordownloading at www.dummies.com/go/designpatternsfd1e.

4 Design Patterns For Dummies

03_798541 intro.qxp 3/27/06 2:20 PM Page 4

Page 26: Design Patterns For Dummies

Part IGetting to Know

Patterns

04_838183 pt01.qxp 3/27/06 2:21 PM Page 5

Page 27: Design Patterns For Dummies

In this part . . .

In this part, your guided tour of design patterns begins.Here, you see what patterns are all about. The idea

is that other programmers have faced the same issuesyou’re facing now and have come up with solutions thathave been well tested. Through the use of patterns, they share their solutions with you, saving you lots of time and effort.

04_838183 pt01.qxp 3/27/06 2:21 PM Page 6

Page 28: Design Patterns For Dummies

Chapter 1

Congratulations, Your ProblemHas Already Been Solved

In This Chapter� Introducing design patterns

� Knowing how design patterns can help

� Extending object-oriented programming

� Taking a look at some specific design patterns

As a programmer, you know how easy it can be to get lost in the detailsof what you’re doing. And when you lose the overview, you don’t plan

effectively, and you lose the bigger picture. When that happens, the codeyou’re writing in the trenches ends up working fine for a while, but unlessyou understand the bigger picture, that code really is a specialized solutionto a particular problem.

And the heck of it is that problems rarely stay solved after you’ve handledthem once. Developers typically regard their work as tackling individualproblems by writing code and solving those problems. But the truth is that inany professional environment, developers almost always end up spending alot more time on maintenance and adapting code to new situations than writ-ing entirely new code.

So if you consider it, it doesn’t make sense to think in terms of Band-Aid fixesto remedy the problems you face because you’ll end up spending a great dealof time putting out fires and trying to extend code written for a specific prob-lem so that it can handle other cases as well. It makes more sense to get alittle overview on the process of code design and maintenance.

05_798541 ch01.qxp 3/27/06 2:21 PM Page 7

Page 29: Design Patterns For Dummies

The idea behind this book is to familiarize you with a set of design patternsto simplify the programming process automatically. The plan is to get yousome overview automatically, no additional effort required. A design patternis a tested solution to a standard programming problem. When you’re famil-iar with the design patterns presented in this book, you can face a program-ming issue and — Bam! — a solution will come to you more quickly. Insteadof banging your head against the wall in desperation, you’ll say, “What Ineed here is the Factory pattern.” Or the Observer pattern. Or the Adapterpattern.

That’s not to say, as some design books seem to suggest, that you shouldspend a great deal of time dealing with abstractions and planning before tack-ling a project. Adding unneeded layers of abstraction to the programmingprocess is not a burden any programmer needs.

The whole beauty here is simply that someone has already faced the problemyou’re facing and has come up with a solution that implements all kinds ofgood design. And being familiar with design patterns can make the designprocess all but automatic for you.

How do you turn into a software design expert, the envy of all, with hardlyany work on your part? Easy. You read this book and get familiar with the pat-terns I cover in depth. You don’t have to memorize anything; you just get toknow those patterns. Then when you encounter a real-world issue thatmatches one of those patterns, something deep inside you says, “Hey! Thatlooks like you need the Iterator pattern.” And all you have to do is look upthat pattern in this book and leaf through the examples to know what to do.So without further ado, this chapter gets you started on your tour of thesehandy, helpful design patterns.

Just Find the Pattern that FitsThe charm of knowing about design patterns is that it makes your solutioneasily reusable, extendable, and maintainable. When you’re working on a pro-gramming problem, the tendency is to program to the problem, not in termsof reuse, extensibility, maintainability, or other good design issues. And that’swhere most programmers should be putting in more work because they endup spending far more time on such issues than on solving the original prob-lem in the long run.

8 Part I: Getting to Know Patterns

05_798541 ch01.qxp 3/27/06 2:21 PM Page 8

Page 30: Design Patterns For Dummies

For example, you may want to create Java objects that can, say, parse XMLdocuments. And to do that, you create a proprietary parser class, and theninstantiate objects of that class to create XML parser objects as needed. Sofar, so good, you think. But it turns out that there are dozens of XML parserclasses out there written in Java that people are attached to, and they mightwant to use the special features of the XML parser class they’re used to. Ifyou’d used the Factory pattern, you would have written code that could useany XML parser class to create parser objects (instead of hardcoding a pro-prietary solution). And your code would be extendable, reusable, and easierto maintain.

In other words, design patterns are solutions to programming problems thatautomatically implement good design techniques. Someone has already facedthe issues you’re facing, solved them, and is willing to show you what thebest techniques are. All without a lot of memorization on your part; all youhave to do is recognize which design pattern fits which situation and lock itinto place.

Sweet.

Enter the Gang of Four BookThe set of 23 standard design patterns was published by Erich Gamma,Richard Helm, Ralph Johnson, and John Vlissides in their seminal 1995 bookDesign Patterns: Elements of Reusable Object-Oriented Software (PearsonEducation, Inc. Publishing as Pearson Addison Wesley). They’ve come to beknown in programming circles as the Gang of Four, or, more popularly, GoF.

A lot of water has passed under the bridge since the GoF book appeared,and it turns out that some of the original 23 patterns were not used asmuch as some of the others. You see them all in this book, but I empha-size the patterns that are used the most — and that includes some new, non-GoF patterns in Chapter 11 that have appeared since the GoF bookdebuted.

It’s important to realize that there is more going on here than just memorizingdesign patterns. There are also specific design insights about object-orientedprogramming that are just as important, and I talk about them throughout thebook. OOP is a terrific advance in programming. But too many programmers

9Chapter 1: Congratulations, Your Problem Has Already Been Solved

05_798541 ch01.qxp 3/27/06 2:21 PM Page 9

Page 31: Design Patterns For Dummies

blindly apply its design strategies without a lot of insight, and that can causeas many problems as it fixes. A large part of understanding how to work withdesign patterns involves understanding the OOP insights behind them —encapsulating what changes most, for example, or knowing when to convertfrom is-a inheritance to has-a composites (see Chapter 2 for more on whatthese terms mean) — and I talk about those insights a lot.

Getting Started: The Mediator PatternFigure 1-1 provides an example design pattern, the Mediator pattern, thatshows what design patterns can do for you. Say that you’ve got a four-pageWeb site that lets users browse a store and make purchases. As things stand,the user can move from page to page. But there’s a problem — the code ineach page has to know when to jump to a new page as well as how to activatethe new page. You’ve got a lot of possible connections and a lot of duplicatecode in the various pages.

You can use a mediator here to encapsulate all the navigation code out of theseparate pages and place it into a mediator object instead. From then on,each page just has to report any change of state to the mediator, and themediator knows what page to send the user to, as shown in Figure 1-2.

Welcome Store

Purchase Goodbye

Figure 1-1:In this

illustrationof the basic

navigationof a typical

online store,the Mediator

patternmediatesbetweenobjects.

10 Part I: Getting to Know Patterns

05_798541 ch01.qxp 3/27/06 2:21 PM Page 10

Page 32: Design Patterns For Dummies

You can build the mediator to deal with the internals of each page so the vari-ous pages don’t have to know the intimate details of the other pages (such aswhich methods to call). And when it’s time to modify the navigation codethat takes users from page to page, that code is all collected in one place, soit’s easier to modify.

Adapting to the Adapter PatternHere’s another design pattern, the Adapter pattern. Say that for a long timeyou’ve been supplied with a stream of objects and fit them into code that canhandle those objects, as shown in Figure 1-3.

I‘m an old object I take old objects

Figure 1-3:Everything

seems to beworking

here.

Welcome Store

Purchase Goodbye

Mediator

Figure 1-2:The

mediatordirects Web

site traffic.

11Chapter 1: Congratulations, Your Problem Has Already Been Solved

05_798541 ch01.qxp 3/27/06 2:21 PM Page 11

Page 33: Design Patterns For Dummies

But now say there’s been an upgrade. The code isn’t expecting those oldobjects anymore, only new objects, and the old objects aren’t going to fitinto the new code, as shown in Figure 1-4.

If you can’t change how the old objects are generated in this case, theAdapter pattern has a solution — create an adapter object that exposesthe interface expected by the old object and the new code, and use theadapter to let the old object fit into the new code, as shown in Figure 1-5.

Problem solved. Who says design patterns are hard?

Standing In for Other Objectswith the Proxy Pattern

Here’s another pattern, the Proxy design pattern. Say that you’ve gotsome local code that’s used to dealing with a local object as shown inFigure 1-6:

I‘m an old object I am an oldto new Adapter

I only takenew objects

Figure 1-5:Old objects

work withnew objects

via anadapter.

I‘m an old object I only takenew objects

Figure 1-4:This isn’tgoing to

work.

12 Part I: Getting to Know Patterns

05_798541 ch01.qxp 3/27/06 2:21 PM Page 12

Page 34: Design Patterns For Dummies

But now say that you want to deal with some remote object, somewhere elsein the world. How can you make the local code think it’s dealing with a localobject still when in fact it’s working with that remote object?

With a proxy. A proxy is a stand-in for another object that makes the localcode think it’s dealing with a local object. Behind the scenes, the proxy con-nects to the remote object, all the while making the local code believe it’sworking with a local object, as you can see in Figure 1-7.

You see the Proxy pattern at work in Chapter 9 in an example that lets youconnect to a remote object over the Internet anywhere in the world, withjust a few lines of code.

Taking a Look at the Observer PatternYou’re most likely familiar with a number of the patterns in this book, such asthe Observer pattern. This pattern, like many others, is already implementedin Java.

Local code

Remote objectProxy

Figure 1-7:Trick your

local codeand remoteobject into

workingtogether.

Local code

Local object

Figure 1-6:Code and an

object,working

together inthe sameneighbor-

hood.

13Chapter 1: Congratulations, Your Problem Has Already Been Solved

05_798541 ch01.qxp 3/27/06 2:21 PM Page 13

Page 35: Design Patterns For Dummies

The Observer design pattern is about passing notifications around to updatea set of objects when some important event has occurred. You can add newobserver objects at runtime and remove them as needed. When an eventoccurs, all registered observers are notified. Figure 1-8 shows how it works;an observer can register itself with the subject.

And another observer, Observer 2, can register itself as well, as shown inFigure 1-9.

Now the subject is keeping track of two observers. When an event occurs,the subject notifies both observers. (See Figure 1-10.)

Subject Observer 1

Observer 2notification

notification

Figure 1-10:When

eventsoccur in the

subject,registeredobservers

are notified.

Subject Observer 1

Observer 2register

Figure 1-9:More

than oneobserver

can registerwith a

subject.

Subject Observer 1register

Figure 1-8:The

Observerpattern lets

observersregister with

subjects.

14 Part I: Getting to Know Patterns

05_798541 ch01.qxp 3/27/06 2:21 PM Page 14

Page 36: Design Patterns For Dummies

Does this sound familiar in Java? If Java event listeners came to mind, you’dbe right. Event listeners can register with objects like push buttons or win-dows to be informed of any events that occur.

That’s just one example of the kind of design pattern you’ve probably alreadyseen implemented in Java. When such examples come up, I include Javaexample code showing how a particular design pattern is already built intoJava. The example code might ring a few bells.

This book is written to be easy to use and understand. You’re not going tosee chalkboard diagrams of complex abstractions that you have to plowthrough. The chapters in this book are aimed at programmers, to be usefulfor programmers; even if you don’t read all of them, you’re going to benefit.The design insights and patterns covered here are becoming standardthroughout the programming world, and they are helpful on an everydaylevel. Hopefully, the next time you face a tough coding issue, you’ll suddenlyfind yourself saying: Aha! this is a job for the Facade pattern.

15Chapter 1: Congratulations, Your Problem Has Already Been Solved

05_798541 ch01.qxp 3/27/06 2:21 PM Page 15

Page 37: Design Patterns For Dummies

16 Part I: Getting to Know Patterns

05_798541 ch01.qxp 3/27/06 2:21 PM Page 16

Page 38: Design Patterns For Dummies

Chapter 2

Putting Plans into Actionwith the Strategy Pattern

In This Chapter� Extending object-oriented programming

� Getting to know abstraction, encapsulation, polymorphism, and inheritance

� Switching from “is-a” to “has-a”

� Handling tasks using algorithms

� Bringing the Strategy pattern to the rescue

As you, the design pattern expert, walk into the boardroom of MegaGigaCo,the CEO and members of the board are celebrating their new contract to

design a set of cars in the sedate way you’d expect — by high-fiving each otherand whooping around the room.

“This contract is going to mean a huge amount of income for us,” says theCEO, sloshing a little champagne on the boardroom table in his excitement.“All we’ve got to do is make sure we get the design process right.” He turnson the overhead projector, and as several large charts appear on the wall, theCEO says, “Now here’s my idea . . .”

“Wrong,” you say.

The CEO looks startled, and says, “But if we . . .”

“Nope,” you say, shaking your head.

“What . . .”

“Sorry,” you tell the CEO and the board, “it’s clear you’re risking your entirecontract by doing things the wrong way. I can see a dozen problems just look-ing at that chart.”

06_798541 ch02.qxp 3/27/06 2:21 PM Page 17

Page 39: Design Patterns For Dummies

The board murmurs with concern and the CEO asks, “And you are?”

“I’m the design pattern pro who’s going to solve all your design problems,”you say. “For a whopping fee, of course.”

The CEO writes down a tentative figure for your fee that, while large, doesn’tseem large enough to you.

“Wrong again,” you say.

The CEO looks at you with raised eyebrows.

“Design patterns,” you explain, “represent solutions to known programmingproblems. Not only that, but they also represent good programming practice,making maintenance and extension of your code that much easier. So as youcan see, hiring an expert like me makes a lot of sense — when I see a pro-gramming problem that has already been solved with a design pattern, I cantell you all about it.”

“Well,” the company programmers say reluctantly, “the idea behind designpatterns sounds okay. But we already use object-oriented techniques in ourprogramming. Doesn’t that already cover the problem?”

“Nope,” you say. In fact, that’s one of the main points behind design patterns —they extend object-oriented programming (OOP).

Extending Object-Oriented ProgrammingNote the subtitle of the Gang of Four’s Design Patterns: Elements of ReusableObject-Oriented Software (1995, Pearson Education, Inc. Publishing as PearsonAddison Wesley). Reuse is an important aspect of working with design pat-terns, and so is handling OOP issues. I discuss OOP first in this chapter, andthen you’ll see how working with OOP issues fits in with the Strategy pattern.

OOP was originally introduced as programs became larger and more com-plex. The idea was to wrap functionality inside objects. In other words, theinspiration was to divide and conquer. Until OOP appeared, you could divideyour code into functions, but that wasn’t enough in the long run. As pro-grams became longer and longer, some way of dividing them up in terms ofeasily handled concepts was needed. What those concepts were, dependedon the program itself, and those concepts came to be known as objects.

18 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 18

Page 40: Design Patterns For Dummies

For example, if you take a look at what’s going on in a kitchen behind thescenes, there’s an enormous amount of complexity. A refrigerator can con-tain coolant pumps, thermostats, fans, lights, and more. A stove can containvarious heating elements, timers, thermostats, lights, and more. Consideredthis way, looking at every present element at once, a kitchen becomes verycomplex.

But if you wrap what you see up into objects, the situation is a lot easier tohandle. There’s the refrigerator. There’s the stove. That’s the dishwasher, andso on. No problem — internal regulation and the various parts that worktogether are wrapped up into an easily conceptualized object.

That’s why objects are called objects in object-oriented programming — youwrap functionality up into those objects and they’re easily conceptualized,much like refrigerators, stoves, dishwashers, and so on. Exactly what thoseobjects are, is up to you (which is why they’re just generically called objects,and why you’ve never heard of refrigerator-oriented programming or stove-oriented programming).

For example, in a program, you may have an object named display that han-dles all the aspects of displaying your application’s results. Another objectmight be named database to interact with a database server, and so forth.There can be a lot of complexity inside each object, but when you wrapeverything up in a set of objects, life becomes a lot easier. You can work interms of the display object and the few simple methods it exposes, not thesetRasterScanRate, populateVideoBuffer, adjustHorizontalHoldand dozens of other functions. That makes the programming a lot easier,which is why OOP became important as programs became longer and longer.

The big four OOP building blocksThere are four pillars of OOP — abstraction, encapsulation, polymorphism,and inheritance. I discuss these in the following sections.

Abstraction is the good kind of breakdownA good part of working with design patterns involves abstraction — the care-ful consideration of how you’re going to handle the problem. Abstractionisn’t a programming technique; in essence, it just means that you conceptual-ize a problem before applying OOP techniques.

Abstraction is all about breaking your approach to a problem into naturalsegments. This is where you come up with the objects that divide the prob-lem into manageable parts. In other words, abstracting a problem simply

19Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 19

Page 41: Design Patterns For Dummies

means thinking of how to tackle that problem in terms of object-orientedcode. The data items needed by each object become that object’s properties,whether public or private, and the actions each object needs to perform inthe real world become its actions in code.

Much of what design patterns are all about has to do with making sure you’resetting up the way you attack the problem correctly. Working with design pat-terns often means spending more time on the abstraction part of the processthan on the concrete classes part.

Encapsulating all that junkWhen you wrap methods and data up into an object, you encapsulate thosemethods and data. That’s the power of working with objects — you removethe complexity from view and make it into an easily graspable object. That’show a mass of pipes, tubing, pumps, thermostats, and lights becomes, con-ceptually, a refrigerator.

When you encapsulate functionality into an object, you decide what interfacethat object exposes to the world. That refrigerator may handle a lot of complexactions behind the scenes, but you might want to put a dial in it to let the usertell the appliance how cold he wants his food. In the same way, you decidewhat getter and setter methods and/or public properties your objects presentto the rest of the application so that the application can interact with it.

That’s the idea behind encapsulation — you hide the complexities insideobjects and then create a simple interface to let that object interact with therest of your code. Design patterns are particularly big on encapsulation. One ofthe primary design insights here is that you should encapsulate what changesthe most. A number of patterns revolve around that idea — extracting the partof your code that changes the most, or that needs the most maintenance, andencapsulating that part into its own object for easier handling. You see a lotabout encapsulation and how to put it to work in unexpected ways to solvecommon problems in this book.

Mighty polymorphism rangersAnother cornerstone of OOP is polymorphism: the ability to write code thatcan work with different object types and decide on the actual object type atruntime. For example, you might want to write code that handles all kinds ofdifferent shapes — rectangles, circles, triangles, and so on. Although they’redifferent shapes, they all have in common certain actions as far as your codegoes — for example, they can all be drawn.

20 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 20

Page 42: Design Patterns For Dummies

Using polymorphism, you can write your code to perform various actions onthe shapes you’re working with — and then decide on the actual shape(s)you want to use at runtime. Polymorphic (which means many form) codeworks with any such shape without being rewritten.

Start with this Shape class that draws a generic shape when you call its drawmethod:

class Shape{public void draw(){System.out.println(“Drawing a shape.”);

}}

Then you extend a new class, Rectangle, from Shape, and let it draw a rec-tangle when you call its draw method as follows:

class Rectangle extends Shape{public void draw(){System.out.println(“Drawing a rectangle.”);

}}

Want to draw a shape? No problem. You just write some code to create anobject named shape and call the object’s draw method:

public class Polymorphism{

public static void main(String[] args){Shape shape = new Shape();

shape.draw();}

}

Running this example gives you this:

Drawing a shape.

21Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 21

Page 43: Design Patterns For Dummies

Want to draw a rectangle using the same code? No problem. Through themagic of polymorphism, just reload the shape variable with a rectangleobject instead and then proceed with the same code as before:

public class Polymorphism{

public static void main(String[] args){Shape shape = new Shape();shape = new Rectangle();

shape.draw();}

}

Running this code gives you:

Drawing a rectangle.

In the first case, you loaded a shape object into the shape variable and thencalled its draw method. In the second case, you took a rectangle objectand loaded it into that same variable, shape — even though that variablewas declared to be a shape object — and then called the draw methodagain to draw a rectangle.

So you used the same variable, shape, to hold a shape object and a rectangle object, which works because rectangle is derived fromshape. In this way, you can decide what type of object to load into theshape variable at runtime, leaving your code unchanged.

Inheritance without the pesky taxesThe last of the formal cornerstones of OOP is inheritance: the process bywhich one class can inherit methods and properties from another. You justsaw inheritance at work (in the previous section) — starting with the Shapeclass as shown here:

class Shape{public void draw(){System.out.println(“Drawing a shape.”);

}}

22 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 22

Page 44: Design Patterns For Dummies

Then deriving the Rectangle class from Shape, as you see here:

class Rectangle extends Shape{public void draw(){System.out.println(“Drawing a rectangle.”);

}}

Polymorphism often comes into play when you work with design patternsbecause design patterns tend to favor composition over inheritance. (You usecomposition when your object contains other objects instead of inheritingfrom them.) Inheritance sets up “is-a” relationships — Rectangle “is-a” Shape,for example. As you’re going to see, however, that can introduce unexpectedrigidity and problems into your code, especially when it comes time to main-tain that code.

Design pattern-oriented programming often prefers object composition overinheritance. When you use composition, your code contains other objects,rather than inheriting from them. And to be supple enough to deal with thevarious kinds of contained objects in the same way, with the same code,design-patterns often rely on polymorphism.

Composition versus inheritance: A firstattempt at designing the new carsSo who says that you should favor composition over inheritance? Perhaps anexample will help. The programmers at MegaGigaCo (from the beginning ofthe chapter) know all about inheritance, and they’ve started designing thenew cars despite your warnings to wait until you’ve had the chance to talkwith them. They know they’re supposed to be designing a series of vehicles,so they’ve started by creating a base class named Vehicle with a methodnamed go that displays the text Now I’m driving.

public abstract class Vehicle {public Vehicle() {}

public void go() {System.out.println(“Now I’m driving.”);

}}

23Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 23

Page 45: Design Patterns For Dummies

Then they’ve created new classes, such as StreetRacer, using Vehicle asa base class like so:

public class StreetRacer extends Vehicle {public StreetRacer() {}

}

So far, so good. If you create a new StreetRacer and run it like this:

public static void main(String[] args) {StreetRacer streetRacer = new StreetRacer();

streetRacer.go();...

}

Then you’re going to see:

Now I’m driving.

That looks fine. So fine, in fact, that MegaGigaCo decides to run with it andcomes out with a Formula One racer that also extends the Vehicle class asyou can see in the following:

public class FormulaOne extends Vehicle {public FormulaOne() {}

}

And you can run both the street racer and the Formula One racer this way:

public static void main(String[] args) {StreetRacer streetRacer = new StreetRacer();FormulaOne formulaOne = new FormulaOne();

streetRacer.go();formulaOne.go();

.

.

.}

24 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 24

Page 46: Design Patterns For Dummies

And you get:

Now I’m driving.Now I’m driving.

Not bad, say the CEO and the board. Who needs design patterns? they ask,shooting you dirty looks. But then they get a contract to produce helicopters.Helicopters, they reason, are just another type of vehicle. So they create heli-copters using a Helicopter class, extending the Vehicle class like this:

public class Helicopter extends Vehicle {public Helicopter() {}

}

But now there’s a problem — if you run the helicopter in addition to the carslike this:

public static void main(String[] args) {StreetRacer streetRacer = new StreetRacer();FormulaOne formulaOne = new FormulaOne();Helicopter helicopter = new Helicopter();

streetRacer.go();formulaOne.go();helicopter.go();

.

.

.}

Then you get this when you run all three vehicles: one street racer, oneFormula One race car, and one helicopter:

Now I’m driving.Now I’m driving.Now I’m driving.

That doesn’t look right, says the CEO doubtfully. Why should the helicopterbe driving? Shouldn’t it be flying? And the problem only gets worse whenMegaGigaCo gets a contract to produce jets, which they also extend from theVehicle class:

public class Jet extends Vehicle {public Jet() {}

}

25Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 25

Page 47: Design Patterns For Dummies

Running all four vehicles — street racer, Formula One race car, helicopter,and jet, now gives you this:

Now I’m driving.Now I’m driving.Now I’m driving.Now I’m driving.

That’s definitely not right, says the CEO. Jets don’t drive when they’re in theair. They fly — and fast. No problem, say the company programmers. We canjust override the go method in the Helicopter and Jet classes to give theright behavior. They create something like this, which makes theHelicopter class fly, not drive:

public class Helicopter extends Vehicle {public Helicopter() {}

public void go() {System.out.println(“Now I’m flying.”);

}}

“Okay,” says the CEO, “but the board of directors has already voted tochange that from ‘Now I’m flying.’ to ‘Now I’m flying at 200 mph’ next week.And more changes will be coming later, if I know them.”

There’s a problem here, you explain, and it’s that the company programmersare spreading the way a single task is accomplished — driving a car or flyinga helicopter — across several generations of classes. That’s not necessarily abig problem, but if how you want to handle that task is going to change fairlyoften, as here, having to edit all those classes becomes a maintenance issue.

You say: maybe inheritance isn’t the answer in a case like this, where youhave to spread out the handling of a changeable task over several generationsof classes. You’re going to be maintaining a lot of customized code across gen-erations of classes when that task changes. And as the derived classes get tobe long and involved, it’s going to be tough to maintain them through allthose changes. You’re going to have to update the go method forever.

The problem you’re trying to solve is how to avoid spreading out the han-dling of a particular, changeable task over several generations of classes. Ifyou don’t avoid that, you’ll be editing a lot of files to update your code.

26 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 26

Page 48: Design Patterns For Dummies

Perhaps there’s a better way of handling the task of making vehicles movethan using inheritance in this case. Hey, says a company programmer — howabout using interfaces instead of using inheritance? You could set up an IFlyinterface and give that interface a method named go that the Helicopterclass has to implement as shown in the following:

public class Helicopter implements IFly {public Helicopter() {}

public void go() {System.out.println(“Now I’m flying.”);

}}

No good, you say. You haven’t solved the problem at all — each class andsubclass still has to implement its own version of the go method, which isjust as bad as when you used inheritance. And because interfaces don’tinclude code, you still have to write custom code in each class, which meanscode reuse goes out the window.

Handling Change with “has-a” Instead of “is-a”

Things change. In commercial development, things change a lot, so it’s worth-while planning for it. If you’ve got a small problem that needs a small solution,you probably won’t have to plan for a great deal of change. But if you’re work-ing on a serious project of some substantial size and it’s going to be around fora while, you should start thinking in terms of change. The requirements yourcode must meet will vary over time, and you will have to modify your code atsome point in the future to handle those evolving requirements. Most develop-ers don’t take this potential for change into account, and they invariably regretit later. How big does a project have to be before you should code to allow forgraceful change? That’s a judgment call, part of the art of programming. Byunderstanding how to handle change, you’ll know better when to allow for it.

Here’s a design insight that you may have seen mentioned: Separate the partsof your code that will change the most from the rest of your application andtry to make them as freestanding as possible for easy maintenance. Youshould also always try to reuse those parts as much as possible.

27Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 27

Page 49: Design Patterns For Dummies

What this means is that if part of your application changes a lot, get it out ofthose large files that otherwise change very little and make the sections thatchange a lot as freestanding as you can so that you can make changes aseasily as possible while reducing side effects. And if you can, reuse the sepa-rated components that change a lot so that if you need to make a change,that change will be made automatically throughout the many places in thecode that use those components.

Here’s how to think about this way of planning for change, and why inheri-tance often can’t handle change very well. With inheritance, base classes andderived classes have an “is-a” relationship. That is, a Helicopter “is-a” Vehicle,which means Helicopter inherits from Vehicle, and if you have to customizethe methods you inherit a great deal, you’re going to run up against mainte-nance issues in the future. The base class handles a particular task one way,but then a derived class changes that, and the next derived class down theline changes things yet again. So you’ve spread out how you handle a taskover several generations of classes.

If, on the other hand, you can extract the volatile parts of your code andencapsulate them as objects, you can use those objects as you need them —and the entire task is handled by the code in such an object, it’s not spreadout over generations of classes. Doing so allows you to customize your codeby creating composites of objects. With composites, you select and use theobjects you want, instead of having a rigid hard-coded internal way of doingthings. That gives you a “has-a” relationship with those objects — a streetracer “has-a” certain way of moving, which is encapsulated in an object; ahelicopter “has-a” different way of moving, which is also encapsulated in anobject. And each object performs a task.

One object, one task often makes sense instead of writing multi-generationcode where one task is spread out over a dozen generations. In other words,you’re reorganizing around the tasks, not around the generations of classesthat inheritance gives you.

Using inheritance automatically sets things up in terms of strict, inclusive “is-a” relationships, which is more likely to cause maintenance and extensibil-ity issues down the line. If you want to plan for change, it usually helps tothink as much as you can in terms of “has-a” relationships, where your codehas a number of objects whose code can be more easily updated as changehappens.

When planning for change, consider “has-a” instead of “is-a” relationships,and put volatile code in the objects your application contains, rather thaninheriting that code.

28 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 28

Page 50: Design Patterns For Dummies

Drawing Up Your PlansHow would the idea of separating out volatile code work in the Vehicle/StreetRacer/Helicopter example in this chapter? According to the CEO,the part that is going to be changing the most is the go method, so that’s thepart to separate out. In design pattern terms, each implementation of the gomethod is called an algorithm (basically that’s just another name for a strat-egy). So you want to create a set of algorithms that can be used by your vari-ous StreetRacer, FormulaOne, Helicopter, and Jet objects. Doing soseparates the volatile code into algorithms. Each algorithm handles onecomplete task, so you don’t have to spread out the handling of that taskover generations of classes.

Creating your algorithmsTo make sure that all the algorithms implement the same methods (that’s justthe go method here), you need to create an interface, the GoAlgorithminterface, which all algorithms must implement:

public interface GoAlgorithm {public void go();

}

The GoAlgorithm interface has one method: go. To make sure any algo-rithm can be used by any Vehicle, all algorithms should implement thisinterface, which means they all have to define a go method. The first algo-rithm, GoByDrivingAlgorithm, displays Now I’m driving. Here’s whatthe GoByDrivingAlgorithm looks like:

public class GoByDrivingAlgorithm implements GoAlgorithm {public void go() {System.out.println(“Now I’m driving.”);

}}

The GoByFlying algorithm, on the other hand, displays Now I’m flying.

public class GoByFlying implements GoAlgorithm {public void go() {System.out.println(“Now I’m flying.”);

}}

29Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 29

Page 51: Design Patterns For Dummies

And the GoByFlyingFast algorithm, used by jets, displays Now I’mflying fast.

public class GoByFlyingFast implements GoAlgorithm {public void go() {System.out.println(“Now I’m flying fast.”);

}}

Great. You just separated algorithms from your code. You’re starting to imple-ment “has-a” rather than “is-a” design techniques. Now you’ve got to putthose algorithms to work.

Using your algorithmsNow you’ve got a number of algorithms you can create objects from in orderto build your code using “has-a”, not “is-a”, relationships. After you create anobject from an algorithm, you’ve got to store that object somewhere, so I’lladd a new method to the Vehicle base class, setGoAlgorithm. Thatmethod stores the algorithm you want to use in an internal, private variable,goAlgorithm as shown in the following:

public abstract class Vehicle {private GoAlgorithm goAlgorithm;

public Vehicle() {}

public void setGoAlgorithm (GoAlgorithm algorithm) {goAlgorithm = algorithm;

}...

}

Now when you want to use a particular algorithm in a derived class, allyou’ve got to do is to call the setGoAlgorithm method with the correctalgorithm object, this way:

setGoAlgorithm(new GoByDrivingAlgorithm());

30 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 30

Page 52: Design Patterns For Dummies

The Vehicle class’s go method also has to change. Previously, it just dis-played the message Now I’m driving.

public void go() {System.out.println(“Now I’m driving.”);

}

Now, however, it has to call the go method defined in the algorithm, so here’show the new code works:

public abstract class Vehicle {private GoAlgorithm goAlgorithm;

public Vehicle() {}

public void setGoAlgorithm (GoAlgorithm algorithm) {goAlgorithm = algorithm;

}

public void go() {goAlgorithm.go();

}}

Now all you have to do is select which algorithm you want to use for whichvehicle. For example, the street racer will use GoByDrivingAlgorithm:

public class StreetRacer extends Vehicle {public StreetRacer() {setGoAlgorithm(new GoByDrivingAlgorithm());

}}

The Formula One race car will also use GoByDrivingAlgorithm:

public class FormulaOne extends Vehicle {public FormulaOne() {setGoAlgorithm(new GoByDrivingAlgorithm());

}}

31Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 31

Page 53: Design Patterns For Dummies

But the helicopter will use GoByFlyingAlgorithm:

public class Helicopter extends Vehicle {public Helicopter() {setGoAlgorithm(new GoByFlyingAlgorithm());

}}

And the jet will use GoByFlyingFastAlgorithm:

public class Jet extends Vehicle {public Jet() {setGoAlgorithm(new GoByFlyingFastAlgorithm());

}}

It’s time to put this to the test. Just compile and run StartTheRace.java,as well as the needed Helicopter.java, Jet.java, and other files in thedownloadable code for this book. StartTheRace.java creates an object ofeach vehicle type and calls each go method:

public class StartTheRace{

public static void main(String[] args) {StreetRacer streetRacer = new StreetRacer();FormulaOne formulaOne = new FormulaOne();Helicopter helicopter = new Helicopter();Jet jet = new Jet();

streetRacer.go();formulaOne.go();helicopter.go();jet.go();

}}

And here’s what you get:

Now I’m driving.Now I’m driving.Now I’m flying.Now I’m flying fast.

32 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 32

Page 54: Design Patterns For Dummies

Just what you wanted, except now you’re using “has-a” relationships insteadof inheritance-based “is-a” relationships. All kinds of code can use these algo-rithms because the code in these algorithms is no longer buried in theStreetRacer, Helicopter, and other classes.

This technique gives you an alternative to subclassing and inheritance. If youuse “is-a” inheritance, you may end up spreading out how you handle a par-ticular task in the base class and all derived classes — as when you overrodethe go method for helicopters and jets. If you use the “has-a” model, you cancreate a well-defined family of algorithms — as many as you need — and thenchoose the algorithm you want to use.

In this way, you’re been able to overcome a problem that inheritance causesfor many programmers: If you have to spread out how you handle a taskacross several generations of classes, and how you handle that task changesa lot, you’re going to be editing a lot of code as you maintain it. If, on theother hand, you can concentrate how you handle that task into a single algo-rithm object, changes will be a lot easier to handle.

The board of directors says the message should change from Now I’mflying. to Now I’m flying at 200 mph. No problem, just change thatin the GoByFlying algorithm:

public class GoByFlying implements GoAlgorithm {public void go() {System.out.println(“Now I’m flying at 200 mph.”);

}}

Now all the code that uses this algorithm is updated automatically; no needto go searching through a lot of class files. In this way, when you concentratehow you handle a task into a single algorithm object, you have a lot morecontrol over that task, especially when you want to make changes to it.

Selecting algorithms at runtime“Wait a minute,” the CEO of MegaGigaCo says. “It occurs to me that jets don’tjust ‘fly fast.’ They drive for a while along the runway first. And when theyland, they drive along the runway too. So shouldn’t their behavior be drive,fly fast, and then drive again?”

“Theoretically, yes,” groan the company programmers. “But that would take alot of extra code.”

33Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 33

Page 55: Design Patterns For Dummies

“Not at all,” you say. “That’s one of the charms of using external algorithmobjects — you can change the behavior you want at runtime.”

When you hardcode a task into your class files, you can’t switch tasks at run-time. But when you use external algorithm objects in a “has-a” relationship,it’s easy to switch at runtime. In other words, the “has-a” relationship cangive you more flexibility than the “is-a” relationship when it comes to config-uring behavior at runtime.

Here’s how selecting algorithms dynamically works in a new example,RealJet.java. To make the jet taxi, you create a new Jet object and set thejet’s algorithm to the GoByDrivingAlgorithm, as shown in the followingcode:

public class RealJet{

public static void main(String[] args) {Jet jet = new Jet();

jet.setGoAlgorithm(new GoByDrivingAlgorithm());...

}

To make the jet drive along the runway, use its go method:

public class RealJet{

public static void main(String[] args) {Jet jet = new Jet();

jet.setGoAlgorithm(new GoByDrivingAlgorithm());jet.go();

.

.

.}

34 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 34

Page 56: Design Patterns For Dummies

You can call the jet’s setGoAlgorithm to change the jet’s go algorithmdynamically, then call the go method again after each time you change thatalgorithm:

public class RealJet{

public static void main(String[] args) {Jet jet = new Jet();

jet.setGoAlgorithm(new GoByDrivingAlgorithm());jet.go();

jet.setGoAlgorithm(new GoByFlyingFastAlgorithm());jet.go();

jet.setGoAlgorithm(new GoByDrivingAlgorithm());jet.go();

}}

Here are the results — the jet taxis, flies, and then taxis again, no problem:

Now I’m driving.Now I’m flying fast.Now I’m driving.

As you see, switching algorithms at runtime is no problem. On the otherhand, if you had hardcoded specific behavior into the jet, there would havebeen no way to change it at runtime. In other words, you can set the strategyyou want to use at runtime. All of which brings us to the design pattern forthis chapter, which this chapter’s whole discussion has really been about —the Strategy design pattern.

Making Your Move withthe Strategy Pattern

The Strategy design pattern is the first one covered in this book, and in factyou’ve seen it at work throughout this chapter already. This design principlecomes into play when it makes sense to extract code that handles specifictasks from your app.

35Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 35

Page 57: Design Patterns For Dummies

Creating a family of algorithms lets you choose your strategy by choosingconsciously which algorithm(s) you want to work with. This design pattern isoften used as an alternative to inheritance, where you can end up spreadingout the way you handle one specific task over many class files.

Here’s the problem, in general. You may find yourself implementing a singletask across several generations of classes. At first, everything is fine, youhandle the task in one class alone, as shown in Figure 2-1.

But as time goes on, special cases seem to require new classes, and youuse inheritance and overriding code in the inheriting classes, spreading theway you handle the single task across a number of inheriting classes (seeFigure 2-2).

doTask(){}

doTask(){ Overriding code}

doTask(){ More overriding code}

Figure 2-2:Adding

tasksrequires

rewritingcode.

doTask(){}

Figure 2-1:One object,

one task.

36 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 36

Page 58: Design Patterns For Dummies

The Strategy design pattern says that you should extract the volatile parts ofyour code and encapsulate them as objects; you can use those objects as youneed them. Now you can customize your code by creating composites ofobjects. At runtime, you just use polymorphism to choose the object(s) youwant to work with, as shown in Figure 2-3.

The GoF book says the Strategy design pattern should: “Define a family ofalgorithms, encapsulate each one, and make them interchangeable. Strategylets the algorithm vary independently from clients that use it.”

The Strategy design pattern points out that, sometimes, it’s good to be task-oriented. That’s especially important if you want to maintain volatile codeaway from the main code for your app, or if you want to change the algorithmyou use at runtime.

Consider using the Strategy design pattern if you have one of the followingsituations:

� You have volatile code that you can separate out of your application foreasy maintenance.

� You want to avoid muddling how you handle a task by having to splitimplementation code over several inherited classes.

� You want to change the algorithm you use for a task at runtime.

So there you have it — any time you start to get task-oriented and want tomake those tasks one of the main design points of your code, the Strategydesign pattern should spring to mind. That’s the way design patterns work.They don’t provide you with specific code. Instead, you familiarize yourselfwith the idea, and when that idea could come in handy there’s an Aha!moment. This looks like a job for the Strategy pattern!

Your code Algorithm object 1

Algorithm object 2

Algorithm object 3

Algorithm object 4

Algorithm variable

Figure 2-3:The

Strategypattern

saves youtime in the

long run.

37Chapter 2: Putting Plans into Action with the Strategy Pattern

06_798541 ch02.qxp 3/27/06 2:21 PM Page 37

Page 59: Design Patterns For Dummies

Knowing how various design patterns work also gives you a way of talking toother people who are familiar with those design patterns. Most professionalprogrammers should know at least some standard design patterns. Whensomeone on your team starts talking about using the Strategy design patternand everyone starts nodding knowingly, you want to be able to nod knowinglyas well.

38 Part I: Getting to Know Patterns

06_798541 ch02.qxp 3/27/06 2:21 PM Page 38

Page 60: Design Patterns For Dummies

Chapter 3

Creating and Extending Objectswith the Decorator and

Factory PatternsIn This Chapter� Keeping code closed for modification, open for extension

� Introducing the Decorator pattern

� Creating your own decorators

� Wrapping objects in decorators

� Building objects with factories

� Encapsulating object creation in factories

� Using the Factory Method pattern

You’re on the job as the new Design Pattern consultant at GigantoComputercompany, getting paid an exorbitant amount of money, and you’re in the

company cafeteria.

“What’ll you have?” asks the surly cook behind the grill counter.

“A burger,” you say, wrestling with your tray.

The cook rings it up on the cash register, and then remembers to ask, “Frieswith that?”

“Sure,” you say.

The cook clears the order on the cash register and starts over, saying,“Burger and fries,” and enters that.

07_798541 ch03.qxp 3/27/06 2:21 PM Page 39

Page 61: Design Patterns For Dummies

“Let’s make that a cheeseburger,” you say on impulse.

The cook gives you a dirty look and starts the order over from scratch, peck-ing at the keyboard and saying, “Burger with cheese and fries. Okay. That it?”

“Hmm,” you say, scanning the posted menu. “Maybe make that a baconcheeseburger.”

The cook stares at you and seems on the verge of saying something unpleas-ant, but enters the order into the cash register, starting the whole processover.

“Hey,” you say, “you sure could benefit by using the Decorator design pat-tern, eh?”

“Yeah,” says the cook, wondering what you’re talking about. “I’ve said thesame thing a thousand times.”

You take your bacon cheeseburger with fries happily, and ask, “How aboutsome tomato slices on that?”

This chapter is all about two important design patterns that take care offlaws in standard object-oriented programming, especially when it comes toinheritance: the Decorator and Factory patterns.

The Decorator pattern is perfect for the opening scenario I just outlinedbecause it’s all about extending the functionality of a given class. After you’vewritten a class, you can add decorators (additional classes) to extend thatclass; doing so means that you won’t have to keep modifying the originalclass’s code over and over again. So your burger can become a cheeseburger,and then a bacon cheeseburger, with no extra trouble.

As I discuss later in the chapter the Factory design pattern is a well-knownand popular one, which does something a little different. Using this designpattern lets you improve the Java new operator by giving you a lot more flexi-bility when you create new objects. When you use this pattern, you use yourown code to create new objects; you don’t use just the new operator. There’san interesting twist here, though: what a lot of programmers think of as theFactory design pattern is not the actual Gang of Four (GoF) Factory designpattern. I look at both the popular and formal versions of the Factory designpattern in this chapter.

Note: For more on OOP, you might take a look at Java All-In-One DeskReference For Dummies, by Doug Lowe, Wiley Publishing, Inc. But we’re notgoing to tackle more OOP than you have already encountered as a Java pro-grammer in any case.

40 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 40

Page 62: Design Patterns For Dummies

Closed for Modification,Open for Extension

One of the most important aspects of the development process that develop-ers and programmers have to grapple with is change, which is why designpatterns were introduced in the first place. In particular, design patterns areintended to help you handle change as you have to adapt your code to newand unforeseen circumstances. As I mention throughout this book, develop-ers spend much more time extending and changing code than they do origi-nally developing it.

The Strategy design pattern introduced in Chapter 2 is all about helping youhandle change by letting you select from a family of external algorithmsrather than having to rewrite your code. The Decorator pattern is similar, inthat it allows you to write your code and avoid modification, while stillextending that code if needed. That’s one of the major design points that Iwant to emphasize.

As much as possible, make your code closed for modification, but open forextension. In other words, design your core code so that it doesn’t have to bemodified a lot, but may be extended as needed.

Here’s an example that makes keeping your core code closed for modificationmore clear. Say that the company you’re working for as a consultant,GigantoComputer, decides to make a new computer. Here’s the code for theComputer class:

public class Computer {public Computer(){}

public String description(){return “You’re getting a computer.”;

}}

When a new computer object is created, its description method returnsthe text You’re getting a computer. So far, so good. But some cus-tomers decide that they want a hard disk in their computers. “No problem,”the company programmers say. “We can just change the code this way”:

41Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 41

Page 63: Design Patterns For Dummies

public class Computer {public Computer(){}

public String description(){return “You’re getting a computer and a disk.”;

}}

Now when a new computer object is created and you call its descriptionmethod, you get the text You’re getting a computer and a disk.But some customers are never satisfied — they want a monitor too. So thecompany programmers change the code again to this:

public class Computer {public Computer(){}

public String description(){return “You’re getting a computer and a disk and a monitor.”;

}}

Now when you create a computer object and call its description method,you’ll see:

You’re getting a computer and a disk and a monitor.

You can see the issue here: The company programmers have to change thecode every time someone wants to customize his or her computer purchase.Obviously, that’s a problem.

And you, the high-power design patterns consultant, can fix it.

Enter the Decorator PatternI can’t say this enough, and to prove it, I’m going to say it again: As much aspossible, make your code closed for modification but open for extension.In Chapter 2, you get an idea how that works with the Strategy design pat-tern. There, you encapsulate code in external algorithms for easy use ratherthan spreading it around inside your core code and modifying it throughoutthat code.

42 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 42

Page 64: Design Patterns For Dummies

The Decorator design pattern takes a different approach. Instead of usingexternal algorithms, this design pattern is all about using wrapper code toextend your core code.

The formal definition of the Decorator pattern from the GoF book (DesignPatterns: Elements of Reusable Object-Oriented Software, 1995, PearsonEducation, Inc. Publishing as Pearson Addison Wesley) says you can,“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.”

This design pattern is called Decorator but that seems to imply optional frills.A better name for this pattern might be the “Augmentor” or “Extender” pat-tern because that’s what it allows you to do: augment or extend a classdynamically at runtime. However, as you see in this chapter, the termDecorator does apply once you understand the concept of “closed for modifi-cation, open for extension.” When you use wrapper code to extend your corefunctionality and you don’t need to modify that core functionality, you areessentially decorating the code.

Here’s how it works. You might start with a core computer, like the one illus-trated in Figure 3-1.

When you call the description method in this example, you get a returnvalue of You’re getting a computer. Now let’s say you want to addmore hardware — a disk, for example. In this case, you can add a wrapper asshown in Figure 3-2.

Computerdescription()

Diskdescription()

Figure 3-2:Next, you

add a diskdrive.

Computerdescription()

Figure 3-1:You start

with a corecomputer.

43Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 43

Page 65: Design Patterns For Dummies

Now when you call the wrapper’s description method, it calls the com-puter object’s description method to get the string You’re getting acomputer and adds and a disk to that string to give you You’re get-ting a computer and a disk.

If you want to add more to the computer, you just place it in another wrapper,such as a Monitor wrapper, as shown in Figure 3-3.

Now when you call the resulting object’s description method, the follow-ing occurs in this order:

1. The object’s description method calls the Disk wrapper’s descrip-tion method.

2. The Disk wrapper’s description method calls the computer object’sdescription method.

3. The computer object’s description method returns the text You’regetting a computer and a disk.

4. The Monitor wrapper’s description object then adds and a moni-tor to give you the resulting final string, You’re getting a com-puter and a disk and a monitor.

Alright, let’s see what this looks like in code.

Computerdescription()

Diskdescription()

Monitordescription()

Figure 3-3:Finally, you

add amonitor to

thecomputer.

44 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 44

Page 66: Design Patterns For Dummies

Putting the Decorator Pattern to WorkYou can start slinging some code by creating the core component, which isthe computer in this example. Here’s what that looks like — note that thedescription method just returns the plain text, computer.

public class Computer {public Computer(){}

public String description(){return “computer”;

}}

Alright, that’s the core component: the computer itself. Now how aboutcreating some decorator classes? Such classes have to act as wrappers forthe Computer class, which means that variables that can hold computerobjects should also be able to hold objects that wrap computer objects.And one easy way to make sure that can happen is to extend the wrapperclasses from the Computer class.

Creating a decoratorYou might start by creating an abstract class that all Computer class wrap-pers have to extend (remember, an abstract class is one that can’t be used tocreate objects directly, but must be inherited from to create a concreteclass). Here’s what that abstract class looks like:

public abstract class ComponentDecorator extends Computer{public abstract String description();

}

This class, ComponentDecorator, has one abstract method, description.Because this class is abstract, you can’t instantiate objects from it. It’s meantto make sure that all wrappers are consistent — when developers extendthis class, they’ll have to provide their own version of the descriptionmethod.

45Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 45

Page 67: Design Patterns For Dummies

Adding a diskHere’s a concrete wrapper, Disk, which adds a hard disk to the core com-puter. This class starts by extending the ComponentDecorator abstractwrapper class:

public class Disk extends ComponentDecorator{

.

.

.}

Because this is a wrapper class, it has to know what it’s wrapping so you canpass a computer object to this class’s constructor. The Disk wrapper willstore the core computer object.

public class Disk extends ComponentDecorator{Computer computer;

public Disk(Computer c){computer = c;

}...

}

Now you’ve got to implement the description method. (You inherited thedescription method from the abstract ComponentDecorator class, whichdeclares an abstract description method, so Java is going to insist you needto write the description method.) That method will call the core computerobject’s description method and add the text and a disk like this:

public class Disk extends ComponentDecorator{Computer computer;

public Disk(Computer c){computer = c;

}

public String description(){return computer.description() + “ and a disk”;

}}

46 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 46

Page 68: Design Patterns For Dummies

So if you wrap a computer object, whose description method returns thetext computer, in a Disk wrapper, when the wrapper’s descriptionmethod adds the text and a disk, you end up with the total text computerand a disk. That’s what you get from the Disk wrapper’s descriptionmethod at this point.

Adding a CDBesides disks, you can also add CD drives to your computer purchase orders.Here’s what the CD wrapper looks like — note that it adds and a CD to thereturn value from the wrapped object’s description method:

public class CD extends ComponentDecorator{Computer computer;

public CD(Computer c){computer = c;

}

public String description(){return computer.description() + “ and a CD”;

}}

Adding a monitorTo add a monitor to the purchase order you have to make the monitor wrap-per add the text and a monitor to the return value of the wrapped object’sdescription method.

public class Monitor extends ComponentDecorator{Computer computer;

public Monitor(Computer c){computer = c;

}

public String description(){return computer.description() + “ and a monitor”;

}}

47Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 47

Page 69: Design Patterns For Dummies

OK, that gives you all you need to start running some code. How about test-ing it out?

Testing it outThe best way to test out your computer component is to use a testing class,Test.java, that can be found in the downloadable code for this book.Test.java starts by creating a computer like this:

public class Test {public static void main(String args[]){Computer computer = new Computer();

.

.

.}

}

Then the code wraps that computer in a wrapper that adds a hard disk.

public class Test {public static void main(String args[]){Computer computer = new Computer();

computer = new Disk(computer);...

}}

Now let’s add a monitor.

public class Test {public static void main(String args[]){Computer computer = new Computer();

computer = new Disk(computer);computer = new Monitor(computer);

.

.

.}

}

48 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 48

Page 70: Design Patterns For Dummies

Then, you might as well add not just one CD drive, but two — cost is no con-sideration here. Finally, you can display the resulting wrapped computer’sfull configuration by calling the computer’s final description method.

public class Test {public static void main(String args[]){Computer computer = new Computer();

computer = new Disk(computer);computer = new Monitor(computer);computer = new CD(computer);computer = new CD(computer);

System.out.println(“You’re getting a “ + computer.description() + “.”);

}}

49Chapter 3: The Decorator and Factory Patterns

Java stream classes are decoratorsYou already know about decorator classes ifyou’ve ever worked with the file system in Java. That’s how Java structures its filesystem classes — as decorators. Do youwant to read data in a buffered way? Youmight take a look at a basic file-reading object,an InputStream object — but there’s noaccessible buffering there. So you mightwrap an InputStream object inside aFilterInputStream object, and then wrapthat in a BufferedInputStream object.The final wrapper, BufferedInputStream,will give you the buffering you want. Here’s theclass hierarchy:

java.lang.Object|_java.io.InputStream

|_java.io.FilterInputStream

|_java.io.BufferedInputStream

And there you go; a BufferedInputStreamobject buffers what it gets from the objectsit’s wrapped, which in this case is aFilterInputStream object, which in turnwraps an InputStream object. That’s theDecorator pattern at work, pure and simple.Here’s what the Java 1.5 documents onFilterInputStream have to say — notehow this description says “Decorator” in justabout every line:

“A FilterInputStreamcontains some otherinput stream, which it uses as its basic source ofdata, possibly transforming the data along theway or providing additional functionality. Theclass FilterInputStream itself simply over-rides all methods of InputStream with ver-sions that pass all requests to the contained inputstream. Subclasses of FilterInputStreammay further override some of these methods andmay also provide additional methods and fields.”

07_798541 ch03.qxp 3/27/06 2:21 PM Page 49

Page 71: Design Patterns For Dummies

And there you go. When you run this code, you get the fully extended com-puter model.

You’re getting a computer and a disk and a monitor and a CD and a CD.

Not bad. You were able to extend the core object simply by wrapping it invarious decorator wrappers, avoiding modification of the core code. Eachsuccessive wrapper called the description method of the object itwrapped in this case and added something to it. That’s how you use theDecorator design pattern.

Improving the New Operatorwith the Factory Pattern

Here, in your capacity of highly paid, hotshot, design pattern pro forMegaGigaCo, you’re creating a new database connection object. Behold thenew operator at work, creating an object in a Java application:

Connection connection = new OracleConnection();

Not bad, you think, after finishing the coding for your OracleConnectionclass. Now you can connect to Oracle databases.

“But,” wails the MegaGigaCo CEO, “what about connecting to Microsoft’s SQLServer?”

“Alright,” you say, “calm down. Let me think about this.” You go off to lunchand then return to find the CEO and board of directors waiting anxiously inyour office and asking, “Is it done yet?”

You get to work and create a new database connection class,SqlServerConnection. And you’re able to create objects of this newclass like this:

Connection connection = new SqlServerConnection();

“Great!” cries the CEO. “Um, what about connecting to MySQL? We want tomake that the default connection.” Jeez, you think. But you set to work, andpresently, you get the useful MySqlConnection put together — and presto,now you can connect to MySQL databases.

Connection connection = new MySqlConnection();

50 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 50

Page 72: Design Patterns For Dummies

But now you’ve got three different kinds of connections to make: Oracle, SQLServer, and MySQL. So you might start to adapt your code to make a connec-tion based on the value in a variable named type: “Oracle”, “SQLServer”, or anything else (which results in the default connection toMySQL).

Connection connection;

if (type.equals(“Oracle”)){connection= new OracleConnection();

}else if (type.equals(“SQL Server”)){connection = new SqlServerConnection();

}else {connection = new MySqlConnection();

}

That’s all fine, you think, but there are about 200 places in your code whereyou need to create a database connection. So maybe it’s time to put this codeinto a method, createConnection, and pass the type of connection youwant to that method as follows:

public Connection createConnection(String type){...

}

You can return the correct connection object, depending on what type of con-nection is required:

public Connection createConnection(String type){if (type.equals(“Oracle”)){return new OracleConnection();

}else if (type.equals(“SQL Server”)){return new SqlServerConnection();

}else {return new MySqlConnection();

}}

Bingo, you think. What could go wrong with that? “Bad news,” cries the CEO,running into your office suddenly. “We need to rework your code to handlesecure connections to all database servers as well! The board of our Westerndivision is demanding it.”

51Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 51

Page 73: Design Patterns For Dummies

You push the CEO out of your office and start to think. All this code is start-ing to change a lot. Your new method, createConnection, is part of yourcore code, and it’s the part you’re editing the most.

In Chapter 2 of this book, you will find this valuable design insight: “Separatethe parts of your code that will change the most from the rest of your appli-cation. And always try to reuse those parts as much as possible.”

Maybe it’s time to start thinking about separating out the part of the codethat’s changing so much — the connection object creation part — andencapsulating it in its own object. And that object is a factory object — it’sa factory, written in code, for the creation of connection objects.

So how did you get here? Here’s the trail of bread crumbs:

1. You started off by using the new operator to create OracleConnectionobjects.

2. Then you used the new operator to create SqlServerConnectionobjects, followed by MySqlConnection objects. In other words, youwere using the new operator to instantiate many different concreteclasses, and the code that did so was becoming larger and had to bereplicated in many places.

3. Then you factored that code out into a method.

4. Because the code was still changing quickly, it turned out to be best toencapsulate the code out into a factory object. In that way, you wereable to separate out the changeable code and leave the core code closedfor modification.

All of which is to say — the new operator is fine as far as it goes, but whenyour object creation code changes a lot, it’s time to think about factoring itout into factory objects.

Building Your First FactoryLots of programmers know how factory objects work — or think they do.The idea, they think, is simply that you have an object that creates otherobjects. That’s the way factory objects are usually created and used, butthere’s a little more to it than that. I look at the popular way of creating fac-tory objects first, then take a look at the strict GoF definition, which is alittle different, and a little more flexible.

52 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 52

Page 74: Design Patterns For Dummies

Creating the factoryThe first factory example, FirstFactory, does things the commonly under-stood way. The FirstFactory class encapsulates the connection objectcreation, and you can pass to it the type of connection you want to create(“Oracle”, “SQL Server”, or anything else). Here’s how you might createan object factory using this class:

FirstFactory factory;

factory = new FirstFactory(“Oracle”);

Now you can use the new factory object to create connection objects likethis with a factory method named createConnection.

FirstFactory factory;

factory = new FirstFactory(“Oracle”);

Connection connection = factory.createConnection();

That’s the idea, and you’ve probably seen how this works in Java, as whenyou create XMLReader objects (discussed later in this chapter). How doyou create the FirstFactory class? To start, save the type of the data-base you’re connecting to, which is passed to the FirstFactory class’sconstructor.

public class FirstFactory {protected String type;

public FirstFactory(String t){type = t;

}...

}

The FirstFactory class exposes the public method createConnectionwhich is what actually creates the objects. Here’s where the object-creationcode that changes a lot goes — all you have to do is to check which type ofobject you should be creating (OracleConnection, SqlServerConnection,or MySqlConnection) and then create it.

53Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 53

Page 75: Design Patterns For Dummies

public class FirstFactory {protected String type;

public FirstFactory(String t){type = t;

}

public Connection createConnection(){if (type.equals(“Oracle”)){return new OracleConnection();

}else if (type.equals(“SQL Server”)){return new SqlServerConnection();

}else {return new MySqlConnection();

}}

}

There you go — you’ve got a factory class.

Creating the abstract Connection classRemember that one of our objectives is to make sure that the core code doesn’t have to be modified or has to be modified as little as possible.Bearing that in mind, take a look at this code that uses the connectionobject returned by our new factory object:

FirstFactory factory;

factory = new FirstFactory(“Oracle”);

Connection connection = factory.createConnection();

connection.setParams(“username”, “Steve”);

connection.setParams(“password”, “Open the door!!!)”;

connection.initialize();

connection.open();...

54 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 54

Page 76: Design Patterns For Dummies

As you see, the connection objects created by our factory are going to beused extensively in the code. To be able to use the same code for all the dif-ferent types of connection objects we’re going to return (for Oracle connec-tions, MySQL connections, and so on), the code should be polymorphic —all connection objects should share the same interface or be derived fromthe same base class. That way, you’ll be able to use the same variable for anycreated object.

In this case, I make Connection an abstract class so all the classes derivedfrom it for the various connection types (OracleConnection,MySqlConnection, and so on) can use the same code after being created bythe FirstFactory object. The Connection class will have just a construc-tor and a description method (which will return a description of the typeof connection).

public abstract class Connection {public Connection(){}

public String description(){return “Generic”;

}}

Okay, that looks good. Now that you’ve created the abstract base class for allconcrete connection classes that will be created by our factory, how aboutcreating those concrete classes?

You should derive all the objects your factory creates from the same baseclass or interface so that code that uses the objects it creates doesn’t have tobe modified for each new object type.

Creating the concrete connection classesThere are three concrete connection classes that FirstFactory cancreate, matching the connections the CEO wants: OracleConnection,SqlServerConnection, and MySqlConnection. As just discussed, eachof these should be based on the abstract Connection class so they can beused in Connection variables after the factory object creates them. Andeach of them should return a description from the description methodthat indicates what kind of connection each connection is. Here’s how theOracleConnection class looks in code:

55Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 55

Page 77: Design Patterns For Dummies

public class OracleConnection extends Connection{public OracleConnection(){}

public String description(){return “Oracle”;

}}

Here’s the SqlServerConnection class — also based on the abstractConnection class:

public class SqlServerConnection extends Connection{public SqlServerConnection(){}

public String description(){return “SQL Server”;

}}

And here’s the MySqlConnection class, also based on the abstractConnection class, and like the others, with its own description method:

public class MySqlConnection extends Connection{public MySqlConnection(){}

public String description(){return “MySQL”;

}}

Excellent — now you’ve got the factory class set up, as well as the classesthat the factory uses to create objects. How about putting it to the test?

Testing it outEverything’s ready to go; all you need is a framework to test it in,TestConnection.java. You can start by creating a factory object whichwill create Oracle connections.

56 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 56

Page 78: Design Patterns For Dummies

public class TestConnection {public static void main(String args[]){FirstFactory factory;

factory = new FirstFactory(“Oracle”);...

}}

As is usual for factory objects, you use a method of the factory object,createConnection in this case, to create objects. Because all objects createdby this factory inherit from the Connection class, you can store whateverobject the factory creates in a Connection variable.

public class TestConnection {public static void main(String args[]){FirstFactory factory;

factory = new FirstFactory(“Oracle”);

Connection connection = factory.createConnection();...

}}

To check the connection object that’s been created and make sure it’s anOracle connection object, just call its description method.

public class TestConnection {public static void main(String args[]){FirstFactory factory;

factory = new FirstFactory(“Oracle”);

Connection connection = factory.createConnection();

System.out.println(“You’re connecting with “ + connection.description());

}}

57Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 57

Page 79: Design Patterns For Dummies

What are the results? You should see the following message:

You’re connecting with Oracle

Not bad; that’s what you’d expect of most factory objects you usually comeacross.

In fact, Java comes stocked with various factories already, such as theXMLReaderFactory class, which lets you build XMLReader objects.

try {XMLReader myReader = XMLReaderFactory.createXMLReader();

} catch (SAXException e) {System.err.println(e.getMessage());

}

In Java, XMLReaderFactory is a final class, not designed for inheritance. Afactory class is a factory class, and that’s it. It’s not designed to be extended.But the formal GoF Factory design pattern is somewhat different — it offersyou more flexibility because before using GoF factories, you’re supposed toextend them.

According to the GoF book, the Factory Method design pattern should “Definean interface for creating an object, but let subclasses decide which class toinstantiate. Factory method lets a class defer instantiation to subclasses.”

The key here is the part that says: “let the subclasses decide.” So far, the fac-tory classes you’ve seen here don’t let the subclasses decide how to config-ure the factory — unless they simply inherit from it and override it, methodby method.

The GoF Factory Method design pattern gives you more flexibility than thetraditional object factory. The GoF way of doing things means that you definehow factory methods should work and leave it up to subclassers to implementthe actual factory.

Say that the Western division of MegaGigaCo suddenly calls and says thatthey don’t like the FirstFactory class at all — they want to be able tocreate secure connections to the database server, not just standard connec-tions. And that means they’ve been having to rewrite FirstFactory everytime you change it, so that they can create secure database connections.

That’s an issue for the developers — every time you update the FirstFactoryclass, the developers have to rewrite it and adapt it for their own use. They’recalling to say they want more control over the process.

Fine, you say, that’s what the GoF Factory Method design pattern is really allabout — delegating control to subclassers. To see how this works, I changethe way connection objects are created, using the GoF techniques that willmake even MegaGigaCo’s Western division happy.

58 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 58

Page 80: Design Patterns For Dummies

Still unclear about when to use the GoF Factory Method design pattern?Consider the GoF Factory Method pattern when circumstances have gottendecentralized enough so that many programmers who subclass your factoryclass are overriding it so much that they’re changing it substantially.

Creating a Factory the GoF WayHow do you “let the subclasses decide which class to instantiate” whencreating an object factory? The way to do that is to define your factory asan abstract class or interface that has to be implemented by the subclassesthat actually do the work by creating objects.

In other words, you at MegaGigaCo headquarters can create the specificationfor factory objects, and the actual implementation of those factories is upto those who subclass your specification. It all starts by creating that factoryspecification, and I do that with an abstract factory class.

Creating an abstract factoryCreating the abstract factory class is easy. This class will be calledConnectionFactory.

public abstract class ConnectionFactory {

.

.

.}

Besides an empty constructor, the important method here is the factorymethod createConnection. I make this method abstract so that any sub-classes have to implement it. This method takes one argument — the type ofconnection you want to create.

public abstract class ConnectionFactory {public ConnectionFactory(){}

protected abstract Connection createConnection(String type);}

And that’s all you need — the specification for an object factory. Now theWestern division will be happy because they can implement their own con-crete factory classes from this abstract factory class.

59Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 59

Page 81: Design Patterns For Dummies

Creating a concrete factoryYou’ve flown out to the MegaGigaCo Western division to set them straight onthis business of object creation. You explain, “I understand that you want togain more control over object creation using your own factory methods.”

“Yep,” say the Western division programmers. “We want to be able to workwith secure database connections. We’ve created some new classes,SecureOracleConnection, SecureSqlServerConnection, andSecureMySqlConnection to create secure connections.”

“Okay,” you say, “all you have to do is to extend the new abstract class I’venamed ConnectionFactory when you create your own object factory. Makesure you implement the createConnection method, or Java won’t let youcompile. Then it’s up to you to write the code in the createConnectionmethod to create objects of the new secure type that you want to use.”

The Western division programmers say, “Hey, that’s easy. We’ll name our newconcrete factory class that creates connection objects SecureFactory,and it’ll extend your abstract ConnectionFactory class this way”:

public class SecureFactory extends ConnectionFactory{

.

.

.}

“Next,” the Western division programmers say, “we just implement thecreateConnection class that the abstract ConnectionFactory classrequires like this”:

public class SecureFactory extends ConnectionFactory{public Connection createConnection(String type){

.

.

.}

}

“Finally,” the programmers say, “we just need to create objects from our ownclasses, the SecureOracleConnection, SecureSqlServerConnection,and SecureMySqlConnection classes, depending on the type passed to thecreateConnection method”:

60 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 60

Page 82: Design Patterns For Dummies

public class SecureFactory extends ConnectionFactory{public Connection createConnection(String type){if (type.equals(“Oracle”)){return new SecureOracleConnection();

}else if (type.equals(“SQL Server”)){return new SecureSqlServerConnection();

}else {return new SecureMySqlConnection();

}}

}

“Simple!” they say.

And it is simple. The difference between the usual way of creating object fac-tories and the GoF way is that the GoF way provides more of a specificationfor a factory and lets subclassers handle the details.

Creating the secure connection classesTo get this GoF Factory Method example off the ground, you need concreteclasses for the new secure connection object factory to create, theSecureOracleConnection, SecureSqlServerConnection, andSecureMySqlConnection classes. They’re easy to create — start withthe SecureOracleConnection class, whose description methodreturns the text “Oracle secure”.

public class SecureOracleConnection extends Connection{public SecureOracleConnection(){}

public String description(){return “Oracle secure”;

}}

61Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 61

Page 83: Design Patterns For Dummies

The SecureSqlServerConnection class’s description method returnsthe text “SQL Server secure”.

public class SecureSqlServerConnection extends Connection{public SecureSqlServerConnection(){}

public String description(){return “SQL Server secure”;

}}

And the SecureMySqlConnection class’s description method returns“MySQL secure”.

public class SecureMySqlConnection extends Connection{public SecureMySqlConnection(){}

public String description(){return “MySQL secure”;

}}

That completes the code for this example — the next step is to see if it’llprove itself.

Testing it outTest your code with TestFactory.java; this creates a SecureFactoryobject factory and uses it to create a SecureOracleConnection object.You create the factory as follows:

public class TestFactory {public static void main(String args[]){SecureFactory factory;

factory = new SecureFactory();

62 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 62

Page 84: Design Patterns For Dummies

.

.

.}

}

Then all you’ve got to do is use the factory’s createConnection method tocreate a new secure connection to a database server like Oracle and use thecreated connection object to verify that you’re now building secure connec-tions, as the Western division wanted to do.

public class TestFactory {public static void main(String args[]){SecureFactory factory;

factory = new SecureFactory();

Connection connection = factory.createConnection(“Oracle”);

System.out.println(“You’re connecting with “ + connection.description());

}}

When you run this, you get, as expected, this text, indicating that you used asecure Oracle connection:

You’re connecting with Oracle secure

The result is just what you’d get from the FirstFactory example discussedearlier in this chapter, except that now, you’ve let the Western division pro-grammers implement their own version of your factory. You set the factoryspecification by creating an abstract class or interface that subclassers haveto use, and they build the actual concrete factory that can create objects. Nolonger does a single concrete factory object instantiate your objects — aset of subclasses does the work.

63Chapter 3: The Decorator and Factory Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 63

Page 85: Design Patterns For Dummies

64 Part I: Getting to Know Patterns

07_798541 ch03.qxp 3/27/06 2:21 PM Page 64

Page 86: Design Patterns For Dummies

Chapter 4

Watch What’s Going On with the Observer and Chain of

Responsibility PatternsIn This Chapter� Using the Observer pattern

� Creating observers and subjects

� Using the Java Observable class

� Using the Java Observer interface

� Using the Chain of Responsibility pattern

The big boss comes into your office and says, “Someone’s been editing thedata in our central database — why wasn’t I informed?”

“How’s that?” you ask. “You want to be informed of every edit that happens tothe data?” You know the boss is new on the job, but this is something evenmore clueless than you’d expected.

“That’s right,” the boss says. “I want personal notification each time a recordis changed in the database. I want to keep an eye on what goes on around here.”

“You mean, like a memo?”

“Right.”

“Hmm,” you say. “I think I have a better idea. How about I use the Observerdesign pattern and register you as a database observer?”

“Huh?” the boss asks.

08_798541 ch04.qxp 3/27/06 2:22 PM Page 65

Page 87: Design Patterns For Dummies

“You’ll be notified each time the database is modified,” you say. “No memosneeded. It’ll all be done automatically, in code.”

“That’s all I ask,” the boss says, leaving.

You smile to yourself as you turn to the code, wondering how happy the bossis going to be with about 200,000 notifications a day. But, by using the Observerdesign pattern, the coding won’t be hard to set up.

This chapter is about keeping your objects in the know when something’shappened and passing the word to notify either a set or a whole chain ofobjects. There are two design patterns coming up in this chapter — theObserver design pattern, and the Chain of Responsibility design pattern.

The Observer design pattern lets several observer objects be notified when asubject object is changed in some way. Each observer registers with the sub-ject, and when a change occurs, the subject notifies them all. Each of theobservers is notified in parallel (that is, at the same time).

The Chain of Responsibility design pattern also lets you notify objects of achange, but this time, the objects are connected in a chain — that is, inseries. The notification goes from one object to the next until an object isfound that can handle the notification.

Notifying Observers with the Observer Pattern

The boss wants to be notified each time a change is made to the company’sdatabase. And, come to think of it, you might as well archive all thosechanges as well. Not only that, but the client who’s making the changesshould be notified of the success or failure of her changes as well.

So now that you’ve got a set of “observers” that needs to know what’s goingon, it makes sense to start thinking in terms of the Observer pattern, whichlets a subject (the database) notify a set of observers (the archive, the boss,and the client) of changes or events.

The Observer design pattern is all about sending notifications to update a setof objects. You can add new observer objects at runtime and remove them aswell. When an event occurs, all registered observers are notified.

The Gang of Four book (Design Patterns: Elements of Reusable Object-OrientedSoftware, 1995, Pearson Education, Inc. Publishing as Pearson AddisonWesley) says that the Observer design pattern should “Define a one-to-manydependency between objects so that when one object changes state, all itsdependents are notified and updated automatically.”

66 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 66

Page 88: Design Patterns For Dummies

Here’s how it works. An observer can register with the subject as shown inFigure 4-1.

The server stores the information that observer has registered. Then anotherobserver, Observer 2, registers as well (see Figure 4-2).

At this point, the subject (database) is keeping track of two observers. Whenan event occurs, the subject notifies both observers as shown in Figure 4-3.

Subject Observer 1

Observer 2notification

notificationFigure 4-3:

When anevent

occurs, allregistered

objects arenotified.

Subject Observer 1

Observer 2register

Figure 4-2:A secondobserverregisters

itself.

Subject Observer 1register

Figure 4-1:An observer

signs up toreceive

notificationsof changes

to thedatabase.

67Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 67

Page 89: Design Patterns For Dummies

At any time, an observer, such as Observer 1, can unregister (ask to stopreceiving notifications — for example, it may be shutting down) with the sub-ject, as shown in Figure 4-4.

Now that Observer 1 is no longer registered, it no longer receives notifica-tions (see Figure 4-5).

However, Observer 1 can register again at any time and be added to the sub-ject’s internal lists of observers once again.

You should consider the Observer design pattern when, as with event listen-ers in Java, you have an object that can cause events to occur — events thatyou want other objects to know about. Instead of writing everything in onemonolithic class, consider breaking control out into a set of objects that willbe notified when an event occurs.

In this example, when a record is edited, the database informs all registeredobservers of the change — that’s the whole idea behind this pattern. Time tostart coding this to get it down in black and white.

Subject Observer 1

Observer 2notification

Figure 4-5:Notifica-tions are

no longersent to the

unregisteredobserver.

Subject Observer 1

Observer 2

unregisterFigure 4-4:

An observercan

unregisteritself.

68 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 68

Page 90: Design Patterns For Dummies

Creating a subject interfaceWhen you implement a design pattern, it’s often a good idea to start by creat-ing an interface to make sure that the objects you create will adhere to thepattern you’re trying to use — especially if multiple objects are involved.Implementing that interface — programming to an interface as it’s called —keeps your code in line and usually keeps things clearer.

When you’re putting the Observer pattern into code, set up an interface orabstract class for the observers; you’ll usually have multiple observers, andyou have to keep the methods they implement consistent.

In this example, I also need to set up an interface for the subject, which iswhat the observers watch; the Subject interface lists the methods subjectsmust implement. I put a registerObserver method here so that the sub-ject can keep track of observers that want to be registered. Besides register-ing observers, you should have some way to get rid of them, so I add aremoveObserver method. And there’s a notifyObservers method thatwill notify the observers of some change.

69Chapter 4: The Observer and Chain of Responsibility Patterns

The Observer pattern in JavaJava implements this design pattern to someextent by using listeners that listen for userinterface events. Want to create a button inyour application? Just make sure you connecta listener to it to handle button events.

JButton button = new JButton(“CheckSpelling”);

JTextField text = new JTextField(30);

public void init(){Container contentPane =

getContentPane();

contentPane.setLayout(newFlowLayout());

contentPane.add(button);

contentPane.add(text);

button.addActionListener(newActionListener()

{public void

actionPerformed(ActionEventevent) {

text.setText(“Good job.”);}

});}

In the Java model, you can add as many listen-ers (observers) as you like, and that’s the way itworks with the loose coupling of the Observerdesign pattern.

08_798541 ch04.qxp 3/27/06 2:22 PM Page 69

Page 91: Design Patterns For Dummies

public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer o);public void notifyObservers();

}

This interface lists the methods that subjects like the database systemshould implement. Next up: the interface for the observers.

Creating an observer interfaceBuilding the Observer interface, implemented by the observers to enablethem to get notifications, is simple. All you need is a method that will becalled when a new notification is ready, and I’ll call that method update. Inthis example, you pass the database operation that was performed (such as“edit”, “delete”, “create” and so on) and the record that was changed asstrings to the update method.

public interface Observer {public void update(String operation, String record);

}

When observers implement the update method, the subject is able to passthem the record that’s been affected and the operation that was performed.

Okay, we’re good to go. It’s time to create the Database subject that is goingto keep track of the observers and notify them when there’s been a change.

Creating a subjectThe subject has to let observers register and has to notify them when anevent occurs. According to the Subject interface, the three methods a subjecthas to implement in these examples are: registerObserver,removeObserver, and notifyObservers. That’s what the Database classdoes in this example.

To keep track of the observers, I will use a Java vector named observers,created in the Database constructor. (The type specifier here, <Observer>,is for Java 1.5 or later and indicates that each observer object implementsthe Observer interface; if you’re using an earlier version of Java, omit thetype specifier.)

70 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 70

Page 92: Design Patterns For Dummies

import java.util.*;

public class Database implements Subject {private Vector<Observer> observers;

public Database() {observers = new Vector<Observer>();

}...

}

When you use a vector, keeping track of observers is simple. When an observerwants to register, it calls the subject’s registerObserver method, passingitself as an object. The subject — an object of our Database class — just hasto add that observer to the observers vector in the registerObservermethod, using the Vector class’s add method.

import java.util.*;

public class Database implements Subject {private Vector<Observer> observers;

public Database() {observers = new Vector<Observer>();

}

public void registerObserver(Observer o) {observers.add(o);

}...

}

How about removing an observer from the observers vector? No problem.When you want to remove an object from a vector, you can use the vector’sremove method; here’s how that works in the Database class’sremoveObserver method:

import java.util.*;

public class Database implements Subject

71Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 71

Page 93: Design Patterns For Dummies

{private Vector<Observer> observers;

public Database() {observers = new Vector<Observer>();

}

public void registerObserver(Observer o) {observers.add(o);

}

public void removeObserver(Observer o) {observers.remove(o);

}...

}

When the user actually does something with the database — deletes arecord, for example — he calls the Database class’s editRecord method.For example, to delete record 1, you might call this method like this:

database.editRecord(“delete”, “record 1”);

Here’s what the editRecord method looks like: When this method is called,you pass it the database operation you want to perform and the record youwant to work on, both as strings in this example. Those strings are stored sothey can be passed on to the observers. After the strings are stored, thenotifyObservers method, coming up next, is called to notify all observers.

import java.util.*;

public class Database implements Subject {private Vector<Observer> observers;private String operation;private String record;

public Database() {observers = new Vector<Observer>();

}...

public void editRecord(String operation, String record)

72 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 72

Page 94: Design Patterns For Dummies

{this.operation = operation;this.record = record;notifyObservers();

}}

Here’s the meat of the code, the part that notifies each observer that there’sbeen a change: the notifyObservers method. Each observer implementsthis example’s Observer interface — which means it has an update method —so notifyObservers just has to loop over all registered observers in theobservers vector, calling each one’s update method with the databaseoperation and affected record.

import java.util.*;

public class Database implements Subject {private Vector<Observer> observers;private String operation;private String record;...

public void notifyObservers() {for (int loopIndex = 0; loopIndex < observers.size(); loopIndex++) {Observer observer = (Observer)observers.get(loopIndex);observer.update(operation, record);

}}

public void editRecord(String operation, String record) {this.operation = operation;this.record = record;notifyObservers();

}}

That’s all you need for Database.java, the subject in this example. Thesubject will let observers register themselves, unregister themselves, and getnotified when a database record has been edited (which you do with theDatabase class’s editRecord method). All that’s left to do to get this showon the road is to create the observers themselves.

Creating observersThis example has three observers — the archive for data backup, the clientwho’s actually doing the work on the database, and the boss, who wants to

73Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 73

Page 95: Design Patterns For Dummies

be notified of every change. To create an observer, you just have to imple-ment the Observer interface you’ve created, which has only one method,update. Here’s what creating an observer for the archives, which I’ll call theArchiver class, looks like:

public class Archiver implements Observer {public Archiver() {}

public void update(String operation, String record){...

}}

The database record and the editing operation are passed as strings to theupdate method. When called, the update method displays that informationon the screen.

public class Archiver implements Observer {public Archiver() {}

public void update(String operation, String record){System.out.println(“The archiver says a “ + operation +“ operation was performed on “ + record);

}}

When the update method is called, then, you’re going to see a messagesomething like this, which gives the name of the observer that was notifiedby the subject:

The archiver says a delete operation was performed on record 1

The observer for the client — the Client class — looks like this:

public class Client implements Observer {public Client() {}

public void update(String operation, String record)

74 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 74

Page 96: Design Patterns For Dummies

{System.out.println(“The client says a “ + operation +“ operation was performed on “ + record);

}}

And here’s the observer class for the boss, the Boss class:

public class Boss implements Observer {public Boss() {}

public void update(String operation, String record){System.out.println(“The boss says a “ + operation +“ operation was performed on “ + record);

}}

You now have a subject (Database.java) and three observers (Archiver.java, Client.java, and Boss.java).

Testing the Database observersBrilliant! You’re ready to test the database and its observers. The test harnesshere is called TestObserver.java, and the idea is to create a Databaseobject, register the observers with that object, and see if they catch edits tothe database.

The inspiration here is loose coupling. (For more on this critical concept,check out the sidebar “Loose coupling beats a monolith” in this chapter.) Nomore information is traded than need be, keeping the data space chatterdown to a minimum. And the observers aren’t locked into the core codebecause you’re using a “has-a” relationship to store observer objects in thesubject code. (For more on “has-a” relationships, turn to Chapter 2.)

Here it goes. You start by creating a Database object as shown in the following:

public class TestObserver {public static void main(String args[]){Database database = new Database();...

}}

75Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 75

Page 97: Design Patterns For Dummies

And you need the three observers.

public class TestObserver {public static void main(String args[]){Database database = new Database();Archiver archiver = new Archiver();Client client = new Client();Boss boss = new Boss();...

}}

You’ve got the subject and the observers. Now you’ve got to register theobservers with the subject, which you do with the Database class’sregisterObserver method. You pass the observer to register to thatmethod this way:

public class TestObserver {public static void main(String args[]){Database database = new Database();Archiver archiver = new Archiver();Client client = new Client();Boss boss = new Boss();

database.registerObserver(archiver);database.registerObserver(client);database.registerObserver(boss);...

}}

Alright, the observers are connected to the subject. Theoretically, whensomething happens to the database, all three observers will be notified, andthey’ll display a message. Is this going to work? There’s only one way to findout. You can make a change to the database with the Database class’seditRecord method, which stores the operation you want to perform andthe record you want to perform it on, and notifies the waiting observers.

In this case, I’m going to perform a delete operation on record 1 in the database:

76 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 76

Page 98: Design Patterns For Dummies

public class TestObserver {public static void main(String args[]){Database database = new Database();Archiver archiver = new Archiver();Client client = new Client();Boss boss = new Boss();

database.registerObserver(archiver);database.registerObserver(client);database.registerObserver(boss);database.editRecord(“delete”, “record 1”);

}}

Compile the code and run it; you should see the following:

The boss says a delete operation was performed on record 1The client says a delete operation was performed on record 1The archiver says a delete operation was performed on record 1

Excellent. All the observers were notified, which is just what you want.

That’s an implementation of the Observer design pattern. It’s more flexiblethan hard coding everything into one unbreakable block and allows you toadd or remove observers at runtime. It couples your objects loosely, which issomething you should strive for, and builds composite objects using “has-a”relationships.

77Chapter 4: The Observer and Chain of Responsibility Patterns

Loose coupling beats a monolithBoth the design patterns discussed in this chapter are about sending notifications to other objects. The Observer and Chain ofResponsibility design patterns implement what’scalled loose coupling — connecting objectsthrough notifications rather than hard coding aconnection.

When you hard code command handlingthroughout a single class, you can end up witha large, monolithic class that’s hard to debug oreven understand. By breaking things out intoencapsulated objects that communicate nomore than they need to — using simple notifi-cations — you can often gain a great deal of

flexibility and robustness. By working with moreself-contained objects, you’re able to debug anddevelop those semi-independent objects easier,making agile development easier. The designinsight here is that loose coupling betweenobjects, rather than simply extending objects bymaking them do more than they were meant todo, is good design policy.

For maximal flexibility, go for loose couplingwhen it comes to information flow, not tight cou-pling. Think of loose coupling as just anotherpart of OOP (object-oriented programming)encapsulation when it comes to applicationdesign.

08_798541 ch04.qxp 3/27/06 2:22 PM Page 77

Page 99: Design Patterns For Dummies

Using Java’s Observer Interface and Observable Class

Java already comes with some built-in support for creating observer-basedcode, but, as you’re going to see, it’s not as flexible as the code discussed ear-lier in this chapter. Java’s support here is based on the Observer interfaceand the Observable class.

Watching with the Observer interfaceThe Observer interface is what you create observers with. This interfacehas just one method, update, that looks like this:

void update(Observable o, Object arg)

This is a lot like the observers discussed in the previous section of this chapter — everything there centers around the observer’s update method,which is called when the observer is notified of a change.

There’s a difference here — this update method is passed an Observableobject and a generic object (when you implement the Observer design pat-tern from scratch, you can set what’s passed to your observers). You canspecify what generic object you want passed to the observers by passingthat object to the Observable class’s notifyObservers method (comingup shortly), but you don’t have any choice about passing the Observableobject. In the examples in the previous section of this chapter, the Observableobject is the Database object, and each observer will be able to interrogatethat object to find out what record was edited, and how.

That brings up a potential problem issue. Note that the entire subject ispassed to each observer every time the observers need to be updated. Theobject is passed by reference, as usual for objects in Java, so even if theDatabase object is huge, you don’t have to worry about running out ofmemory; the Database object itself isn’t passed, but a reference to it is. Butthat means that each observer has direct access to the subject object, and socan potentially change the subject object or the data in it, as well as poten-tially causing deadlock issues with shared resources. That’s not what you’dcall loose coupling; as a general design insight, it’s best to trade only theinformation you need to trade.

78 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 78

Page 100: Design Patterns For Dummies

Notifying with the Observable classThe Java Observable class is what you create subjects with; more specifi-cally, you extend this class to create subjects. This class features some of thefollowing built-in methods:

� void addObserver(Observer o) Adds an observer to the inter-nally stored set of registered observers for this subject.

� protected void clearChanged() Clears the internal changedflag, meaning that no changes are waiting to be passed to the observers.

� int countObservers() Returns the number of observers currentlyregistered for this subject.

� void deleteObserver(Observer o) Removes a registeredobserver from the internally stored set of observers for this subject.

� void deleteObservers() Removes all registered observers forthis subject; there will be no registered observers when the call returns.

� boolean hasChanged() Returns true if the subject has changed.

� void notifyObservers() Notifies all registered observers that thisobject has changed by calling their update methods, if there has been achange. You can indicate that there has been a change by calling thesetChanged method.

� void notifyObservers(Object arg) Notifies all registeredobservers that this object has changed and passes the given object tothem by calling their update methods, if there has been a change. Youcan indicate that there has been a change by calling the setChangedmethod.

� protected void setChanged() Sets this subject object as havingbeen changed. Call this before calling notifyObservers, or notifyObservers will not do anything.

Note that when you use a subject that extends the Observable class, youhave to call the setChanged method before calling notifyObservers. Ifyou don’t call setChanged first, notifyObservers won’t do anything.

When the update method of each observer is called, how do you actuallypass data on to those observers? There are two ways, corresponding to thetwo objects the update method is called with, the Observable object itself,and another object you can (optionally) specify:

void update(Observable o, Object arg)

79Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 79

Page 101: Design Patterns For Dummies

You can either build in getter/setter methods into the Observable object, orput together an object with all the data you want to send to observers andpass that object to the notifyObservers method; that object will then bepassed as the second argument to the update method of the observers. I’mgoing to modify the database example to use Java’s Observer/Observableas an example, and I’ll use the first technique — adding getter/setter methodsto the Observable object — here.

Creating the Observable objectTo create a subject, you extend the Observable class, so here’s how I createthe new version of the Database class:

import java.util.Observable;import java.util.Observer;

public class Database extends Observable {public Database() { }...

}

To let users make changes to the database, I add the editRecord method,which is passed both the operation to perform and the record in question(passed as strings to make the code easier). The editRecord method storesthe operation and record, then calls the setChanged andnotifyObservers methods to pass that new data along to the observers.

import java.util.Observable;import java.util.Observer;

public class Database extends Observable {private String operation;private String record;

public Database() { }

public void editRecord(String operation, String record) {

80 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 80

Page 102: Design Patterns For Dummies

this.operation = operation;this.record = record;setChanged();notifyObservers();

}...

}

When the observers are called, they’re passed the Database object, so I addgetter methods to let code retrieve the database operation and affectedrecord from that object.

import java.util.Observable;import java.util.Observer;

public class Database extends Observable {private String operation;private String record;

public Database() { }

public void editRecord(String operation, String record) {this.operation = operation;this.record = record;setChanged();notifyObservers();

}

public String getRecord() {return record;

}

public String getOperation() {return operation;

}}

So far so good; you’ve built the subject, complete with the editRecordmethod that you use to work with the database, and getter methods toallow access to information about what’s going on in the database. Now youneed to build the observers.

81Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 81

Page 103: Design Patterns For Dummies

Creating the Observer objectsTo implement the Archiver, Client, and Boss observers, you implementthe java.util.Observer interface, as here in the Archiver class:

import java.util.Observer;

public class Archiver implements Observer {

.

.

.}

I also add an empty constructor and implement the update method from theObserver interface.

import java.util.Observer;

public class Archiver implements Observer {

public Archiver() {}

public void update(Observable obs, Object record){

.

.

.}

}

Each observer’s update method is passed the subject Database object andan optional, unused object. The Database object has been written to includegetter methods for the operation the user is performing and the record heor she is working on, so all you have to do in this example in each observer isget that information and display it.

import java.util.Observer;

public class Archiver implements Observer {

public Archiver() {}

82 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 82

Page 104: Design Patterns For Dummies

public void update(Observable obs, Object record){System.out.println(“The archiver says a “ + ((Database)obs).getOperation() +“ operation was performed on “ + ((Database)obs).getRecord());

}}

Same goes for the Boss class, which will also grab the data about what theuser did and display it.

import java.util.Observer;

public class Boss implements Observer {

public Boss() {}

public void update(Observable obs, Object record){System.out.println(“The boss says a “ + ((Database)obs).getOperation() +“ operation was performed on “ + ((Database)obs).getRecord());

}}

And the Client class also grabs that information and displays it.

import java.util.Observer;

public class Client implements Observer {

public Client() {}

public void update(Observable obs, Object record){System.out.println(“The client says a “ + ((Database)obs).getOperation() +“ operation was performed on “ + ((Database)obs).getRecord());

}}

Bingo, you’re set — you’ve created all three observers. All that remains is tocreate your objects, test them, and connect them in an observer/observablerelationship.

83Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 83

Page 105: Design Patterns For Dummies

Testing the Observable codeThe file TestObservable.java in the downloadable code for the book (seethe Introduction for the Web address where you can download this) is a testharness that creates Database (subject) and Archiver, Client, and Boss(observer) objects and connects them. It starts by creating all the necessaryobjects.

public class TestObservable {public static void main(String args[]){Database database = new Database();

Archiver archiver = new Archiver();Client client = new Client();Boss boss = new Boss();

.

.

.}

}

To add an observer to an Observable object, you use the Observableclass’s addObserver method, which is much like the addListener methodused when working with UI (user interface) elements. Here’s how to add thearchiver, client, and boss objects as observers of the database object:

public class TestObservable {public static void main(String args[]){Database database = new Database();

Archiver archiver = new Archiver();Client client = new Client();Boss boss = new Boss();

database.addObserver(archiver);database.addObserver(client);database.addObserver(boss);

.

.

.}

}

84 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 84

Page 106: Design Patterns For Dummies

That connects the observer objects to the observable object. To makesomething happen, just call the Database class’s editRecord method tomake a change in the database, and the Database then notifies the observers:

public class TestObservable {public static void main(String args[]){Database database = new Database();

Archiver archiver = new Archiver();Client client = new Client();Boss boss = new Boss();

database.addObserver(archiver);database.addObserver(client);database.addObserver(boss);

database.editRecord(“delete”, “record 1”);}

}

Compile and run this test harness; you’ll see that each observer is notified ofthe change with the following messages:

The boss says a delete operation was performed on record 1The client says a delete operation was performed on record 1The archiver says a delete operation was performed on record 1

85Chapter 4: The Observer and Chain of Responsibility Patterns

Do-it-yourself ObservablesThe Observable code you tested withTestObservable.java works. Great,right? However, I suggest that if you want to dothis, you should write it yourself. TheObservable class is a concrete class, andthat limits your flexibility. You can’t changewhat’s passed to observers, and you can’t letsubclasses implement their own versions of theObservable methods unless they want tooverride those methods — in which case, whyare you using the Observable class at all?

Because Observable is a class, you have to extend it in your own code, and that’s aproblem because Java doesn’t allow multiple

inheritance — if you subclass Observable,you can’t subclass from your own classes. Thatwipes out your use of inheritance in your appli-cation, which is too big a price to pay. IfObservable were an interface, the storymight be different, but it’s a concrete class.

And on top of that, Observable hides impor-tant methods like setChanged that you might have reasonable reasons to use withouthaving to subclass the Observable class. So although Observable works, you shouldconsider it only a lightweight implementation of the Observer pattern.

08_798541 ch04.qxp 3/27/06 2:22 PM Page 85

Page 107: Design Patterns For Dummies

Using the Chain of ResponsibilityPattern

Here’s another pattern that’s all about notifying other objects when some-thing’s happened: the Chain of Responsibility design pattern. This pattern isall about connecting objects in a chain of notification; as a notification travelsdown the chain, it’s handled by the first object that is set up to deal with theparticular notification.

The Observer pattern notifies observers in parallel fashion as shown inFigure 4-6:

But the Chain of Responsibility pattern notifies objects in series, along achain as illustrated in Figure 4-7:

The first object in the chain that can deal with the notification handles it, andany following objects aren’t notified.

Subject Object 1 Object 2 Object 3

Figure 4-7:The chain

notifies oneobserver,

whichnotifiesanother

observer, . . .

Subject Observer 1

Observer 2notification

notification

Figure 4-6:The

Observerpattern

sendsnotificationsto everyoneat the same

time.

86 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 86

Page 108: Design Patterns For Dummies

The GoF book says that the Chain of Responsibility design pattern should“Avoid coupling the sender of a request to its receiver by giving more thanone object a chance to handle the request. Chain the receiving objects andpass the request along the chain until an object handles it.”

You use this pattern when not all your observers are created equal. For exam-ple, say that you have a layered application with a set chain of command forevents — a mouse event may originate in a particular control, then bubble upto the control’s container, then the container’s window, and eventually up tothe application itself. The first object that can handle the event correctlyshould grab it and stop the event from further bubbling.

In other words, if you want to process your notifications using a hierarchicalchain of objects, this is your pattern.

Here’s an example which implements a help interface in a layered application.Say the user right-clicks an element in the UI and requests help for a particularvisual element. If the front end of the application can handle the help request, itwill handle that request; if it can’t, it passes that request on to the intermediatelayer of the application; if the help request still can’t be handled, it’s passed onto the application object itself, which displays a default message.

Creating a help interfaceTo keep control over the objects in your chain, make them all implement thesame interface. In this example, I use an interface named Help, with onemethod, getHelp, which is passed an int constant that describes whichhelp message is required.

interface HelpInterface{public void getHelp(int helpConstant);

}

Creating chainable objectsThere are three application layers that can deal with a help request in thisexample — the front end, the intermediate layer, and the application object —and you want to chain those objects together as shown in Figure 4-8.

87Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 87

Page 109: Design Patterns For Dummies

To chain them, you can pass to each object’s constructor the next object in thechain — its successor in the chain — as shown here with the FrontEnd class:

public class FrontEnd implements HelpInterface{HelpInterface successor;

public FrontEnd(HelpInterface s){successor = s;

}...

}}

The front end can only handle help requests about the front end, for which Iuse the constant FRONT_END_HELP. If the constant passed to the FrontEndobject’s getHelp method is not FRONT_END_HELP, it should pass the helprequest to the next object in the chain; otherwise, it knows it can handle this help request and will display a help message as you can see in the follow-ing code:

public class FrontEnd implements HelpInterface{final int FRONT_END_HELP = 1;HelpInterface successor;

public FrontEnd(HelpInterface s){successor = s;

}

public void getHelp(int helpConstant){if(helpConstant != FRONT_END_HELP){successor.getHelp(helpConstant);

} else {System.out.println(“This is the front end. Don’t you like it?”);

}}

}

Front End IntermediateLayer Application

Figure 4-8:Chaining

objectstogether.

88 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 88

Page 110: Design Patterns For Dummies

The intermediate layer, class IntermediateLayer, can handle help requestscorresponding to the INTERMEDIATE_LAYER_HELP constant. If it gets passedthat constant in the getHelp method, it displays a help message — otherwise,it passes the help request on to the next object in the chain.

public class IntermediateLayer implements HelpInterface{final int INTERMEDIATE_LAYER_HELP = 2;HelpInterface successor;

public IntermediateLayer(HelpInterface s){successor = s;

}

public void getHelp(int helpConstant){if(helpConstant != INTERMEDIATE_LAYER_HELP){successor.getHelp(helpConstant);

} else {System.out.println(“This is the intermediate layer. Nice, eh?”);

}}

}

The end of the chain is the Application object; the buck stops here. Thereis no successor to this link in the chain, so if the getHelp method is called inthe Application object, it just displays a default message.

public class Application implements HelpInterface{

public Application(){}

public void getHelp(int helpConstant){System.out.println(“This is the MegaGigaCo application.”);

}}

That gives you all the links in the chain. And it’s a simple matter to connectthem all.

Testing the Help systemYou can test all this out in a test harness named TestHelp.java. This filecreates an Application, FrontEnd, and IntermediateLayer object, andyou chain them together by passing the successor to each object to the

89Chapter 4: The Observer and Chain of Responsibility Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 89

Page 111: Design Patterns For Dummies

object’s constructor. When the chain is complete, the code calls the frontend’s getHelp method with a constant named GENERAL_HELP.

public class TestHelp {public static void main(String args[]){final int FRONT_END_HELP = 1;final int INTERMEDIATE_LAYER_HELP = 2;final int GENERAL_HELP = 3;

Application app = new Application();

IntermediateLayer intermediateLayer = new IntermediateLayer(app);

FrontEnd frontEnd = new FrontEnd(intermediateLayer);

frontEnd.getHelp(GENERAL_HELP);}

}

Since the front end can’t handle help requests of this kind, it passes therequest on to the intermediate layer. Since that layer can’t handle the helprequest either, the request is passed on to the application object. And theapplication object displays its generic message:

This is the MegaGigaCo application.

There you have it; the Chain of Responsibility design pattern at work. Want tohandle notifications in a loosely coupled way, but also have a definite chainof command in mind? This is the pattern for you.

90 Part I: Getting to Know Patterns

08_798541 ch04.qxp 3/27/06 2:22 PM Page 90

Page 112: Design Patterns For Dummies

Chapter 5

From One to Many: The Singletonand Flyweight Patterns

In This Chapter� Using the Singleton pattern

� Creating singletons

� Synchronizing to avoid multithreading issues

� Handling multithreading issues a better way

� Using the Flyweight pattern

In your capacity as highly paid consultant to MegaGigaCo, you’re trou-bleshooting some performance issues. “Everything just goes really

slowly,” say the company programmers.

“Hmm,” you say, “I notice you have a really big database object, about 20megabytes.”

“Yep,” they say.

“How many of these objects do you have at any one time?”

“About 219,” the company programmers say.

“So you have 219 20-megabyte objects when your code is running?” you ask.“Does anyone see a problem with that?”

“Nope,” they say.

You tell them, “You’re using too many system resources. You’ve got hundredsof huge objects that you’re expecting the computer to handle. Do you reallyneed all those objects?”

09_798541 ch05.qxp 3/27/06 2:22 PM Page 91

Page 113: Design Patterns For Dummies

“Well. . . . ,” they say.

“I thought not,” you say. “I’ll fix your problem using the Singleton design pat-tern. For a few megabucks.”

“Hmm,” they say, “now it’s you that’s straining the system resources.”

This chapter is about taking control of the number of objects you have float-ing around in your code. There are two patterns especially helpful here: theSingleton design pattern and the Flyweight design pattern.

With the Singleton design pattern, you have only one object of a particularclass throughout your code. With the Flyweight pattern, you might also haveonly one object of a particular class — but it looks to your code as though it’smany different objects. A neat trick.

Instantiating Just One Object with the Singleton Pattern

I start with the Singleton pattern and tackle the MegaGigaCo programmers’problem: They want to make sure they create only one object of a particularclass, no matter how hard other people’s code tries to create multiple objects.

The company programmers are creating hundreds of Database objects intheir code, and that’s a problem because each object is huge. What’s thesolution? The Singleton pattern to the rescue.

The Singleton design pattern is all about making sure that you can instantiateonly one object of a particular class. If you don’t use a pattern like this one,the new operator just keeps on creating more and more objects — each aseparate, new object — of the same class as shown in Figure 5-1:

Using new:Database object1Database object2Database object3 . . .

Databaseclass

Figure 5-1:Creatingobject1,object2,

object3, andmany more.

92 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 92

Page 114: Design Patterns For Dummies

To make sure you only have one object, no matter how many times someone’scode tries to create more objects, use the Singleton design pattern. The Gangof Four (GoF) book (Design Patterns: Elements of Reusable Object-OrientedSoftware, 1995, Pearson Education, Inc. Publishing as Pearson Addison Wesley)says that the Singleton design pattern must: “Ensure a class only has oneinstance, and provide a global point of access to it.”

You use the Singleton design pattern when you want to either restrictresource use (instead of creating numbers of large objects without limit) orwhen you have a sensitive object whose data shouldn’t be accessed by multi-ple instances (such as a registry).

Besides registry objects, you can use the Singleton pattern when you want torestrict the number of objects created because you want to share the data inthose objects — as when you have a window object or dialog object that dis-plays and modifies data, and you don’t want to create multiple objects, whichmight confuse access to that data.

Creating a single object can also be important when you’re multithreadingand you don’t want conflicts in how the data behind that object is accessed.For example, you may be working with a database object, and if multiplethreads each create their own database objects — all of which work with thesame underlying data store — you could have a serious issue. I discuss howto work with the Singleton pattern and multithreading in this chapter.

Any time you really want only one object of a certain class, check out theSingleton pattern (instead of the new operator) — it’ll get the job done.

93Chapter 5: From One to Many: The Singleton and Flyweight Patterns

The Single and the FlyThe Singleton pattern lets you make sure thatno matter how many times your code tries tocreate an object from a specific class, only onesuch object is created. That’s important in caseyou’ve got an object that is so sensitive thatconflicts just can’t be tolerated, such as anobject named, say, windowsRegistry.Using the Singleton pattern lets you take con-trol over the object instantiation process awayfrom the new operator.

The Flyweight pattern is similar to the Singletonpattern. Here, however, the idea is that if your

code uses many large objects — using upsystem resources — you can fix things by usinga smaller set of template objects that can beconfigured on-the-fly to look like those largerobjects. The configurable objects — the flyweights — are smaller and reusable (so thereare fewer of them), but after being configured,they will appear to the rest of your code asthough you still have many large objects.

09_798541 ch05.qxp 3/27/06 2:22 PM Page 93

Page 115: Design Patterns For Dummies

Creating a Singleton-based databaseTime to start slinging some code. Let’s say you start with a class namedDatabase that the company programmers have been working with. Thatclass has a simple constructor, as shown in the following code:

public class Database {private int record;private String name;

public Database(String n){name = n;record = 0;

}...

}

You need to add two built-in methods, editRecord, which lets you edit arecord in the database, and getName, which returns the name of the database.

public class Database {private int record;private String name;

public Database(String n){name = n;record = 0;

}

public void editRecord(String operation){System.out.println(“Performing a “ + operation +“ operation on record “ + record + “ in database “ + name);

}

public String getName(){return name;

}}

Okay so far, but here’s the issue: Whenever you use the new operator toinstantiate an object of the Database class, you have to create a new object.Since you have three uses of databases, you have three objects:

94 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 94

Page 116: Design Patterns For Dummies

Database dataOne = new Database(“Products”);...

Database dataTwo = new Database(“Products Also”);...

Database dataThree = new Database(“Products Again”);...

How are you going to avoid creating a new object each time someone usesthe new operator on your class? Here’s one solution — make the constructorprivate.

private Database(String n){name = n;record = 0;

}

That stops anyone’s code from using the new operator, except for the codeinside the Database class. But wait a minute — that’s crazy, isn’t it? Who onEarth would have a private constructor? How could you create objects ofsuch a class if you can’t even call the constructor?

Well, some built-in Java classes do it this way. For example, the Graphicsand Graphics2D classes both have protected constructors — you can’tcreate an object of these classes directly. Instead, you have to use a utilitymethod, the getGraphics method, to create Graphics or Graphics2Dobjects. Java does things this way because Graphics objects have to be tai-lored to the component whose graphics context they support. In other words,you might create a window and then use its getGraphics method to get aGraphics or Graphics2D object. And if you call getGraphics repeatedly,you’ll be passed the same Graphics or Graphics2D object.

Sounds good — you give your class a constructor with no public access andlet the rest of the world create objects with a utility method that calls thatconstructor behind the scenes. You can also add code to the utility methodto make sure that no more than one object exists.

How would that look in the Database class? First, you make the constructorprivate:

public class Database {private int record;private String name;

95Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 95

Page 117: Design Patterns For Dummies

private Database(String n){name = n;record = 0;

}...

Fine, you can block the use of the new operator from any code not inside theDatabase class. Now the only way you can create objects of this class isthrough a utility method, and the usual name for that method when you’reusing the Singleton pattern is getInstance (or createInstance, or amore specific name, such as createDatabase). Note that this methodshould be public and also be static so you can call it using just the Databaseclass’s name (as Database.getInstance()).

public class Database {private int record;private String name;

private Database(String n){name = n;record = 0;

}

public static Database getInstance(String n){}...

}

This method should return a Database object, but that only works whenthere’s one of those in existence. So the code in this method first checks ifthat object, which I call singleObject, exists, and if not, it’ll create it. Thenit returns that object.

public class Database {private static Database singleObject;private int record;private String name;

private Database(String n){

96 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 96

Page 118: Design Patterns For Dummies

name = n;record = 0;

}

public static Database getInstance(String n){

if (singleObject == null){singleObject = new Database(n);

}

return singleObject;}...

}

Problem solved — now only one object of the Database class exists at onetime (although note that there are some multithreading issues coming up, as Idiscuss in the section “Uh oh — don’t forget about multithreading” later inthis chapter). Calling the getInstance method gives you a Databaseobject like the one shown in Figure 5-2:

When you call getInstance again, you’re passed the same object as thefirst time (see Figure 5-3).

No matter how many times you call getInstance, you’re passed the sameobject. Is this going to work as it should? There’s one way to find out.

Using getInstance

Database object1Database object1 . . .

getInstance()

Database classFigure 5-3:Getting the

same objectagain.

Using getInstance

Database object1

getInstance()

Database class

Figure 5-2:Creating

oneDatabase

object.

97Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 97

Page 119: Design Patterns For Dummies

Testing the Singleton patternHere’s a test harness for the new Singleton Database class, TestSingleton.java. It starts by getting a Database object named products using theDatabase class’s getInstance method and then displays the name of theDatabase object, as stored in that object.

public class TestSingleton {public static void main(String args[]){Database database;

database = Database.getInstance(“products”);

System.out.println(“This is the “ + database.getName() + “ database.”);...

}}

Then the code gets a Database object from the getInstance method again,this time passing employees as the name to store in the Database object.

public class TestSingleton {public static void main(String args[]){Database database;

database = Database.getInstance(“products”);

System.out.println(“This is the “ + database.getName() + “ database.”);

database = Database.getInstance(“employees”);

System.out.println(“This is the “ + database.getName() + “ database.”);

}}

But a Database object has already been created, so the second time around,you should still be dealing with the same Database object, not a new one.You can check that by looking at the output of this code:

This is the products database.This is the products database.

98 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 98

Page 120: Design Patterns For Dummies

Sure enough, you got the products database both times — the Databaseclass did what it should: Only one Database object was created. There youhave it; by restricting access to a class’s constructor and allowing objects to becreated only with a utility method, you’ve implemented the Singleton pattern.

Or have you?

Uh oh, don’t forget about multithreadingTake a look at the getInstance method you’ve put together in the preced-ing sections.

public static Database getInstance(String n){

if (singleObject == null){singleObject = new Database(n);

}

return singleObject;}

There’s a potential flaw here — a small but definite flaw, which has to do withmultithreading. Remember, you want to guarantee that only one Databaseobject exists. But when you have multiple threads running through yourcode, you might have a problem here. In particular, note the test that deter-mines whether or not a Database object has already been created:

public static Database getInstance(String n){

if (singleObject == null){singleObject = new Database(n);

}

return singleObject;}

If two threads are making this test at the same time, and no Database objectexists yet, they could conceivably both get past the if (singleObject ==null) test — which means both threads will create a Database object.

How can you fix this? One easy fix is to use the Java synchronized key-word, which you can use to restrict access to getInstance to one thread ata time. Here’s what that looks like:

public class DatabaseSynchronized {private static DatabaseSynchronized singleObject;private int record;private String name;

99Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 99

Page 121: Design Patterns For Dummies

private DatabaseSynchronized(String n){name = n;record = 0;

}

public static synchronized DatabaseSynchronized getInstance(String n){

if (singleObject == null){singleObject = new DatabaseSynchronized(n);

}

return singleObject;}

public void editRecord(String operation){System.out.println(“Performing a “ + operation +“ operation on record “ + record + “ in database “ + name);

}

public String getName(){return name;

}}

Using the synchronized keyword blocks access to the getInstance methodby any new thread once a thread is executing code inside the method; any newthreads attempting to get in have to wait until the current thread is finished.Using synchronized is one easy way to enforce single-threaded execution,and in this case, it solves the problem.

Putting the synchronized solution to workBecause access to getInstance is synchronized, you can call it from multi-ple threads. TestSingletonSynchronized.java puts the synchronizedsolution to work. This code starts by calling getInstance to create aDatabaseSynchronized object, giving it the internal name products.

public class TestSingletonSynchronized implements Runable{public static void main(String args[]){TestSingletonSynchronized t = new TestSingletonSynchronized();

}

public TestSingletonSynchronized(){

100 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 100

Page 122: Design Patterns For Dummies

DatabaseSynchronized database;

database = DatabaseSynchronized.getInstance(“products”);...

}

The code also launches a new thread to attempt to create a newDatabaseSynchronized object.

public class TestSingletonSynchronized implements Runable{Thread thread;

public static void main(String args[]){TestSingletonSynchronized t = new TestSingletonSynchronized();

}

public TestSingletonSynchronized(){DatabaseSynchronized database;

database = DatabaseSynchronized.getInstance(“products”);

thread = new Thread(this, “second”);thread.start();

System.out.println(“This is the “ + database.getName() + “ database.”);

}...

}

The new thread’s code tries to create a DatabaseSynchronized object withthe internal name employees.

public class TestSingletonSynchronized implements Runable{Thread thread;

public static void main(String args[]){TestSingletonSynchronized t = new TestSingletonSynchronized();

}

public TestSingletonSynchronized(){DatabaseSynchronized database;

101Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 101

Page 123: Design Patterns For Dummies

database = DatabaseSynchronized.getInstance(“products”);

thread = new Thread(this, “second”);thread.start();

System.out.println(“This is the “ + database.getName() + “ database.”);

}

public void run() {DatabaseSynchronized database = DatabaseSynchronized.getInstance(“employees”);

System.out.println(“This is the “ + database.getName() + “ database.”);

}}

But as you can see when you run this code, only one DatabaseSynchronizedobject exists — the originally created products database.

This is the products database.This is the products database.

As soon as you synchronize the getInstance method, you don’t have toworry about it anymore — only one thread can be in that method executingcode at a time. That locks the object-creation code behind safe walls, whichmeans that it’ll do its thing as it should — test to see if the object it’s sup-posed to create already exists, and if not, create it.

At first glance, this appears to be excellent; synchronizing the getInstancemethod solves the multithreading issue and protects the code against con-flict conditions where multiple objects could be created by mistake.

However, there’s still a question — synchronizing the code works, but is it thebest way to accomplish the task? Synchronizing code involves a lot of overheadcode that Java adds to monitor what’s going on with threads. And it slows yourcode down significantly, for two reasons: The entrance to the synchronizedmethod has to be constantly monitored, especially when a thread is inside themethod executing code, and because synchronized code blocks threads toavoid conflicts, threads end up twiddling their thumbs and losing you time.

Synchronizing getInstance works but at a substantial cost. Is there a betterway of doing things? You bet.

102 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 102

Page 124: Design Patterns For Dummies

Handling threading betterThe problem you’re trying to fix with the synchronized keyword is that youdon’t want the test that checks whether the single object has been created tobe corrupted by multiple threads. A better way of doing things is to makesure that test isn’t necessary at all.

“How’s that?” the company programmers ask in astonishment. “If you’re notgoing to test if the object hasn’t already been created, how can you be sureyou’re not creating a new one?”

You explain, “By stripping all the object-creation code out of thegetInstance method altogether. I’m going to rewrite the code so that onlyone object can be created, period. And it’ll be created before any thread getsits hands on that object.”

“Hmm,” say the company programmers. “Sounds like it might work.”

Here’s the idea — you create the object you want only one of when the codeis first loaded into the Java Virtual Machine (the JVM, which is what runsJava code). Don’t let getInstance create any objects at all — let it returnonly that one object that’s already been created. You can create that singleobject when the JVM first loads the code like this inDatabaseThreaded.java:

public class DatabaseThreaded{private static DatabaseThreaded singleObject = new DatabaseThreaded(“products”);

private int record;private String name;

private DatabaseThreaded(String n){name = n;record = 0;

}

.

.

.}

Fine, now you’ve created the single object you want — there’s no reason forany object-creation code in this class. And there’s no reason to perform tests

103Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 103

Page 125: Design Patterns For Dummies

to see if the code has already been created. All you have to do is to return theobject when the getInstance method is called.

public class DatabaseThreaded{private static DatabaseThreaded singleObject = new DatabaseThreaded(“products”);

private int record;private String name;

private DatabaseThreaded(String n){name = n;record = 0;

}

public static synchronized DatabaseThreaded getInstance(String n){

return singleObject;}

public void editRecord(String operation){System.out.println(“Performing a “ + operation +“ operation on record “ + record + “ in database “ + name);

}

public String getName(){return name;

}}

As you can see, this is simplicity itself. The singleton object is createdbefore any threads can get at it and returned as needed. Beautiful.

Putting the pre-thread solution to workDoes it work? As with the synchronized solution, you can put this version towork by creating a DatabaseThreaded object by calling the getInstancemethod.

public class TestSingletonThreaded implements Runable{public static void main(String args[]){TestSingletonThreaded t = new TestSingletonThreaded();

}

public TestSingletonThreaded()

104 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 104

Page 126: Design Patterns For Dummies

{DatabaseThreaded database;

database = DatabaseThreaded.getInstance(“products”);...

}

And you can use another thread to try to create a different DatabaseThreadedobject.

public class TestSingletonThreaded implements Runable{Thread thread;

public static void main(String args[]){TestSingletonThreaded t = new TestSingletonThreaded();

}

public TestSingletonThreaded(){DatabaseThreaded database;

database = DatabaseThreaded.getInstance(“products”);

thread = new Thread(this, “second”);thread.start();

System.out.println(“This is the “ + database.getName() + “ database.”);

}

public void run() {DatabaseThreaded database;

database = DatabaseThreaded.getInstance(“employees”);

System.out.println(“This is the “ + database.getName() + “ database.”);

}}

When you put all this to work, you see that you’re indeed dealing with thesame object.

This is the products database.This is the products database.

105Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 105

Page 127: Design Patterns For Dummies

This is a better solution than synchronizing the getInstance method —there’s no possibility of creating more than one object, so there’s not going tobe any conflict between threads. You’ve removed all the overhead involvedwith synchronizing code just by taking the object-creation code out of thegetInstance method.

If you’re using a version of Java before 1.2 (we’re talking early days here),there was a problem with the garbage collector that could spell problems. Ifthere is no reference to the singleton object outside the singleton itself, ashere, the garbage collector might swallow that object. That bug was fixed inJava 1.2.

Here’s something to be careful of — if you’re using multiple class loaders andsingleton objects, you might end up with issues. Because each class loaderuses its own namespace, you might in fact end up with multiple singletonobjects. So if you’re using multiple class loaders, make sure your code coordi-nates among them to ensure only one singleton object exists at any one time.

The Flyweight Pattern Makes One Look like Many

The Singleton pattern is all about having a single object, and all your codeknows is: you’ve got only one, single object. There’s another pattern that alsois all about restricting object creation, but this time it gives the rest of yourcode the feeling of multiple objects. That’s the Flyweight pattern.

This pattern is called flyweight because instead of having to work with manymassive, individual objects, you whittle them down to a smaller set of moregeneric objects, called flyweights, that can be configured at runtime to looklike the more plentiful, massive objects. Each massive object consumessystem resources; by extracting what’s generic from those massive objectsand relying on runtime configuration to mimic those massive objects, yousave those resources.

You take all the specialized contents out of the massive objects to create fly-weight objects. When you do that, you end up with more-generic objects, andyou can reduce the number you need — possibly down to just one — whichcan be configured as needed at runtime to mimic the larger set of more mas-sive objects.

106 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 106

Page 128: Design Patterns For Dummies

The GoF book says the Flyweight pattern must, “Use sharing to support largenumbers of fine-grained objects efficiently.” They go on to say, “A flyweight isa shared object that can be used in multiple contexts simultaneously. The fly-weight acts as an independent object in each context — it’s indistinguishablefrom an instance of the object that’s not shared.”

Here’s what happens. Say you start with a large set of massive objects in yourcode. You remove from those objects all the specialized, instance-specificcontents that you can to end up with a shareable object, a flyweight, that actslike a template. That template object can then be configured at runtime bypassing it all the specialized contents it needs to appear like one of the moremassive objects. So you start with a set of heavy, resource-intensive objectslike the ones shown in Figure 5-4.

107Chapter 5: From One to Many: The Singleton and Flyweight Patterns

Alternatives to SingletonsThe way of working with singletons I’ve pre-sented involves handling them as objects, but there is an alternative in Java that bears discussing — simply making all the methodsand variables in a class static. That can work,but usually it’s best to confine such a way ofdoing things to simple, self-contained objects. Ifyou start working with multiple classes and any-thing but the simplest initialization of yourobjects, you can start running into problemsthat are very subtle, especially when Javathinks you’re mixing static and non-static code.The best way of creating singletons, for mostpractical, real-world applications, is the wayI’ve presented it here.

As an alternative to static methods and vari-ables, you might also have considered globalobjects as singletons, and it’s true that if youhave just one global object of a particularclass, that object is shared in the scope inwhich it’s visible. But there are a few things tothink about here — starting with one of the pri-mary tenants of OOP (object-oriented program-ming): encapsulation. That is, it’s not good to

clutter your namespace. Global objects aren’tcool anymore, and haven’t been since OOP wasbrought in to handle large programs. The wholeinspiration behind OOP is to remove clutter fromnamespaces, not the reverse. And the otherpoint is that just because you have only onesuch global object at a particular time doesn’tmean another one can’t be created inadver-tently in another namespace, giving you somevery hard-to-debug issues. The singleton codepresented in this section makes sure that onlyone object can be created; when you work withglobal variables across different namespaces,there is no such built-in guarantee.

Another issue worth discussing: subclassing asingleton is not a good idea — at best, the con-structor will have to be made protected, whichmeans various subclasses can work with it. Ifyou’re in a situation where you think you haveto start subclassing a singleton, better thinktwice — is the object you’re working with reallya singleton? If so, why do you need to subclassit at all?

09_798541 ch05.qxp 3/27/06 2:22 PM Page 107

Page 129: Design Patterns For Dummies

From the heavy objects, you then go to a smaller number of flyweight objects(just one here, but note that the actual number depends on your application)that you configure at runtime to give the appearance of multiple, largerobjects (see Figure 5-5).

Whenever you’ve got a large number of massive objects that are putting astrain on your application, the Flyweight pattern should pop into your mind.If you can extract the specialized content from each such object that makes itunique and create a flyweight or set of flyweights that can act as customiz-able templates, this can be the way to go.

Yourcode

FlyweightObject

Configuration 1

Configuration 2

Configuration 3

Configuration 4

Figure 5-5:Using a

flyweightobject.

Yourcode

Heavy object 1

Heavy object 2

Heavy object 3

Heavy object 4

Figure 5-4:Code full of

heavy, largeobjects.

108 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 108

Page 130: Design Patterns For Dummies

For example, say that in your capacity as a design pattern expert, you’vebeen chosen to teach a class on design patterns. The software you’ve beengiven to track student records gives each student his or her own object, anda big one it is, too. You decide that it’s time to start saving some systemresources. This is a job for the Flyweight pattern.

Creating a studentTo simplify the student-tracking code, you decide to have one configurableFlyweight object named Student. This object has to be configurable to looklike as many students as needed, so you have to add getter/setter methods toget and set data, such as the student’s name, ID, and test score.

You might also want to be able to compare how this student did with respectto the other students, so you add a method called getStanding, whichreturns the student’s offset from average.

Here’s what the Student class — the flyweight class in this example — lookslike:

public class Student {String name;int id;int score;double averageScore;

public Student(double a){averageScore = a;

}

public void setName(String n){

name = n;}

public void setId(int i){

id = i;}

public void setScore(int s){

score = s;}

public String getName(){

return name;

109Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 109

Page 131: Design Patterns For Dummies

}

public int getID(){

return id;}

public int getScore(){

return score;}

public double getStanding(){

return (((double) score) / averageScore - 1.0) * 100.0;}

}

Note the getStanding method at the very end of this code, which returnsthe percentage by which the student’s score differs from the average score.Okay, now you have a configurable object that you can use to track theprogress of each student in the class. It’s time to see if it works.

Testing the Flyweight patternTo use the Flyweight pattern, you’ve got to keep track of the data you want touse to configure the flyweight to appear like various, more massive objects.In this case, you want to configure a Student object to appear like a set ofreal students, so you might store the students’ data (names, IDs, and testscores) in a set of arrays like this in TestFlyweight.java:

public class TestFlyweight {public static void main(String args[]){String names[] = {“Ralph”, “Alice”, “Sam”};int ids[] = {1001, 1002, 1003};int scores[] = {45, 55, 65};

.

.

.

To compare a particular student to the other students, you’ll also need todetermine the average test score, which you find by summing the scores anddividing by the total number of scores:

public class TestFlyweight {public static void main(String args[]){

110 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 110

Page 132: Design Patterns For Dummies

String names[] = {“Ralph”, “Alice”, “Sam”};int ids[] = {1001, 1002, 1003};int scores[] = {45, 55, 65};

double total = 0;for (int loopIndex = 0; loopIndex < scores.length; loopIndex++){total += scores[loopIndex];

}

double averageScore = total / scores.length;...

In this example, you need only one flyweight Student object, which youcreate by passing the average test score to the Student constructor:

public class TestFlyweight {public static void main(String args[]){String names[] = {“Ralph”, “Alice”, “Sam”};int ids[] = {1001, 1002, 1003};int scores[] = {45, 55, 65};

double total = 0;for (int loopIndex = 0; loopIndex < scores.length; loopIndex++){total += scores[loopIndex];

}

double averageScore = total / scores.length;

Student student = new Student(averageScore);...

Now you can configure the flyweight object as needed, rather than having adedicated object for each student. Here’s what it looks like in a loop that firstconfigures the flyweight object for a particular student, then displays the stu-dent’s name and standing:

public class TestFlyweight {public static void main(String args[]){String names[] = {“Ralph”, “Alice”, “Sam”};int ids[] = {1001, 1002, 1003};int scores[] = {45, 55, 65};

double total = 0;for (int loopIndex = 0; loopIndex < scores.length; loopIndex++){total += scores[loopIndex];

111Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 111

Page 133: Design Patterns For Dummies

}

double averageScore = total / scores.length;

Student student = new Student(averageScore);

for (int loopIndex = 0; loopIndex < scores.length; loopIndex++){student.setName(names[loopIndex]);student.setId(ids[loopIndex]);student.setScore(scores[loopIndex]);

System.out.println(“Name: “ + student.getName());System.out.println(“Standing: “ + Math.round(student.getStanding()));

System.out.println(“”);}

}}

Running this code gives you the desired results — the flyweight object is con-figured for each student on-the-fly, and his or her standing, expressed as apercentage offset from the average score, is displayed.

Name: RalphStanding: -18

Name: AliceStanding: 0

Name: SamStanding: 18

So instead of three full objects, you need only one configurable object. Muchlike the Singleton pattern, the idea behind the Flyweight pattern is to controlobject creation and limit the number of objects you need.

Handling threading betterThe Flyweight pattern is all about controlling object creation, but you mighthave noticed that it suffers from the same problem that the Singleton codedid earlier in this chapter — if you leave object creation up to the new opera-tor, you might end up with multiple objects when you wanted only a singleone, especially if you’ve got a multithreaded program.

If your code uses multiple threads, you can avoid creating too many flyweightobjects by taking the object creation process away from the new operator in

112 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 112

Page 134: Design Patterns For Dummies

the same way you did with singletons. You can create the flyweight objectwhen the class is first loaded, make the constructor private, and allow objectcreation only through a getInstance method:

public class StudentThreaded {String name;int id;int score;double averageScore;private static StudentThreaded singleObject = new StudentThreaded();

private StudentThreaded(){}

public void setAverageScore(double a){ averageScore = a;

}

public void setName(String n){

name = n;}

public void setId(int i){

id = i;}

public void setScore(int s){

score = s;}

public String getName(){

return name;}

public int getID(){

return id;}

public int getScore(){

return score;}

113Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 113

Page 135: Design Patterns For Dummies

public double getStanding(){

return (((double) score) / averageScore - 1.0) * 100.0;}

public static StudentThreaded getInstance(){

return singleObject;}

}

This code, TestFlyweightThreaded.java, puts to work this new versionof the flyweight by creating a student object and accessing it both from themain thread and a worker thread.

public class TestFlyweightThreaded implements Runable{Thread thread;

public static void main(String args[]){TestFlyweightThreaded t = new TestFlyweightThreaded();

}

public TestFlyweightThreaded(){String names[] = {“Ralph”, “Alice”, “Sam”};int ids[] = {1001, 1002, 1003};int scores[] = {45, 55, 65};

double total = 0;for (int loopIndex = 0; loopIndex < scores.length; loopIndex++){total += scores[loopIndex];

}

double averageScore = total / scores.length;

StudentThreaded student = StudentThreaded.getInstance();

student.setAverageScore(averageScore);student.setName(“Ralph”);student.setId(1002);student.setScore(45);

thread = new Thread(this, “second”);thread.start();

System.out.println(“Name: “ + student.getName() +

114 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 114

Page 136: Design Patterns For Dummies

“, Standing: “ + Math.round(student.getStanding()));}

public void run() {StudentThreaded student = StudentThreaded.getInstance();

System.out.println(“Name: “ + student.getName() +“, Standing: “ + Math.round(student.getStanding()));

}}

Running this code gives you this result, where you’re clearly dealing with thesame object in both the main and secondary threads:

Name: Ralph, Standing: -18Name: Ralph, Standing: -18

Does the Flyweight pattern have any drawbacks? Some. The main issue isthat it can take some time to configure a flyweight object, and if you’realways swapping configurations, you can lose much of the performance gainsyou hoped to achieve. Another possible drawback: Because you’re extractinga generic template class from your existing objects in order to create fly-weight objects, you’re adding another layer of programming, which can makemaintenance and extension harder.

115Chapter 5: From One to Many: The Singleton and Flyweight Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 115

Page 137: Design Patterns For Dummies

116 Part I: Getting to Know Patterns

09_798541 ch05.qxp 3/27/06 2:22 PM Page 116

Page 138: Design Patterns For Dummies

Part IIBecoming an OOP Master

10_838183 pt02.qxp 3/27/06 2:22 PM Page 117

Page 139: Design Patterns For Dummies

In this part . . .

In this part, you get the inside scoop on patterns andobject-oriented programming (OOP). Patterns have a

great deal to say about OOP and about how to improveyour object-oriented experience. Many programmers haveknee-jerk ways of working with OOP, which are just plainwrong. The design patterns in this part are there to pointyou to a better way.

10_838183 pt02.qxp 3/27/06 2:22 PM Page 118

Page 140: Design Patterns For Dummies

Chapter 6

Fitting Round Pegs into SquareHoles with the Adapter and

Facade PatternsIn This Chapter� Using the Adapter pattern

� Creating adapters

� Adapting Ace objects as Acme objects

� Handling adapter issues

� Using the Facade pattern

Sometimes, objects just don’t fit together as they should. A class mayhave changed, or an object turns out to be just too difficult to work with.

This chapter comes to the rescue by covering two design patterns: theAdapter pattern and the Facade pattern. The Adapter design pattern lets youadapt what an object or class has to offer so that another object or class canmake use of it. The Facade design pattern is similar, in that it changes thelook of an object, but the goal here is a little different: You use this designpattern to simplify the exposed methods of an object or class, making iteasier to work with that object or class.

The Adapter Scenario“Alright,” says the MegaGigaCo team leader, entering the room, “hold every-thing. Management has decreed that we switch our back-end framework tothe one sold by the CEO’s nephew’s company.”

11_798541 ch06.qxp 3/27/06 2:22 PM Page 119

Page 141: Design Patterns For Dummies

“Hmm,” says a programmer, “that could be a problem. Our online user inter-face takes customer orders using software from the Ace company and pack-ages them in objects of the Ace class. What type of objects can we pass tothe new back end?”

“Only the new Acme objects,” the team leader says, “not Ace objects.”

“Uh oh,” everyone says. “There go our jobs.”

You can see the problem. Currently, the Ace objects that are passed to theback end fit right in, as shown in Figure 6-1.

But when the back end is switched to take Acme objects (instead of Aceobjects), the current Ace objects created by the user interface won’t fit. That scenario looks like Figure 6-2.

“I have the solution,” you say. Everyone turns to you and you say, “Of course,as a consultant, I’ll have to charge a whopper fee on this.”

“Anything,” the team leader says. “The mortgage folks don’t understandabout missing payments if I lose my job.”

“You need to use the Adapter pattern,” you explain. “The Adapter pattern lets you adapt what an object or class exposes to what another object orclass expects.” You draw the solution on the whiteboard like that shown in Figure 6-3.

I‘m an Ace object I only takeAcme objects

User interface object Back endFigure 6-2:The user

interface nolonger

works withthe back

end.

I‘m an Ace object I take Ace objects

User interface object Back end

Figure 6-1:These twoobjects fit

togetherwell.

120 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 120

Page 142: Design Patterns For Dummies

“Ah,” says the development team. “We are beginning to understand.”

“Fine,” you say, “pay me some money.”

Fixing Connection Problems with Adapters

The Adapter design pattern lets you fix the interface between objects andclasses without having to modify the objects or classes directly. When you’re working with store-bought applications, you often can’t get inside toalter what one application produces to make it more palatable to anotherapplication.

This is particularly important in online development. As more and more com-panies start going for larger-scale enterprise solutions, they’re ditching thesmaller corporations’ software in favor of soup-to-nuts solutions from the bigboys like IBM. And that’s a shame because the issue is almost always one ofcompatibility — the smaller corporation’s software can’t talk to one or twoother components in the whole system. But turning to an expensive solutionisn’t always necessary. Usually, the problems can be fixed with a smalladapter. In other words, letting the big boys win at your expense could beavoided with just a little effort here.

How the Adapter pattern works is best seen in an example. Currently, theMegaGigaCo user interface, which I discuss in previous sections of this chap-ter, packages user data in objects of the Ace class. This class handles cus-tomer names with these two methods:

� setName

� getName

I‘m an Ace object I am an Ace toAcme Adapter

I only takeAcme objects

User interface object Adapter Back endFigure 6-3:

The adapterfits thepieces

together.

121Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 121

Page 143: Design Patterns For Dummies

But, as you know, MegaGigaCo is switching to Acme software for the backend, which has to be able to handle customer orders in a different way. Theproblem is that the Acme back end expects customer orders to be packagedin Acme objects. And Acme objects use four methods, not two, to handle thecustomer’s name. They are:

� setFirstName

� setLastName

� getFirstName

� getLastName

So you need an adapter to make sure that the Acme back end can handle Aceobjects. This adapter calls the two methods supported by the Ace object andextends that into a set of four methods that Acme objects usually offer, asshown in Figure 6-4.

That’s the idea and what the Adapter design pattern is all about.

The Gang of Four (GoF) book (Design Patterns: Elements of Reusable Object-Oriented Software, 1995, Pearson Education, Inc. Publishing as Pearson AddisonWesley) says the Adapter pattern lets you “Convert the interface of a classinto another interface the client expects. Adapter lets classes work togetherthat couldn’t otherwise because of incompatible interfaces.”

Although the official definition of the Adapter pattern talks about classes,this pattern actually has two variations: one for objects and one for classes. I look at both in this chapter.

You use the Adapter design pattern when you’re trying to fit a square peginto a round hole. If what a class or object exposes isn’t what you need toend up with, you can add an adapter — much like an electrical outlet adapterfor international travel — to give you what you need.

getNamesetName

setFirstNamesetLastName

getFirstNamegetLastName

User interface object Adapter Back end

Figure 6-4:The Ace

and Acmeadapter.

122 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 122

Page 144: Design Patterns For Dummies

This design pattern is particularly good when you’re working with legacycode that can’t be changed, while the software that interacts with that codedoes change.

Now to get down to actually putting the Adapter pattern to work.

Creating Ace objectsBefore the CEO’s nephew ruined everything for your department, Ace objectshandled customer names with just two methods: setName and getName —here’s an interface which specifies those two methods:

public interface AceInterface{public void setName(String n);public String getName();

}

The Ace objects that came out of the user interface were objects of theAceClass, which implemented this interface:

public class AceClass implements AceInterface {

.

.

.}

The two methods, setName and getName, were simplicity itself to add.

public class AceClass implements AceInterface {String name;

public void setName(String n){name = n;

}

public String getName(){return name;

}}

123Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 123

Page 145: Design Patterns For Dummies

That’s all you needed when the user interface produced Ace objects and theback end consumed Ace objects. But now the company is switching to anAcme back end, which consumes Acme objects. (Thanks again to thatnephew!)

Creating Acme objectsAcme objects must handle customer names with four methods: setFirstName, setLastName, getFirstName, and getLastName. Here’s an inter-face, AcmeInterface, which lists these methods:

public interface AcmeInterface{public void setFirstName(String f);public void setLastName(String l);public String getFirstName();public String getLastName();

}

Acme objects are based on the Acme class, which implements theAcmeInterface.

public class AcmeClass implements AcmeInterface{

.

.

.}

Here are the four methods this class exposes:

public class AcmeClass implements AcmeInterface{String firstName;String lastName;

public void setFirstName(String f){firstName = f;

}

public void setLastName(String l){lastName = l;

}

public String getFirstName(){

124 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 124

Page 146: Design Patterns For Dummies

return firstName;}

public String getLastName(){return lastName;

}}

At this point, you’ve got the Ace objects produced by the user interface and the Acme objects consumed by the back end. Now you’ve got to createan adapter that lets you plug Ace objects into the Acme back end.

Creating an Ace-to-Acme object adapterYou want to create an adapter to let software that expects an Acme object toactually work with an Ace object, so you should create an object adapter.Object adapters work by composition (see Chapter 2 for more on composi-tion) — the adapter stores the object it’s adapting inside itself.

Continuing with the example in this chapter, I name the adapter AceToAcmeAdapter, and because it has to look like an Acme object, it implements theAcmeInterface interface.

public class AceToAcmeAdapter implements AcmeInterface{

.

.

.}

This adapter uses object composition to hold the object it’s supposed to beadapting, an AceClass object. You can pass that object to the adapter’s con-structor, which will store the Ace object.

public class AceToAcmeAdapter implements AcmeInterface{AceClass aceObject;

public AceToAcmeAdapter(AceClass a){aceObject = a;

}...

}

125Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 125

Page 147: Design Patterns For Dummies

The difference between Ace and Acme objects is that Ace objects store thecustomer’s name as a single string, while Acme objects store the first nameand last name separately. To adapt between Ace and Acme objects, I split thename stored in the Ace object passed to the constructor into first and lastnames. You can recover the customer name from the stored Ace object usingits getName method.

public class AceToAcmeAdapter implements AcmeInterface{AceClass aceObject;String firstName;String lastName;

public AceToAcmeAdapter(AceClass a){aceObject = a;firstName = aceObject.getName().split(“ “)[0];lastName = aceObject.getName().split(“ “)[1];

}}

Now you’ve got the customer’s first and last names. To mimic an Acme object,you have to implement the Acme methods setFirstName, setLastName,getFirstName, and getLastName, returning or setting the customer’s firstand last names as needed. Here’s what those methods look like:

public class AceToAcmeAdapter implements AcmeInterface{AceClass aceObject;String firstName;String lastName;

public AceToAcmeAdapter(AceClass a){aceObject = a;firstName = aceObject.getName().split(“ “)[0];lastName = aceObject.getName().split(“ “)[1];

}

public void setFirstName(String f){firstName = f;

}

public void setLastName(String l){lastName = l;

}

public String getFirstName()

126 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 126

Page 148: Design Patterns For Dummies

{return firstName;

}

public String getLastName(){return lastName;

}}

Excellent — you’ve got your adapter. Is it going to work?

Testing the adapterThroughout this section, you have been adapting Ace objects so they looklike Acme objects. Now it’s time to see if the Adapter pattern is working theway you want it to. You can test this with the TestAdapter.java test har-ness, which starts by creating an Ace object that contains the customername Cary Grant.

public class TestAdapter {public static void main(String args[]){AceClass aceObject = new AceClass();

aceObject.setName(“Cary Grant”);...

}

Then you pass this Ace object to an AceToAcmeAdapter object.

public class TestAdapter {public static void main(String args[]){AceClass aceObject = new AceClass();

aceObject.setName(“Cary Grant”);

AceToAcmeAdapter adapter = new AceToAcmeAdapter(aceObject);...

}

127Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 127

Page 149: Design Patterns For Dummies

And you’re good to go — you can use the Acme methods like getFirstNameand getLastName with no problem.

public class TestAdapter {public static void main(String args[]){AceClass aceObject = new AceClass();

aceObject.setName(“Cary Grant”);

AceToAcmeAdapter adapter = new AceToAcmeAdapter(aceObject);

System.out.println(“Customer’s first name: “ + adapter.getFirstName());

System.out.println(“Customer’s last name: “ + adapter.getLastName());

}}

Running this code gives you:

Customer’s first name: CaryCustomer’s last name: Grant

Just what you’d expect if you were using a bona fide Acme object; the callingcode need never know it’s not dealing with an Acme object.

That’s how object adapters work. An adapter uses composition to store theobject it’s supposed to adapt, and when the adapter’s methods are called, ittranslates those calls into something the adapted object can understand andpasses the calls on to the adapted object. The code that calls the adapternever needs to know that it’s not dealing with the kind of object it thinks it is,but an adapted object instead.

Using object composition to wrap the adapted object is good object-orienteddesign, as discussed in Chapter 2. And note that if you subclass the adaptedobject, the adapter wrapper will be able to handle the subclassed objectswith minimal changes.

Inheriting class adaptersThere’s another kind of adapter besides object adapters — class adapters.You explain to the company programmers: “While object adapters use com-position to store the object they’re adapting, class adapters are designed touse multiple inheritance to merge the adapted class and the class you’readapting it to.”

128 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 128

Page 150: Design Patterns For Dummies

“There’s a flaw here,” say the company programmers, “if you’re working withJava.”

“And that is?” you ask.

“Java doesn’t support multiple inheritance,” they say.

“Right you are,” you say. “Which means you can’t create true class adaptersin Java.”

The GoF book uses languages like C++ and Smalltalk when discussing classadapters, but not Java because Java doesn’t support multiple inheritance. If it did, you could inherit from both the adapted class and the target classyou want to mimic in an adapter class, as you can see in Figure 6-5.

Here’s an example using single inheritance in Java, which is as close as youcan get to creating class adapters. The user interface team comes to you andsays, “We like Java AWT check boxes, and we’re not so fond of Swing checkboxes.”

“Ever thought of entering the 21st century?” you ask.

Ignoring the cheap jab, the UI (user interface) team says, “The problem isthat the rest of the user interface uses Swing — and we want to not only stickwith AWT check boxes, but also make them look like Swing check boxes toany Swing code that needs to use them.”

“That’s going to be expensive,” you say.

“Do we need to put in a special request to Sun Microsystems?” they ask.

“No, I’ll do it. But it’s going to cost you plenty.”

Target class Adapted class

Adapter

Figure 6-5:Inheritingfrom boththe target

and adaptedclass.

129Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 129

Page 151: Design Patterns For Dummies

You write the user interface code for Swing check boxes and determine if acheck box is checked using the isSelected method. But AWT check boxesdon’t support isSelected; the AWT method is getState. So you need anadapter to wrap an SWT check box and adapt the getState to isSelectedinstead, as shown in Figure 6-6.

The class adapter, CheckboxAdapter, is going to inherit from the AWTCheckbox class.

import java.awt.*;

public class CheckboxAdapter extends Checkbox{

.

.

.}

The public constructor passes control back to the AWT Checkbox construc-tor this way:

import java.awt.*;

public class CheckboxAdapter extends Checkbox{

public CheckboxAdapter(String n) {super(n);

}...

}

To implement the isSelected method of the CheckboxAdapter class, youjust pass on the data you get back from the AWT getState method.

getState isSelected

AWT check box Adapter Back end

Figure 6-6:Using anadapter

betweenAWT and

SWT.

130 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 130

Page 152: Design Patterns For Dummies

import java.awt.*;

public class CheckboxAdapter extends Checkbox{

public CheckboxAdapter(String n) {super(n);

}

public boolean isSelected(){return getState();

}}

You can use the adapted check boxes in Swing UI code; here’s how that worksin an example, Checkboxes.java, which builds a JFrame object that imple-ments the ItemListener interface to catch check box events:

import java.awt.*;import javax.swing.*; import java.awt.event.*;

public class Checkboxes extends JFrame implements ItemListener{}

The main method creates a new Checkboxes object and displays it.

import java.awt.*;import javax.swing.*; import java.awt.event.*;

public class Checkboxes extends JFrame implements ItemListener{

.

.

.public static void main(String args[]) {

final Checkboxes f = new Checkboxes();

f.setBounds(100, 100, 400, 300);f.setVisible(true);f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {

System.exit(0);}

});}

}

131Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 131

Page 153: Design Patterns For Dummies

The Checkboxes constructor creates four CheckboxAdapter objects andadds them to the content pane.

import java.awt.*;import javax.swing.*; import java.awt.event.*;

public class Checkboxes extends JFrame implements ItemListener{

CheckboxAdapter checks[];JTextField text;

public Checkboxes() {

Container contentPane = getContentPane();contentPane.setLayout(new FlowLayout());

checks = new CheckboxAdapter[4];

for(int loopIndex = 0; loopIndex <= checks.length - 1; loopIndex++){checks[loopIndex] = new CheckboxAdapter(“Check “ + loopIndex);

checks[loopIndex].addItemListener(this);contentPane.add(checks[loopIndex]);

}

text = new JTextField(30);

contentPane.add(text); }

.

.

.public static void main(String args[]) {

final Checkboxes c = new Checkboxes();

c.setBounds(100, 100, 400, 300);c.setVisible(true);c.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

c.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {

System.exit(0);}

});}

}

132 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 132

Page 154: Design Patterns For Dummies

You can handle the CheckboxAdapter objects as you would standard Swingcheck boxes when it comes to the isSelected method. When there’s a checkbox event, the itemChanged method will be called, and you can check whichof the check boxes is/are checked using isSelected in that method — theselected check boxes will be displayed in the text control.

import java.awt.*;import javax.swing.*; import java.awt.event.*;

public class Checkboxes extends JFrame implements ItemListener{

CheckboxAdapter checks[];JTextField text;

public Checkboxes() {

Container contentPane = getContentPane();contentPane.setLayout(new FlowLayout());

checks = new CheckboxAdapter[4];

for(int loopIndex = 0; loopIndex <= checks.length - 1; loopIndex++){checks[loopIndex] = new CheckboxAdapter(“Check “ + loopIndex);

checks[loopIndex].addItemListener(this);contentPane.add(checks[loopIndex]);

}

text = new JTextField(30);

contentPane.add(text); }

public void itemStateChanged(ItemEvent e){

String outString = new String(“Selected: “);

for(int loopIndex = 0; loopIndex <= checks.length - 1; loopIndex++){if(checks[loopIndex].isSelected()) {

outString += “ checkbox “ + loopIndex;}

}text.setText(outString);

}

public static void main(String args[])

133Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 133

Page 155: Design Patterns For Dummies

{final Checkboxes f = new Checkboxes();

f.setBounds(100, 100, 400, 300);f.setVisible(true);f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {

System.exit(0);}

});}

}

So object adapters rely on object composition, while class adapters rely oninheritance. Object adapters can be more flexible because they can workwith not just the objects they’ve been designed to adapt but also subclassedobjects of the adapted objects. But with class adapters, you have to modifythe class adapter to do the same thing. To be more flexible, in general, don’tforget the design principle that says you should favor composition overinheritance.

One final note on adapters — besides adapting the behavior of a class orobject, adapters can also improve that behavior by adding their own meth-ods. For example, an adapted object that reports temperatures in Fahrenheitmight be improved if its adapter also adds a method that reports tempera-tures in Centigrade.

Drawbacks of adapters? Not many — mostly that there’s an additional layerof code added, and so to maintain. But if rewriting legacy code isn’t anoption, adapters provide a good option.

Simplifying Life with FacadesSimilar to the Adapter pattern is the Facade design pattern. These two pat-terns work in much the same way, but they have different purposes. TheAdapter pattern adapts code to work with other code. But the Facade patterngives you a wrapper that makes the original code easier to deal with.

For example, say that someone’s designed a printer and shows it to youproudly. “How do I make it print?” you ask.

134 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 134

Page 156: Design Patterns For Dummies

“First,” he tells you, “call the initialize method.”

“Okay,” you say. “Now it prints?”

“No, you have to call the turnFanOn method.”

“Okay. Now it’ll print?” you ask.

“Nope. Call the warmUp method.”

“Alright. Now it prints, right?”

“Not yet. You have to call the getData method to get the data from the com-puter to print.”

“Okay, the getData method. And next?”

“The formatData method.”

“And?”

“The checkToner method, the checkPaperSupply method, the runInternalDiagnostics method, the checkPaperPath method, the . . . .”

“Hold on,” you say, writing a facade for the whole mess. Your facade calls allthose methods behind the scenes and dramatically simplifies the interface.“Here you go.”

“What’s this?” the printer designer asks.

“The print method,” you say. “Just call the print method, and the printerprints. No more to do.”

“Hey,” he says, “that might be a good idea. Now I can add aprepareToCallThePrintMethod method, a callThePrintMethodmethod, a cleanupAfterPrinting method, a. . . .”

“You’re hopeless,” you say.

The Facade design pattern makes an OOP interface (and that’s the generaluse of the term, not just a Java interface) easier to use. It’s fundamentally adesign issue — if an object or class interface is too hard to work with, theFacade pattern gives you a front end to that interface to make it easier. Here’sthe official GoF word on the Facade pattern — note that they’re also using theterm “interface” generically here:

135Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 135

Page 157: Design Patterns For Dummies

The GoF book says the Facade pattern should “Provide a unified interface toa set of interfaces in a system. Facade defines a higher-level interface thatmakes the subsystem easier to use.”

Often, you use the Facade pattern when you’re dealing with poorly encapsu-lated code. Not everyone is an OOP genius, as you quickly learn when youwork in any large-scale commercial software development environment.When you get tired of dealing with an awkwardly-designed interface and findyourself just wishing it did x, y, and/or z simply, that’s when it’s time for anew interface.

The idea is simple; a facade just simplifies the interface (using the genericsense of the word “interface” here, not a Java interface) between a class orobject and the code that makes use of that class or object. (See Figure 6-7.)

You usually use the Facade design pattern when you can’t rewrite the codeyou wish were simpler. Although using a Facade can fix the problem, it addsanother layer, and if the underlying code changes, you’re going to have tochange your Facade pattern as well.

There’s an OOP design principle at work here, sometimes called the Principleof Least Knowledge, sometimes called the Law of Demeter, sometimes justcalled effective encapsulation. The idea is that for effective OOP, you don’twant to insist that separate entities (classes of objects) have to know toomuch about each other. As much as possible, you should lock away the detailsinside each class or object and make the coupling between entities as loose aspossible (see Chapter 4 for more on loose coupling). If one object needs toknow too much about another to make their coupling loose, a Facade patterncan help.

Always go for the loosest coupling you can.

I‘ve got adifficultinterface

I am theFacade

I only needto deal witha simpleinterface

Figure 6-7:The Facade

patternmakes aninterface

less com-plicated.

136 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 136

Page 158: Design Patterns For Dummies

Dealing with a difficult objectHere’s an example showing how the Facade design pattern can save the day.Your company has just purchased the rival company, and management isjubilant.

“Hmm,” you ask, “isn’t this going to cause some software incompatibilities?Their product is very different from ours.”

“Nonsense,” says the Big Boss. “Things couldn’t be simpler.”

“Well,” you ask, “how do you set the name of an object?”

“Couldn’t be simpler. Just call the setFirstNameCharacter method. Thatsets the first character of the name.”

“Uh, what about the second character of the name?”

“Just call the setSecondNameCharacter method. Couldn’t be simpler.”

“So let me get this straight,” you say. “To set the name of an object, you callthe setFirstNameCharacter method to set the first character of the name,the setSecondNameCharacter method to set the second character of thename, all the way up to the setFiveMillionthNameCharacter to set thefive millionth name character?”

“Nope,” says the Big Boss, “you can only set seven-name characters.”

“Ah,” you say. “Couldn’t be simpler.”

“Right,” says the Big Boss.

Here’s the code given to you after the merger to handle the creation of theformer rival company’s product, DifficultProduct.

public class DifficultProduct{public DifficultProduct(){}...

}

137Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 137

Page 159: Design Patterns For Dummies

You set the name of this product character by character, using the setFirstNameCharacter, setSecondNameCharacter, setThirdNameCharacter,and so-forth methods, which are already built into this class:

public class DifficultProduct{char nameChars[] = new char[7];

public DifficultProduct(){}

public void setFirstNameCharacter(char c){nameChars[0] = c;

}

public void setSecondNameCharacter(char c){nameChars[1] = c;

}

public void setThirdNameCharacter(char c){nameChars[2] = c;

}

public void setFourthNameCharacter(char c){nameChars[3] = c;

}

public void setFifthNameCharacter(char c){nameChars[4] = c;

}

public void setSixthNameCharacter(char c){nameChars[5] = c;

}

public void setSeventhNameCharacter(char c){nameChars[6] = c;

}...

}

138 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 138

Page 160: Design Patterns For Dummies

To recover the name of the object, you call the getName method, which, sen-sibly, returns a String.

public class DifficultProduct{char nameChars[] = new char[7];

public DifficultProduct(){}

public void setFirstNameCharacter(char c){nameChars[0] = c;

}

public void setSecondNameCharacter(char c){nameChars[1] = c;

}

public void setThirdNameCharacter(char c){nameChars[2] = c;

}

public void setFourthNameCharacter(char c){nameChars[3] = c;

}

public void setFifthNameCharacter(char c){nameChars[4] = c;

}

public void setSixthNameCharacter(char c){nameChars[5] = c;

}

public void setSeventhNameCharacter(char c){nameChars[6] = c;

}

public String getName(){return new String(nameChars);

}}

139Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 139

Page 161: Design Patterns For Dummies

To set the name of a DifficultProduct object, you’ve got to work letter byletter — here’s how you’d create a printer, for example:

DifficultProduct difficultProduct = new DifficultProduct();

difficultProduct.setFirstNameCharacter(‘p’);difficultProduct.setSecondNameCharacter(‘r’);difficultProduct.setThirdNameCharacter(‘i’);difficultProduct.setFourthNameCharacter(‘n’);difficultProduct.setFifthNameCharacter(‘t’);difficultProduct.setSixthNameCharacter(‘e’);difficultProduct.setSeventhNameCharacter(‘r’);

“See?” asks the Big Boss, “couldn’t be easier.”

“Enough of this nonsense,” you say; “I’m going to write a facade.”

Creating a simplifying facade Your boss has given you your directive, and you get to work on a facade, theSimpleProductFacade class, which should look like the following:

public class SimpleProductFacade{public SimpleProductFacade(){}...

}

This facade is going to wrap the object (DifficultProduct in this exam-ple). Usually, the way you write a facade is to have the facade modify theobject’s external interface. You can also pass configuration parameters to the facade’s constructor, but that’s not needed in this example, which justcreates the new DifficultProduct object and stores it.

public class SimpleProductFacade{DifficultProduct difficultProduct;

public SimpleProductFacade(){difficultProduct = new DifficultProduct();

}...

}

140 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 140

Page 162: Design Patterns For Dummies

The problem with the original DifficultObject class is the way you setthe object’s name, using the clumsy methods setFirstNameCharacter,setSecondNameCharacter, setThirdNameCharacter, and so on. To fixthat, you decide to provide the facade with a simple setName method thatyou pass the name of the object as a string to. That method simply breaksthe name from a string to an array of chars, and passes those chars on to the wrapped DifficultObject methods setFirstNameCharacter,setSecondNameCharacter, setThirdNameCharacter, and so on methods:

public class SimpleProductFacade{DifficultProduct difficultProduct;

public SimpleProductFacade(){difficultProduct = new DifficultProduct();

}

public void setName(String n){char chars[] = n.toCharArray();

if(chars.length > 0){difficultProduct.setFirstNameCharacter(chars[0]);

}

if(chars.length > 1){difficultProduct.setSecondNameCharacter(chars[1]);

}

if(chars.length > 2){difficultProduct.setThirdNameCharacter(chars[2]);

}

if(chars.length > 3){difficultProduct.setFourthNameCharacter(chars[3]);

}

if(chars.length > 4){difficultProduct.setFifthNameCharacter(chars[4]);

}

if(chars.length > 5){difficultProduct.setSixthNameCharacter(chars[5]);

}

if(chars.length > 6){

141Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 141

Page 163: Design Patterns For Dummies

difficultProduct.setSeventhNameCharacter(chars[6]);}

}...

}

Methods that don’t need a facade, like the simple getName method, can bepassed on to the underlying object without modification.

public class SimpleProductFacade{DifficultProduct difficultProduct;

public SimpleProductFacade(){difficultProduct = new DifficultProduct();

}

public void setName(String n){char chars[] = n.toCharArray();

if(chars.length > 0){difficultProduct.setFirstNameCharacter(chars[0]);

}...if(chars.length > 6){difficultProduct.setSeventhNameCharacter(chars[6]);

}}

public String getName(){return difficultProduct.getName();

}}

Now you’ve wrapped the difficult object in a facade and exposed a set ofsimple-to-use methods, setName and getName. The next step is to get it allto actually do something.

142 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 142

Page 164: Design Patterns For Dummies

Testing the facadeTo make sure the facade code does what you want, test it with TestFacade.java. This code creates a new SimpleProductFacade object, then sets theobject’s name (“printer”) with setName and retrieves it with getName.

public class TestFacade {public static void main(String args[]){TestFacade t = new TestFacade();

}

public TestFacade(){SimpleProductFacade simpleProductFacade = new SimpleProductFacade();

simpleProductFacade.setName(“printer”);

System.out.println(“This product is a “ + simpleProductFacade.getName());

}}

And you get this, showing you were able to use the new setName method toset the name of the object:

This product is a printer

You’ve conquered the difficult object and its awkward interface with a facade.

Any facades that already exist in Java? There aren’t many built-in examples offacades in Java; Sun’s not about to admit that some Java subsection is hardenough to deal with that it has to include a facade to fix things. About theclosest you come to facades in Java are, paradoxically, the so-called Adapterclasses.

Java Adapter classes make implementing Java interfaces easier because theyimplement the interface’s methods themselves, using empty methods, whichmeans you don’t have to. So if you’ve got a built-in Java interface you want toimplement, you can often just use an Adapter class instead and override onlythose methods you want to change.

143Chapter 6: The Adapter and Facade Patterns

11_798541 ch06.qxp 3/27/06 2:22 PM Page 143

Page 165: Design Patterns For Dummies

The name adapter seems to suggest that Java adapters are all about theAdapter design pattern, but remember that the idea behind the Adapter pat-tern is, as the GoF say, “Adapter lets classes work together that couldn’t oth-erwise because of incompatible interfaces.” The Java Adapter classes aremore about making an interface easier to work with, which is closer to howthe GoF describe the Facade design pattern: “Facade defines a higher-levelinterface that makes the subsystem easier to use.”

Here’s an example that puts the Java WindowAdapter to work to handle just the window closing event in an inner class. (If you implemented theWindowListener interface, you’d have seven methods to implement, from windowActivated to windowOpened.)

import java.awt.*;import java.awt.event.*;

class AppFrame extends Frame{

public void paint(Graphics g){

g.drawString(“Using a window adapter”, 60, 100);}

}

public class app{

public static void main(String [] args){

AppFrame a = new AppFrame();

a.setSize(200, 200);

a.addWindowListener(new WindowAdapter() {public voidwindowClosing(WindowEvent e) {System.exit(0);}});

a.show();}

}

If you click this window’s Close button, the window closes and the applica-tion exits, thanks to the WindowAdapter.

144 Part II: Becoming an OOP Master

11_798541 ch06.qxp 3/27/06 2:22 PM Page 144

Page 166: Design Patterns For Dummies

Chapter 7

Mass Producing Objects with the Template Method and

Builder Patterns In This Chapter� Using the Template Method design pattern

� Creating robots using template methods

� Subclassing template methods

� Understanding how the Builder pattern differs from the Template Method pattern

� Using the Builder design pattern

“G ood news,” says the CEO of GigundoCorp — the new companyyou’re doing consulting work for — while running into the break

room. “We landed that contract!”

“What contract?” everyone asks.

“That contract where we build robots that build cars,” says the CEO.

“Oh, that contract,” everyone says.

“Now get out there and do the software,” says the CEO, shooing programmersout the door.

“Just a second,” you say. “Shouldn’t we take some time to look at the designissues? For example, is it possible you might be building other types ofrobots in the future?”

“Sure,” says the CEO, “we have other bids out there. But there’s no time tothink about that! We need to get started on those automotive robots!”

12_798541 ch07.qxp 3/27/06 2:23 PM Page 145

Page 167: Design Patterns For Dummies

“Yeah!” all the programmers cry, running back to their cubicles.

“Something tells me they’re going to be sorry,” you say to the empty breakroom, littered with empty Styrofoam cups rolling across the floor.

This chapter is all about two patterns that give you clever ways of dealingwith and adapting the process of creating objects: the Template Method pat-tern, and the Builder pattern. The Template Method pattern lets subclassesredefine the steps involved in creating an object, which is going to be usefulhere when it’s time to create different kinds of robots. And the Builder pat-tern gives you even more flexibility with the creation process by separatingthe construction process out into its own object. Both are coming up in thischapter.

Creating the First RobotThe GigundoCorp programmers churn out their software in a matter of days,and it’s simple enough. The robot starts with a constructor in the classRobot:

public class Robot {public Robot(){}...

}

And there are various actions that the robot can take, matched by methodsof the same name in the Robot class — for example, to start the robot, youcall the start method; to make the robot do its work by assembling a part(this robot is specialized to work on carburetors), call the assemblemethod; to test the installation of the part, call the test method, and so on.

public class Robot {public Robot(){}

public void start(){System.out.println(“Starting....”);

146 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 146

Page 168: Design Patterns For Dummies

}

public void getParts(){System.out.println(“Getting a carburetor....”);

}

public void assemble(){System.out.println(“Installing the carburetor....”);

}

public void test(){System.out.println(“Revving the engine....”);

}

public void stop(){System.out.println(“Stopping....”);

}}

All that’s needed is one method, called go here, which will make the robotdo its work by calling the start, getParts, assemble, test, and stopmethods:

public class Robot {public Robot(){}

public void go(){start();getParts();assemble();test();stop();

}

public void start(){System.out.println(“Starting....”);

}

public void getParts(){

147Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 147

Page 169: Design Patterns For Dummies

System.out.println(“Getting a carburetor....”);}

public void assemble(){System.out.println(“Installing the carburetor....”);

}

public void test(){System.out.println(“Revving the engine....”);

}

public void stop(){System.out.println(“Stopping....”);

}}

You can quickly put together a test harness to check out the Robot class.Just create a Robot object and call its go method to make the robot do itswork.

public class TestRobot {public static void main(String args[]){Robot robot = new Robot();

robot.go();}

}

And when you test the robot you get the following messages (much to theCEO’s delight):

Starting....Getting a carburetor....Installing the carburetor....Revving the engine....Stopping....

“Excellent!” cries the CEO. “Bonuses all around. I told you we didn’t need anyof that darn design pattern stuff.” The company programmers give you dirtylooks — and you happily collect your paycheck.

148 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 148

Page 170: Design Patterns For Dummies

Creating Robots with the TemplateMethod Pattern

“Good news!” cries the CEO of GigundoCorp, galloping into the break roomthe next day. “We landed that other contract!”

“What other contract?” everyone asks.

“The contract for a robot that bakes cookies,” the CEO says. “Now get outthere and create the software for it.”

The company programmers look into their coffee cups. “We’re going to haveto rewrite all our software from scratch,” they say.

The CEO glances at you from the corner of hooded eyes and asks, “Will itcost a lot?”

“Plenty,” the company programmers say. And all this time you’re resisting thetemptation to say, “I told you so.”

This is a good time to start talking about the Template Method design pat-tern. Here’s the problem the GigundoCorp programmers face — they have an automotive robot class as shown in Figure 7-1:

But now they need a cookie robot class as represented in Figure 7-2, and thatclass has to be written from scratch.

Cookie RobotFigure 7-2:The cookie

robot.

Automotive Robot

Figure 7-1:The

automotiverobot.

149Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 149

Page 171: Design Patterns For Dummies

The cookie robot has a number of methods in common with the automotiverobot, such as start and stop, but it needs to do different things as well — theassemble method should no longer display the message Getting a car-buretor. . . ., for example; it should display a more appropriate mes-sage like Getting flour and sugar. . . .

That’s where the Template Method pattern comes in. This pattern says you can write a method that defines a multi-step algorithm, just like the go method you’ve seen earlier in this chapter, which runs the multi-step algorithm corresponding to the robot’s work.

public void go(){start();getParts();assemble();test();stop();

}

Then you make this method into a template by allowing subclasses to rede-fine (in Java terms, override) various steps in this algorithm as needed. In thiscase, to build the cookie robot, for example, you’d override the getParts,assemble, and test methods.

According to the official Gang of Four (GoF) phrasing, the Template Methodwill “Define the skeleton of an algorithm in an operation, deferring somesteps to subclasses. Template Method lets subclasses redefine certain stepsof an algorithm without changing the algorithm’s structure.” (Design Patterns:Elements of Reusable Object-Oriented Software, 1995, Pearson Education, Inc.Publishing as Pearson Addison Wesley.)

So that means you should use the Template Method pattern when you havean algorithm that is made of up multiple steps, and you want to be able tocustomize some of those steps. Note that if you want to rewrite everythingfrom scratch every time — if every step has to be customized by writing itfrom scratch — then you have no need of a template. Only if you have stepsthat are shared by various implementations of the algorithm do you need towork with a template.

Creating robots by templateIf you had a template method to base robots on, you could make use of it inan inheriting class as illustrated in Figure 7-3:

150 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 150

Page 172: Design Patterns For Dummies

By calling the go method, your multi-step algorithm is executed. To cus-tomize the inherited class, you only have to override the steps in the algo-rithm you want, like this in the cookie robot case (see Figure 7-4):

That’s the idea behind the Template Method design pattern — this methodexecutes a multi-step algorithm that’s customizable by subclasses. How’sthat going to look in the case of the two types of robots you need, automotiverobots and cookie robots?

Inheriting class

Base class

Template method:

go() { start(); getParts(); assemble(); test(); stop();}

getParts();assemble();test();

Figure 7-4:Modifying

the inheritedmethods.

Inheriting class

Base class

Template method:

go() { start(); getParts(); assemble(); test(); stop();}

Figure 7-3:Inheriting

from thetemplate

base class.

151Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 151

Page 173: Design Patterns For Dummies

I start by putting the actual template method (the go method, which exe-cutes the work a robot has to do) in an abstract class (abstract so it has tobe inherited), called RobotTemplate.

public abstract class RobotTemplate{public final void go(){start();getParts();assemble();test();stop();

}...

}

And this class will also have default implementations of each of the methodscorresponding to the steps in the algorithm, start, getParts, assemble,test, and stop.

public abstract class RobotTemplate{public final void go(){start();getParts();assemble();test();stop();

}

public void start(){System.out.println(“Starting....”);

}

public void getParts(){System.out.println(“Getting parts....”);

}

public void assemble(){System.out.println(“Assembling....”);

}

public void test()

152 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 152

Page 174: Design Patterns For Dummies

{System.out.println(“Testing....”);

}

public void stop(){System.out.println(“Stopping....”);

}}

If a robot is fine with any of these methods, such as the start and stopmethods, it doesn’t have to override them. Otherwise, you can customizewhat specific methods do in subclasses.

For example, say you want to use the RobotTemplate class to create anautomotive robot. You’d start by extending the abstract RobotTemplateclass in a new class, AutomotiveRobot.

public class AutomotiveRobot extends RobotTemplate{

.

.

.}

The automotive robot should override a few of the RobotTemplatemethods; for example, getParts should now display Getting a carburetor. . . ., assemble should now display Installing the carburetor. . . ., and test should display Revving theengine. . . ., so here’s how you can customize the backbone multi-step algorithm provided by the template:

public class AutomotiveRobot extends RobotTemplate{public void getParts(){System.out.println(“Getting a carburetor....”);

}

public void assemble(){System.out.println(“Installing the carburetor....”);

}

public void test(){System.out.println(“Revving the engine....”);

}}

153Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 153

Page 175: Design Patterns For Dummies

You can also customize your template-based code by adding additional methods, such as a constructor that takes a name for the new robot and a getName method that returns that name.

public class AutomotiveRobot extends RobotTemplate{private String name;

public AutomotiveRobot(String n){name = n;

}

public void getParts(){System.out.println(“Getting a carburetor....”);

}

public void assemble(){System.out.println(“Installing the carburetor....”);

}

public void test(){System.out.println(“Revving the engine....”);

}

public String getName(){return name;

}}

Excellent. You’ve used the inherited template go method and customized itfor automotive robots.

You can also customize the inherited template method for cookie robots in anew class, CookieRobot, which also extends the RobotTemplate class. You can write the CookieRobot class by making the getParts method dis-play Getting flour and sugar. . . ., the assemble method displayBaking a cookie. . . ., and the test method display Crunching acookie. . . .

public class CookieRobot extends RobotTemplate{private String name;

public CookieRobot(String n)

154 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 154

Page 176: Design Patterns For Dummies

{name = n;

}

public void getParts(){System.out.println(“Getting flour and sugar....”);

}

public void assemble(){System.out.println(“Baking a cookie....”);

}

public void test(){System.out.println(“Crunching a cookie....”);

}

public String getName(){return name;

}}

Now that you’ve used the go template method in two new classes,AutomotiveRobot and CookieRobot, and had to rewrite only those steps of the robot algorithm that differed between the two types of robots — you didn’t have to rewrite these two classes from scratch.

Testing the creation of robotsWant to put this to the test? Run TestTemplate.java, which creates anobject of the AutomotiveRobot and CookieRobot classes and calls the go method of each.

public class TestTemplate {public static void main(String args[]){AutomotiveRobot automotiveRobot = new AutomotiveRobot(“Automotive Robot”);

CookieRobot cookieRobot = new CookieRobot(“Cookie Robot”);

System.out.println(automotiveRobot.getName() + “:”);automotiveRobot.go();

155Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 155

Page 177: Design Patterns For Dummies

System.out.println();System.out.println(cookieRobot.getName() + “:”);cookieRobot.go();

}}

When you run this test, you see that you have indeed been able to customizethe multiple steps of the two types of robots’ work algorithms.

Automotive Robot:Starting....Getting a carburetor....Installing the carburetor....Revving the engine....Stopping....

Cookie Robot:Starting....Getting flour and sugar....Baking a cookie....Crunching a cookie....Stopping....

Built-in Template Methods in JavaAny built-in uses of the Template Method design pattern come to mind inJava? Here’s one — the update method built into Java to handle windowrefreshes. The update method is responsible for redrawing a window asneeded, and it performs a well-defined sequence of steps. One of those steps,a call to the paint method, which is responsible for drawing the window’sdisplay, is available for overloading, and you’ve probably overloaded thepaint method dozens of times. Bet you never thought you were using theTemplate Method design pattern.

There are many Java window classes that use the update method as a tem-plate method. For example, there’s an update method in the JFrame class,and you can override the paint method called by update to do your ownpainting in a JFrame. Here’s an example that displays a JFrame:

import javax.swing.*;import java.awt.*;import java.awt.event.*;

public class Hello extends JFrame {

public Hello()

156 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 156

Page 178: Design Patterns For Dummies

{super(“Hello Application”);

}

public static void main(String args[]) {

final JFrame h = new Hello();

h.setBounds(100, 100, 300, 300);h.setVisible(true);h.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

h.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {

System.exit(0);}

});}

}

All you’re going to get here is an empty window, unless you do somethingmore. And that’s overriding the paint method this way, where I’m using the Graphics object passed to that method to write No worries. in thewindow.

import javax.swing.*;import java.awt.*;import java.awt.event.*;

public class Hello extends JFrame {

public Hello() {

super(“Hello Application”);}

public static void main(String args[]) {

final JFrame h = new Hello();

h.setBounds(100, 100, 300, 300);h.setVisible(true);h.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

h.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {

System.exit(0);}

});

157Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 157

Page 179: Design Patterns For Dummies

}

public void paint (Graphics g){

super.paint(g);g.drawString(“No worries.”, 60, 60);

}}

By overriding the paint method, you’ve changed one of the steps in thealgorithm that displays your window.

Adding a hookYou can also provide hooks into your algorithm. A hook is a method that con-trols some aspect of that algorithm. For example, if you wanted to make thetesting part of the Robot algorithm optional, you could surround that partwith a conditional whose condition is set by a hook method named testOK.

public abstract class RobotHookTemplate{public final void go(){start();getParts();assemble();if (testOK()){test();

}stop();

}

public void start(){System.out.println(“Starting....”);

}

public void getParts(){System.out.println(“Getting parts....”);

}

public void assemble(){System.out.println(“Assembling....”);

}

public void test()

158 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 158

Page 180: Design Patterns For Dummies

{System.out.println(“Testing....”);

}

public void stop(){System.out.println(“Stopping....”);

}

public boolean testOK(){return true;

}}

By default, you can ignore the hook method testOK — if you do nothing withit, the Robot algorithm calls the full set of steps, including the test method.However, you can hook into the algorithm by overriding the testOK methodin a subclass, like this in a new class, CookieHookRobot, where testOKreturns false, not true.

public class CookieHookRobot extends RobotHookTemplate{private String name;

public CookieHookRobot(String n){

name = n;}

public void getParts(){System.out.println(“Getting flour and sugar....”);

}

public void assemble(){System.out.println(“Baking a cookie....”);

}

public String getName(){return name;

}

public boolean testOK(){return false;

}

}

159Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 159

Page 181: Design Patterns For Dummies

Because the hook method testOK returns false now, the Robot algorithmwill not call the test method, as you know from the go method.

public final void go(){start();getParts();assemble();if (testOK()){test();

}stop();

}

Testing the hook methodNow put this into a test harness, TestHookTemplate.java, and call thecookieHookRobot.go method.

public class TestHookTemplate {public static void main(String args[]){CookieHookRobot cookieHookRobot = new CookieHookRobot(“Cookie Robot”);

System.out.println(cookieHookRobot.getName() + “:”);cookieHookRobot.go();

}}

You’ll see the Robot algorithm at work — minus the test step:

Cookie Robot:Starting....Getting flour and sugar....Baking a cookie....Stopping....

There you have it — you didn’t have to do anything with the hook, but if youdid, you can affect the execution of the algorithm. If you build your algorithmusing a succession of abstract methods, each of these methods has to beoverridden in a subclass; hooks, on the other hand, don’t have to be overrid-den at all, unless you want to change the default execution of the algorithm.

160 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 160

Page 182: Design Patterns For Dummies

You use the Template Method design pattern when you’ve got an algorithm ofseveral steps and you want to allow customization by subclasses. It’s thateasy. Implement the steps in that algorithm as an overridable method calls inan abstract class, and let the subclasses override those steps as required.

The Template Method pattern is great when you have a multi-step algorithmto implement that you also want to customize. There’s an allied pattern thatdoes much the same thing that I take a look at in the next section, called theBuilder pattern.

Building Robots with the Builder Pattern“Good news!” cries the CEO of GigundoCorp, trotting into the break room.“Our customers have told us that they want more control over what actions a robot will perform, so we can’t use a pre-written template method anymore.Now they want to be able to pick and choose each action the robot will perform.”

“Let me get this straight,” you say. “The way we’ve set things up, robots start,get parts, assemble, test, and then stop. But now customers want to controlthe order and number of those commands? So a robot might start, then test,then assemble, then stop?”

“Right,” says the CEO.

“Time for a new design pattern,” you say.

“I was afraid of that,” says the CEO.

The client rulesIn the Template Method design pattern, the multi-step algorithm is king —you set it up the way you want it, and all the subclasses have to follow yourlead. But now the situation is different — the client wants to set the orderand number of steps in the algorithm. So the code you develop will no longerbe central, as it was, and will have to be encapsulated in a new class — abuilder class.

The Template Method pattern you saw earlier in this chapter lets you cus-tomize the steps of a multi-step algorithm by overriding the steps in thatalgorithm as you can see in Figure 7-5.

161Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 161

Page 183: Design Patterns For Dummies

Everything is based on the template method in this design pattern, and youcan customize that template as needed. But now you no longer have controlover the algorithm — the client does, and it constructs a robot by specifyingwhich actions, and in which order, the robot should execute. For example, to add a start action, the client code might call an addStart method. To add a test action, it might call an addTest method, and so on as shown inFigure 7-6.

Being able to specify the actions the robot under construction should exe-cute, and in what order, is now under the control of the GigundoCorp cus-tomer. So your code now moves to a new class, the CookieRobotBuilderclass, which is the class that supports the addStart, addTest,addAssemble, and addStop methods as shown in Figure 7-7.

Client code

addStartaddTestaddAssembleaddStop

Figure 7-6:Customizingclient code

with anaddStartmethod.

Inheriting class

Base class

Template method:

go() { start(); getParts(); assemble(); test(); stop();}

getParts();assemble();test();

Figure 7-5:The

TemplateMethodpattern

allows youto customize

the multi-step

algorithm.

162 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 162

Page 184: Design Patterns For Dummies

So the client code uses the CookieRobotBuilder to build a cookie robot.When the client code is done building the robot, it calls the CookieRobotBuilder getRobot method to get the newly built robot, as illustrated inFigure 7-8.

What if the client code wanted to build an automotive robot instead, givingthat robot the same sequence of actions? In that case, all it would have to do is to use an AutomotiveRobotBuilder object instead, as shown inFigure 7-9.

Client code

addStartaddTestaddAssembleaddStopgetRobot

AutomotiveRobotBuilder

robot

Figure 7-9:Using the

AutomotiveRobot

Builderclass for

constructioninstead of

the CookieRobot

Builderclass.

Client code

addStartaddTestaddAssembleaddStopgetRobot

CookieRobotBuilder

robot

Figure 7-8:Sending therobot to theclient code.

Client code

addStartaddTestaddAssembleaddStop

CookieRobotBuilder

Figure 7-7:Separating

out theconstruction

code intothe Cookie

RobotBuilder

class.

163Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 163

Page 185: Design Patterns For Dummies

So now that the client code has taken over the specification of the algorithm,you don’t inherit a template method anymore and then customize thatmethod to create your own robots. Instead, to create different types ofrobots, you allow client code to use different builder objects.

That’s the idea: the client code now sets the sequence and number of thesteps in the algorithm, and selects which builders to use to create the robotit wants.

After the sequence and number of steps have been set up in the client code,that code can use them over and over, creating all kinds of different robots —all it has to do is to switch between various builders. And that’s what theBuilder design pattern is all about.

The GoF says that the Builder design patterns let you “Separate the construction of a complex object from its representation so that the same construction processes can create different representations.”

The main difference between the Template Method and the Builder design pat-terns is in who creates the sequence of steps in the algorithm. In the TemplateMethod, you do, and subclasses can make alterations. In the Builder pattern,the client code sets the sequence and number of steps in the algorithm andswaps between the builders you provide to create various objects that embodythat algorithm.

Use the Builder design pattern when you want client code to have controlover the construction process but want to be able to end up with differentkinds of objects (each of which is built by a different type of builder). Forexample, this is the pattern you want when you’re building robots using thesame construction process but want to be able to end up with different kindsof robots — all the client code has to do is to load different builders; the con-struction process stays the same. Here’s another example — you might wantto take a text stream and build a document from it but be able to create docu-ments in various formats, such as RTF, Microsoft Word, plain text, and so on.Although the construction process is the same for each document, you use adifferent builder for each type of document.

In other words, when the client code has control over the constructionprocess but you still want to be able to construct different kinds of objects,the Builder design pattern should spring to mind.

This pattern is similar to the Factory pattern, also one of the GoF patterns,but the Factory pattern can be more involved, and it centers on a single-stepcreation process, not a configurable sequence of steps, as here.

164 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 164

Page 186: Design Patterns For Dummies

Letting clients build robotsWhen you use the Builder pattern, the client code is in charge of the construc-tion process, and it’s up to your builders to do what the client code wants. Tolet the client build robots to perform various sequences of actions — starting,assembling, stopping, and so on — I make the RobotBuilder interface sup-port these methods: addStart, addGetParts, addAssemble, addTest,and addStop.

For example, to make the robot under construction start, test, assemble, and then stop, the client code only needs to call the builder’s addStart,addTest, addAssemble, and addStop methods, in that order. When therobot has been constructed, the client code only needs to call the builder’sgetRobot method to get the new robot. And the new robot object will sup-port a go method that, when called, executes the sequence of actions it’sbeen constructed to run.

Because you can have multiple types of robot builders — those that buildcookie robots or automotive robots, for example — I start by creating aRobotBuilder interface that all robot builders have to implement. Thisinterface lists the methods that all robot builders must implement, fromaddStart to addStop, as well as the getRobot method:

public interface RobotBuilder {public void addStart();public void addGetParts();public void addAssemble();public void addTest();public void addStop();public RobotBuildable getRobot();

}

I start by creating the cookie robot builder, CookieRobotBuilder, which,as all robot builders must, implements the RobotBuilder interface.

public class CookieRobotBuilder implements RobotBuilder{

.

.

.}

The robot that the code will build is based on the CookieRobotBuildableclass, coming up in the “Creating some buildable robots” section. The con-structed robot is going to be a CookieRobotBuildable object, so we’llneed an object of that class in the builder (this is the object the builder willreturn as the fully constructed robot):

165Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 165

Page 187: Design Patterns For Dummies

public class CookieRobotBuilder implements RobotBuilder{CookieRobotBuildable robot;

public CookieRobotBuilder(){robot = new CookieRobotBuildable();

}...

}

The client code can add robot actions like start, stop, test, assemble,getParts, and so on in any order, and each action can be added any numberof times. To keep track of the sequence of actions the client code wants tobuild into the current robot, I use an ArrayList object named actions inthe builder.

import java.util.*;

public class CookieRobotBuilder implements RobotBuilder{CookieRobotBuildable robot;ArrayList<Integer> actions;

public CookieRobotBuilder(){robot = new CookieRobotBuildable();actions = new ArrayList<Integer>();

}...

}

An easy way of storing the action sequence in the actions ArrayList asit’s built by the client code is to assign an integer for each action, as shown inthe following:

� start = 1

� getParts = 2

� assemble = 3, and so on

I store Integer objects in the ArrayList. For example, when the clientcode wants to add a start action, it calls addStart, making the robot builderadd an Integer object containing 1 to the actions ArrayList, and so on.Here are all the methods that add actions to the robot in the builder:

166 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 166

Page 188: Design Patterns For Dummies

import java.util.*;

public class CookieRobotBuilder implements RobotBuilder{CookieRobotBuildable robot;ArrayList<Integer> actions;

public CookieRobotBuilder(){robot = new CookieRobotBuildable();actions = new ArrayList<Integer>();

}

public void addStart(){actions.add(new Integer(1));

}

public void addGetParts(){actions.add(new Integer(2));

}

public void addAssemble(){actions.add(new Integer(3));

}

public void addTest(){actions.add(new Integer(4));

}

public void addStop(){actions.add(new Integer(5));

}...

}

When the client code wants to get the robot object it has configured from thebuilder, it calls the builder’s getRobot method. When that method is called,you know the construction process is complete, so you can configure therobot by passing it the ArrayList of actions it should execute. In this exam-ple, each robot can be configured by passing the ArrayList to the robot’sloadActions method; after the robot is configured, it’s returned by thegetRobot method in the builder.

167Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 167

Page 189: Design Patterns For Dummies

import java.util.*;

public class CookieRobotBuilder implements RobotBuilder{CookieRobotBuildable robot;ArrayList<Integer> actions;

public CookieRobotBuilder(){robot = new CookieRobotBuildable();actions = new ArrayList<Integer>();

}

public void addStart(){actions.add(new Integer(1));

}...

public void addStop(){actions.add(new Integer(5));

}

public RobotBuildable getRobot(){robot.loadActions(actions);return robot;

}

}

That completes the builder, which lets the client code configure the robot byadding various actions — as many, and in whatever order, as required. Sohow about creating the Robot class that the robots will be based on?

Creating some buildable robotsEach type of builder builds a different type of robot, and each robot is basedon its own class, such as the CookieRobotBuildable or AutomotiveRobotBuildable class. All robots have to have a go method to make themexecute their actions, so you might start with an interface, RobotBuildable,that makes sure that the go method is implemented in all robots.

public interface RobotBuildable{public void go();

}

168 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 168

Page 190: Design Patterns For Dummies

Now all Robot classes will implement this interface. Here’s how the CookieRobotBuildable class, which you make cookie robot objects out of, works.You can load the robot with the ArrayList of actions that it’s supposed toexecute into an ArrayList named actions in the loadActions method,which is called by the robot builder to configure this robot.

import java.util.*;

public class CookieRobotBuildable implements RobotBuildable{ArrayList<Integer> actions;

public CookieRobotBuildable(){}

public void loadActions(ArrayList a){actions = a;

}...

}

When the client code wants the robot to perform the actions it’s been built toperform, that code calls the robot’s go method. In the go method, you caniterate over the actions ArrayList and call the methods correspondingto the actions that have been built into the robot. For example, unpacking a 1from the ArrayList means you should call the start method, unpacking a2 means you should call the getParts method, and so on. You can handlethis with an Iterator object and a switch statement in the robot’s gomethod, as shown in the following code:

import java.util.*;

public class CookieRobotBuildable implements RobotBuildable{ArrayList<Integer> actions;

public CookieRobotBuildable(){}

public final void go(){Iterator itr = actions.iterator();

169Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 169

Page 191: Design Patterns For Dummies

while(itr.hasNext()) {switch ((Integer)itr.next()){case 1: start();break;

case 2: getParts();break;

case 3: assemble();break;

case 4: test();break;

case 5: stop();break;

}}

}...

public void loadActions(ArrayList a){actions = a;

}}

You have to add the methods for each action as well: The start method (displays Starting. . . .), the getParts method (displays Gettingflour and sugar. . . ., for a cookie robot), and so on.

import java.util.*;

public class CookieRobotBuildable implements RobotBuildable{ArrayList<Integer> actions;

public CookieRobotBuildable(){}

public final void go(){Iterator itr = actions.iterator();

while(itr.hasNext()) {switch ((Integer)itr.next()){

170 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 170

Page 192: Design Patterns For Dummies

case 1: start();break;

case 2: getParts();break;

case 3: assemble();break;

case 4: test();break;

case 5: stop();break;

}}

}

public void start(){System.out.println(“Starting....”);

}

public void getParts(){System.out.println(“Getting flour and sugar....”);

}

public void assemble(){System.out.println(“Baking a cookie....”);

}

public void test(){System.out.println(“Crunching a cookie....”);

}

public void stop(){System.out.println(“Stopping....”);

}

public void loadActions(ArrayList a){actions = a;

}}

171Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 171

Page 193: Design Patterns For Dummies

That completes the CookieRobotBuildable class. Now you’ve got therobot builder and the robot; all you need is the client code that will actuallyconfigure the robot as it wants.

Because the builder and the robot are both based on interfaces, the clientcode can be independent of the type of builder or robot it wants. The con-struction code can stay the same no matter what builder and what robot arerequired. The only place where it matters which builder you want to use iswhere you actually load that builder.

Testing the robot builderThe test harness, TestRobotBuilder.java, acts as the client code. Thatcode lets the user decide what type of robot to build with the followingprompt: Do you want a cookie robot [c] or an automotive one [a]?

import java.io.*;

public class TestRobotBuilder {public static void main(String args[]){String response = “a”;

System.out.print(“Do you want a cookie robot [c] or an automotive one [a]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}...

}

Depending on which type of robot the user selects, a cookie robot builder oran automotive robot builder is created and stored in the RobotBuilder vari-able builder. (Note that the rest of the code is independent of the type ofbuilder and robot you’re using.)

172 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 172

Page 194: Design Patterns For Dummies

import java.io.*;

public class TestRobotBuilder {public static void main(String args[]){RobotBuilder builder;String response = “a”;

System.out.print(“Do you want a cookie robot [c] or an automotive one [a]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}

if (response.equals(“c”)){builder = new CookieRobotBuilder();

} else {builder = new AutomotiveRobotBuilder();

}...

}}

Then this client code can construct the robot as it wants, using the builder’saddStart, addGetParts, addAssemble, addTest, and addStop methods,which it can use in any order.

import java.io.*;

public class TestRobotBuilder {public static void main(String args[]){RobotBuilder builder;String response = “a”;

System.out.print(“Do you want a cookie robot [c] or an automotive one [a]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

173Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 173

Page 195: Design Patterns For Dummies

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}

if (response.equals(“c”)){builder = new CookieRobotBuilder();

} else {builder = new AutomotiveRobotBuilder();

}

//Start the construction process.

builder.addStart();builder.addTest();builder.addAssemble();builder.addStop();

.

.

.}

}

After the robot has been built, the client code calls the builder’s getRobotmethod, which returns a robot stored in a RobotBuildable variable. And you can call the robot’s go method to make sure it does what it’s supposed to.

import java.io.*;

public class TestRobotBuilder {public static void main(String args[]){RobotBuilder builder;RobotBuildable robot;String response = “a”;

System.out.print(“Do you want a cookie robot [c] or an automotive one [a]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}

174 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 174

Page 196: Design Patterns For Dummies

if (response.equals(“c”)){builder = new CookieRobotBuilder();

} else {builder = new AutomotiveRobotBuilder();

}

//Start the construction process.

builder.addStart();builder.addTest();builder.addAssemble();builder.addStop();

robot = builder.getRobot();

robot.go();}

}

This client code can produce cookie robots or automotive robots simply byselecting the right builder. Here, it is creating a cookie robot:

Do you want a cookie robot [c] or an automotive one [a]? cStarting....Crunching a cookie....Baking a cookie....Stopping....

And here it is creating an automotive robot, using the same constructionsequence:

Do you want a cookie robot [c] or an automotive one [a]? aStarting....Revving the engine....Installing the carburetor....Stopping....

Not bad. You’ve put builders to work to let client code take control over theconstruction process.

175Chapter 7: The Template Method and Builder Patterns

12_798541 ch07.qxp 3/27/06 2:23 PM Page 175

Page 197: Design Patterns For Dummies

176 Part II: Becoming an OOP Master

12_798541 ch07.qxp 3/27/06 2:23 PM Page 176

Page 198: Design Patterns For Dummies

Chapter 8

Handling Collections with theIterator and Composite Patterns

In This Chapter� Using the Iterator pattern

� Creating iterators

� Iterating over vice presidents using a home-grown iterator

� Understanding the Composite pattern

� Using iterators inside composites

� Parsing XML documents using the Composite pattern

The CEO of GiantDataPool Inc., the new corporation you’re consulting for,sidles into your cubicle and says something inaudible.

“What?” you ask.

The CEO looks around with a haunted expression and says, “I have a top-secret project for you.”

“Top secret?” you ask. “What’s it about?”

“Not so loud!” whispers the CEO. “We need an outsider for this project, so I’mcoming to you. It seems that we’ve got some administrative bloat going on,and we need to track our vice presidents — no one knows how many thereare now. There seems, um, to be about twice as many vice presidents as pro-grammers now.”

“Too much management, not enough programmers,” you sigh. “The typicalcorporate story.”

13_798541 ch08.qxp 3/27/06 2:23 PM Page 177

Page 199: Design Patterns For Dummies

“We want to start with the Sales division,” the CEO whispers. “Can you writea program that loops over all the VPs and prints them all out?”

“Better than that,” you say. “I’ll use the Iterator pattern.”

This chapter is about two allied design patterns: the Iterator pattern and theComposite pattern. The Iterator pattern gives you a way of accessing the ele-ments inside an object without having to know the internal details of thatobject. For example, Sun has introduced all kinds of collections in Java rela-tively recently, and these collections allow you to create iterators — specialobjects designed to give you access to the members of a collection — foreasy access.

The Composite design pattern is also about collections. With the Compositepattern, the idea is that you can create tree-like structures where each item inthe tree — a single leaf with no children, or an entire branch with many chil-dren — can be handled in the same way. The Composite pattern is designedto let you handle different types of objects in the same collection in the sameway, and iterators fit in naturally here — to handle the elements of a treebranch, for example, you can iterate over them. You learn how to make themost of both these patterns in this chapter.

Accessing Objects with the Iterator Pattern

When you’re dealing with a collection of objects, the Iterator pattern is theideal solution. These days, you have all kinds of collections to work with —trees, binary trees, arrays, ring buffers, hashes, hash maps, array lists, andmany more. The ways these collections store their data internally vary agreat deal, and if you want to access that data in the same way as these col-lections do internally, you have to learn a different technique for every collec-tion type.

That’s where the Interator pattern comes in. You can use a well-defined inter-face of methods to access the elements of a collection. Over the years, thosestandard methods have become widely adopted, and they appear throughoutthis chapter. Using those methods, you can access the elements in collec-tions in a standard way.

According to the Gang of Four (GoF), you can use the Iterator design patternto “Provide a way to access the elements of an aggregate object sequentiallywithout exposing its underlying representation.” (Design Patterns: Elements ofReusable Object-Oriented Software, 1995, Pearson Education, Inc. Publishing asPearson Addison Wesley).

178 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 178

Page 200: Design Patterns For Dummies

In other words, iterators are designed to let you handle many different kindsof collections by accessing their members in a standard, accepted way, with-out having to know the internal details of those collections.

The Iterator design pattern is especially important when the collection you’recreating is made up internally of separate subcollections, as when you’vemixed hashes with array lists, for example.

Iterators are usually written in Java as standalone classes. Why aren’t itera-tors built into the collections they work with? They could be, but in Java andother languages, they’re not. The design insight here is one of what’s calledsingle responsibility — a class should have only one thing to do. The thinkingis that the collection maintains the collection; the iterator provides access tothe elements of the collection. Separating responsibilities between classes isuseful when a class has to change — if there’s too much going on in a singleclass, it’s going to be too hard to rewrite. When change has to happen, asingle class should have only one reason to change.

Accessing your objects with an iteratorYou start to work on the CEO’s problem of tracking vice presidents. In thiscase, you decide to store the vice presidents in a collection, with a set of methods that provide access to the VPs. In the early days of iterators, the classic methods that iterators were supposed to implement were the following:

� was

� first

� next

� isDone

� currentItem

In Java today, however, iterators follow the lead of thejava.util.Iterator interface, which defines these three methods:

� next

� hasNext

� remove

179Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 179

Page 201: Design Patterns For Dummies

The next method returns the next element in the collection, hasNextreturns true if there are additional elements in the collection and false oth-erwise, and remove allows you to remove an element from the collection.

That’s how iterators work — they provide a simple, consistent interface forworking with various collections. Suppose that client code is faced with acomplex, terrifying collection (as represented in Figure 8-1) and doesn’t knowhow to work with it.

The client code can get an iterator to smooth out the interface with the col-lection, and the client code can use the iterator’s standard methods to inter-act with the collection, as shown in Figure 8-2:

The first order of business to deal with the vice president problem is to storethe vice presidents in some way. You decide to start by creating a class thatstores each VP’s information in a class named VP.

You must create the following four important components for this class:

� The constructor to which you pass the name of the VP.

� The name of the division in which the VP works.

� A getName method to return the name of the VP.

� A print method that prints the VP’s info, including both the VP’s nameand division.

Clientcode

Complexterrifyingcollection

IteratorhasNextnextremove

Figure 8-2:Using an

iterator tohandle a

collection.

Clientcode

Complexterrifyingcollection

???

Figure 8-1:Client code

facing acomplex

andterrifying

collection.

180 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 180

Page 202: Design Patterns For Dummies

public class VP {private String name;private String division;

public VP(String n, String d){name = n;division = d;

}

public String getName(){return name;

}

public void print(){System.out.println(“Name: “ + name + “ Division: “ + division);

}

}

That encapsulates individual vice presidents. Now you’ve got to store all thevice presidents in a collection.

Gathering the vice presidents into a collectionIn this example, I base the collection of vice presidents on a simple Javaarray. The reason for that is that any more substantial Java collection, suchas a vector, array list, hash map, or so on, already has an iterator methodbuilt in that returns you a handy iterator, so creating an iterator from scratchto work with the collection seems a little silly.

You decide to store the vice presidents in a division, such as Sales, in aclass named Division.

public class Division {

.

.

.}

181Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 181

Page 203: Design Patterns For Dummies

The Division constructor stores the name of the division, such as Sales,and the getNames method returns that name.

public class Division {private String name;

public Division(String n){name = n;

}

public String getName(){return name;

}...

}

The vice presidents are stored in an array of vP objects named vPs, and youcan add a new vice president to that array with the add method, as shown inthe following code:

public class Division {private VP[] VPs = new VP[100];private int number = 0;private String name;

public Division(String n){name = n;

}

public String getName(){return name;

}

public void add(String n){VP vp = new VP(n, name);VPs[number++] = vp;

}...

}

182 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 182

Page 204: Design Patterns For Dummies

In other words, the Division object is the collection, and the VP objects are the elements in the collection. To add an iterator, the collection shouldhave a method — the name is up to you, perhaps something like iterator(possible names include createIterator and getIterator). This methodpasses the array of vice presidents to the constructor of the iterator class,DivisionIterator, and returns a newly-created DivisionIteratorobject.

public class Division {private VP[] VPs = new VP[100];private int number = 0;private String name;

public Division(String n){name = n;

}

public String getName(){return name;

}

public void add(String n){VP vp = new VP(n, name);VPs[number++] = vp;

}

public DivisionIterator iterator(){return new DivisionIterator(VPs);

}

}

The next step is to create the iterator itself, the DivisionIterator class,that lets you iterate over the vice presidents stored in the collection.

Creating the iteratorThe iterator class, DivisionIterator, implements the three java.util.Iterator methods: next, hasNext, and remove. You start this way by implementing the Iterator interface:

import java.util.Iterator;

public class DivisionIterator implements Iterator{

183Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 183

Page 205: Design Patterns For Dummies

.

.

.}

The constructor accepts the array of VP objects and stores it:

import java.util.Iterator;

public class DivisionIterator implements Iterator{private VP[] VPs;

public DivisionIterator(VP[] v){VPs = v;

}...

}

Now you’ve got to implement the Iterator interface methods to make thisclass into an iterator. The next method returns the next element in the array,and that’s easy enough to do if you keep track of your present location in thearray.

import java.util.Iterator;

public class DivisionIterator implements Iterator{private VP[] VPs;private int location = 0;

public DivisionIterator(VP[] v){VPs = v;

}

public VP next(){return VPs[location++];

}...

}

184 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 184

Page 206: Design Patterns For Dummies

The hasNext method should return true if there is a next element in thearray that hasn’t been read so far, and false otherwise. In this case, youhave to check not only if you’re at the end of the array, but also becauseyou’re dealing with a fixed-length array, you have to check if the next ele-ment is null — if it is, that array element is empty. Here’s what the hasNextmethod looks like:

import java.util.Iterator;

public class DivisionIterator implements Iterator{private VP[] VPs;private int location = 0;

public DivisionIterator(VP[] v){VPs = v;

}

public VP next(){return VPs[location++];

}

public boolean hasNext(){if(location < VPs.length && VPs[location] != null){return true;

} else {return false;

}}...

}

In this case, you’re interested in treating the vice presidents array as read-only, so you might add an empty implementation for the remove method.

import java.util.Iterator;

public class DivisionIterator implements Iterator{private VP[] VPs;private int location = 0;

public DivisionIterator(VP[] v){

185Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 185

Page 207: Design Patterns For Dummies

VPs = v;}

public VP next(){return VPs[location++];

}

public boolean hasNext(){if(location < VPs.length && VPs[location] != null){return true;

} else {return false;

}}

public void remove(){}

}

Excellent. You’ve got vice president objects, a division that represents a col-lection of vice presidents, and an iterator. All that’s left is to put this all towork and start iterating over vice presidents.

Iterating over vice presidentsTo test this out, all you’ve got to do is to create a division, stock it with somevice presidents, and then iterate over those vice presidents. That all happensin the test harness, TestDivision.java.

public class TestDivision{public static void main(String args[]){TestDivision d = new TestDivision();

}

public TestDivision(){...

}

186 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 186

Page 208: Design Patterns For Dummies

The code starts by creating the corporate Sales division and adding somevice presidents:

public class TestDivision{Division division;

public static void main(String args[]){TestDivision d = new TestDivision();

}

public TestDivision(){division = new Division(“Sales”);

division.add(“Ted”);division.add(“Bob”);division.add(“Carol”);division.add(“Alice”);...

}}

Then it creates a Division class iterator by calling the iterator methodand uses the hasNext and next methods to loop over the collection of vicepresidents, displaying each one.

public class TestDivision{Division division;DivisionIterator iterator;

public static void main(String args[]){TestDivision d = new TestDivision();

}

public TestDivision(){division = new Division(“Sales”);

division.add(“Ted”);division.add(“Bob”);division.add(“Carol”);division.add(“Alice”);

187Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 187

Page 209: Design Patterns For Dummies

iterator = division.iterator();

while (iterator.hasNext()){VP vp = iterator.next();vp.print();

}}

}

And sure enough, it prints out the full list of vice presidents.

Name: Ted Division: SalesName: Bob Division: SalesName: Carol Division: SalesName: Alice Division: Sales

Java itself, of course, comes stocked with plenty of iterators, especially in itsnew collection classes. You can see an example using one of the built-in itera-tors in Java in Chapter 7, where you iterate over an ArrayList when con-structing a robot whose actions can be configured and stored at runtime. Thecode looks like this:

import java.util.*;

public class CookieRobotBuildable implements RobotBuildable{ArrayList<Integer> actions;

public CookieRobotBuildable(){}

public final void go(){Iterator itr = actions.iterator();

while(itr.hasNext()) {switch ((Integer)itr.next()){case 1: start();break;

case 2: getParts();break;

case 3: assemble();break;

case 4: test();

188 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 188

Page 210: Design Patterns For Dummies

break;case 5: stop();break;

}}

}

public void start(){System.out.println(“Starting....”);

}

public void getParts(){System.out.println(“Getting flour and sugar....”);

}

public void assemble(){System.out.println(“Baking a cookie....”);

}

public void test(){System.out.println(“Crunching a cookie....”);

}

public void stop(){System.out.println(“Stopping....”);

}

public void loadActions(ArrayList a){actions = a;

}}

In Java, iterators are everywhere. The Iterator interface is the basis of theCollection, ListIterator, and Enumeration interfaces, and they’reimplemented all over the place. Here’s a partial list of classes that implementthe Collection interface. (Take a deep breath before reading this aloud.)

189Chapter 8: Handling Collections with the Iterator and Composite Patterns

� AbstractCollection

� AbstractList

� AbstractQueue

� AbstractSequentialList

� AbstractSet

� ArrayBlockingQueue

� ArrayList

� AttributeList

13_798541 ch08.qxp 3/27/06 2:23 PM Page 189

Page 211: Design Patterns For Dummies

More fun with for/inJava 5 makes working with iterators all the more easy by making them disap-pear entirely. You can do that with the for/in statement. For example, sayyou have an ArrayList named VPs that stores vice president names asstrings. You could use this code to print out each one:

for (String vp: VPs){System.out.println(vp);

}

For each iteration of the loop over the VPs collection, the String variablevp holds the current vice president’s name, and you can print it out asshown. Here’s how to use this loop in context in an example application,TestForIn.java, which creates an ArrayList of strings to store thenames of the VPs and then loops over that ArrayList:

import java.util.*;

public class TestForIn{ArrayList<String> VPs;

public static void main(String args[]){TestForIn t = new TestForIn();

190 Part II: Becoming an OOP Master

� BeanContextServicesSupport

� BeanContextSupport

� ConcurrentLinkedQueue

� CopyOnWriteArrayList

� CopyOnWriteArraySet

� DelayQueue

� EnumSet

� HashSet

� JobStateReasons

� LinkedBlockingQueue

� LinkedHashSet

� LinkedList

� PriorityBlockingQueue

� PriorityQueue

� RoleList

� RoleUnresolvedList

� Stack

� SynchronousQueue

� TreeSet

� Vector

13_798541 ch08.qxp 3/27/06 2:23 PM Page 190

Page 212: Design Patterns For Dummies

}

public TestForIn(){VPs = new ArrayList<String>();

VPs.add(“Ted”);VPs.add(“Bob”);VPs.add(“Carol”);VPs.add(“Alice”);

for (String vp: VPs){System.out.println(vp);

}}

}

Putting Together CompositesThe CEO of GiantDataPool Inc. hurtles into your cubicle jubilantly and cries,“I like firing vice presidents!”

“Good,” you say.

“I want to do more. Now I need a printout of all the vice presidents in thecompany — not just the Sales division, but all divisions.”

“All divisions?” you ask.

“Yep. And there are some vice presidents just floating around independently,not even connected to a division.”

“Hmm,” you say, “this is going to take a new design pattern.”

“Hey wait,” says the CEO. “Remember that this is supposed to be a cost-cutting measure.”

“I’ll use the Composite pattern,” you say.

“Is it expensive?”

“No,” you say, “but I am.”

191Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 191

Page 213: Design Patterns For Dummies

You understand the problem — now you have to handle the whole corpora-tion, not just a single division. The corporation has divisions with VPs — anddivisions can contain other divisions — as well as free-floating VPs. Yipes.Figure 8-3 shows what the corporation looks like:

So now you’ve got a complex organization to work with, not just the simpleSales division. And the CEO wants to be able to print out the whole structure,so not only should each VP object have a print method, but each divisionshould have a print method too. Okay, it’s time for the Composite pattern.

You want to have a print method that can be called to print out a vice presi-dent, a division, or the whole corporation. The Composite pattern is all aboutcreating tree-like structures where the leaves in a structure can be treated inthe same way as the branches (which are substructures that can contain mul-tiple leaves, as well as other branches). The idea here is that, to make lifeeasier, you should be able to treat the leaves and compositions of leaves in atree structure the same.

Corporation

Sales Division VP: CaryR&D Division

VP: Ted

VP: Bob

VP: Wally

VP: Andre

VP: Carol

VP: Steve

VP: Mike

VP: Nancy

VP: Alice

Western Sales Division

Figure 8-3:All the parts

of thecorporation.

192 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 192

Page 214: Design Patterns For Dummies

The GoF says you use the Composite design pattern to “Compose objectsinto tree structures to represent part-whole hierarchies. Composite letsclients treat individual objects and compositions of objects uniformly.”

That’s what you need here — a design pattern that lets you treat the leavesand branches of a tree structure equally because you want to be able to printout all the vice presidents individually, in a division, or in the whole corpora-tion, just by calling the print method.

The Composite design pattern fits in with the Iterator pattern because whenyou ask each division to print itself, it can simply iterate over each vice presi-dent. That’s typical of the Composite pattern — when you ask a branch toperform some action, it iterates over all its contained leaves and branches.

The insight behind the Composite pattern is really about treating the leavesand branches in a tree-like structure the same way, not about tree structuresper se. That makes it a heck of a lot easier to work with complex structureslike trees because you don’t have to use a different set of methods with a partof the structure compared to the whole.

To implement the Composite pattern, the GoF suggests that you use anabstract class as the basis for both the leaves and branches in the tree. Doingso gives the leaves and branches a common set of methods, which is whatthe Composite pattern is all about. The GoF suggests an abstract class, butyou can also use an interface for this job in Java.

It all starts with an abstract classI’ll stick with the GoF suggestion and create an abstract class that both vicepresidents and divisions will implement, the Corporate class. Here’s what itlooks like — note that it has an add method, an iterator method to returnan iterator over any contained vice presidents, and a print method:

import java.util.*;

public abstract class Corporate{public String getName(){return “”;

}

public void add(Corporate c){}

193Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 193

Page 215: Design Patterns For Dummies

public Iterator iterator(){return null;

}

public void print(){}

}

This is the class that both the vice president leaves and the divisionbranches in the corporation will extend.

Creating the vice president leavesThe VP class you created earlier in this chapter has to be modified a little sothat you can unify the way you deal with both vice presidents and divisionsin the corporate tree, as the Composite pattern says you should. In particu-lar, you have to base the VP class on the common Corporate abstract classyou created in the previous section.

import java.util.*;

public class VP extends Corporate{

.

.

.}

The actual guts of the VP class are much as before — you just store the VP’sname and division, and the print method prints out that information. But tolet client code treat VPs the same way as it treats divisions, you can add anew iterator method to return an iterator. Because VPs don’t contain otherVPs, the returned iterator returns the current VP object only when you callthe next method, and the hasNext method always returns false. Here’show you add the iterator method to the VP class, which returns a new iter-ator of the VPIterator class:

import java.util.*;

public class VP extends Corporate{private String name;private String division;

public VP(String n, String d){

194 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 194

Page 216: Design Patterns For Dummies

name = n;division = d;

}

public String getName(){return name;

}

public void print(){System.out.println(“Name: “ + name + “ Division: “ + division);

}

public Iterator iterator(){return new VPIterator(this);

}

}

What’s the VPIterator class look like? That’s easy enough — in this class,you just implement the Java Iterator interface, pass the VP object the iter-ator it should work with to its constructor, have the next method return thatobject, and the hasNext method return false, as shown in the followingcode:

import java.util.Iterator;

public class VPIterator implements Iterator{private VP vp;

public VPIterator(VP v){vp = v;

}

public VP next(){return vp;

}

public boolean hasNext(){return false;

}

public void remove(){}

}

195Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 195

Page 217: Design Patterns For Dummies

Now client code can treat vice president leaves the same as divisionbranches — even to the extent of getting an iterator for a VP leaf to “iterate”over it. In reality, the vice president leaf iterator only returns the vice presi-dent, but now that you have an iterator for each leaf, you don’t have tomodify code that works with divisions to work with leaves as well.

Creating the division branchesEach branch in the corporate tree is a division of the company which cancontain multiple vice presidents — and subdivisions as well. To handle divi-sions, you decide to modify your Division class from earlier in this chapterto make it extend the Corporate class, just as the VP class did, as shown inthe following code:

import java.util.*;

public class Division extends Corporate{

.

.

.}

The rest of the Division class is the same as earlier in this chapter, exceptthat you have to convert all its code to deal with Corporate objects throughcomposition instead of the VP objects you used earlier. Before, the Divisionclass stored only VPs because you were dealing with only one division of thecompany. Now that you’re dealing with the whole company, a division cancontain subdivisions as well as VPs. Since both divisions and VPs extend the Corporate class, you can simply switch to storing and working withCorporate objects in the Division class — note that the print methoditerates over all objects in the division, whether they’re VPs or divisions.

import java.util.*;

public class Division extends Corporate{private Corporate[] corporate = new Corporate[100];private int number = 0;private String name;

public Division(String n){name = n;

}

196 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 196

Page 218: Design Patterns For Dummies

public String getName(){return name;

}

public void add(Corporate c){corporate[number++] = c;

}

public Iterator iterator(){return new DivisionIterator(corporate);

}

public void print(){Iterator iterator = iterator();

while (iterator.hasNext()){Corporate c = (Corporate) iterator.next();c.print();

}}

}

By converting from handling the VP class inside a division to handling theCorporate class, you can now store VPs or other divisions — and so you’reimplementing the Composite design pattern, which says you should be ableto treat leaves or branches as equally as possible.

The division iterator, as implemented by the DivisionIterator class, is also as it was when you were dealing with a single division that iteratedover the contained vice presidents — except that you also have to switchDivisionIterator to iterate over Corporate objects (for example, VPsand other divisions). That looks like this:

import java.util.Iterator;

public class DivisionIterator implements Iterator{private Corporate[] corporate;private int location = 0;

public DivisionIterator(Corporate[] c){corporate = c;

}

197Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 197

Page 219: Design Patterns For Dummies

public Corporate next(){return corporate[location++];

}

public boolean hasNext(){if(location < corporate.length && corporate[location] != null){return true;

} else {return false;

}}

public void remove(){}

}

You sit back with a satisfied smile, thanks to the Composite pattern. To makethe transition from the single-division example in the first half of this chapterto the more involved, tree-like structure of the full corporation example, allyou have to do is make sure that all objects in the tree are based on the sameclass and implement the same methods, allowing them to be treated in thesame way.

It’s easy to create an overly complex tree structure where you have to treatleaves and branches in entirely separate ways. But it usually makes muchmore sense to make handling leaves and branches in the same way, and it’snot much harder to do that — just make sure you base all tree objects on thesame abstract class or interface and implement the same set of methods.

Building your corporationYou’ve got the vice presidents; you’ve got the divisions. Now it’s time to buildthe corporation that contains them. To keep this relatively simple, you mightjust use an ArrayList to hold the divisions and vice presidents in the cor-poration. All the objects in the corporation are Corporate objects, so theArrayList will hold Corporate objects.

import java.util.*;

public class Corporation extends Corporate{private ArrayList<Corporate> corporate = new ArrayList<Corporate>();

public Corporation()

198 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 198

Page 220: Design Patterns For Dummies

{}...

}

When you want to add a new Corporate object to the tree, just use the corporation’s add method, which just adds the new object to the internalArrayList.

import java.util.*;

public class Corporation extends Corporate{private ArrayList<Corporate> corporate = new ArrayList<Corporate>();

public Corporation(){}

public void add(Corporate c){corporate.add(c);

}...

}

Want to print out all the objects in the corporation? Just call the corpora-tion’s print method, which uses the ArrayList’s own iterator to print thedivisions and vice presidents stored in the corporation — note that when youcall a division’s print method, it iterates over all its internal objects andcalls each of their print methods. So calling this single print method at theCorporation level prints out everyone in the corporation.

import java.util.*;

public class Corporation extends Corporate{private ArrayList<Corporate> corporate = new ArrayList<Corporate>();

public Corporation(){}

public void add(Corporate c){corporate.add(c);

}

199Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 199

Page 221: Design Patterns For Dummies

public void print(){Iterator iterator = corporate.iterator();

while (iterator.hasNext()){Corporate c = (Corporate) iterator.next();c.print();

}}

}

Time to test it out using the test harness, which is TestCorporation.java.You create a new Corporation object first.

import java.util.*;

public class TestCorporation{Corporation corporation;

public static void main(String args[]){TestCorporation t = new TestCorporation();

}

public TestCorporation(){corporation = new Corporation();...

}

Then you create the R&D division and stock it with vice presidents.

import java.util.*;

public class TestCorporation{

.

.

.public TestCorporation(){corporation = new Corporation();

Division rnd = new Division(“R&D”);rnd.add(new VP(“Steve”, “R&D”));rnd.add(new VP(“Mike”, “R&D”));

200 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 200

Page 222: Design Patterns For Dummies

rnd.add(new VP(“Nancy”, “R&D”));...

}}

Next comes the Sales division. You use the add method to add not only vicepresidents to this division but also a subdivision, Western Sales, which hasits own vice presidents.

import java.util.*;

public class TestCorporation{

.

.

.public TestCorporation(){corporation = new Corporation();

Division rnd = new Division(“R&D”);rnd.add(new VP(“Steve”, “R&D”));rnd.add(new VP(“Mike”, “R&D”));rnd.add(new VP(“Nancy”, “R&D”));

Division sales = new Division(“Sales”);

sales.add(new VP(“Ted”, “Sales”));sales.add(new VP(“Bob”, “Sales”));sales.add(new VP(“Carol”, “Sales”));sales.add(new VP(“Alice”, “Sales”));

Division western = new Division(“Western Sales”);western.add(new VP(“Wally”, “Western Sales”));western.add(new VP(“Andre”, “Western Sales”));

sales.add(western);...

} }

And you can add vice presidents to the corporation directly, as well as divi-sions, because you can treat leaves and branches equally. After creating avice president, you can add the vice president — and the divisions you’ve

201Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 201

Page 223: Design Patterns For Dummies

already created — to the corporation and print the whole thing out with asingle call to the corporation’s print method, which calls the print methodof each contained object.

import java.util.*;

public class TestCorporation{

.

.

.public TestCorporation(){corporation = new Corporation();

Division rnd = new Division(“R&D”);rnd.add(new VP(“Steve”, “R&D”));rnd.add(new VP(“Mike”, “R&D”));rnd.add(new VP(“Nancy”, “R&D”));

Division sales = new Division(“Sales”);

sales.add(new VP(“Ted”, “Sales”));sales.add(new VP(“Bob”, “Sales”));sales.add(new VP(“Carol”, “Sales”));sales.add(new VP(“Alice”, “Sales”));

Division western = new Division(“Western Sales”);western.add(new VP(“Wally”, “Western Sales”));western.add(new VP(“Andre”, “Western Sales”));

sales.add(western);

VP vp = new VP(“Cary”, “At Large”);

corporation.add(rnd);corporation.add(sales);corporation.add(vp);

corporation.print();}

}

Running the test harness prints out, as it should, the entire corporation’s vicepresidents.

Name: Steve Division: R&DName: Mike Division: R&DName: Nancy Division: R&D

202 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 202

Page 224: Design Patterns For Dummies

Name: Ted Division: SalesName: Bob Division: SalesName: Carol Division: SalesName: Alice Division: SalesName: Wally Division: Western SalesName: Andre Division: Western SalesName: Cary Division: At Large

You hand the list triumphantly to the CEO. “Time to start trimming the tree,”you say.

“Eh?” asks the CEO.

“Get rid of the deadwood,” you say. The CEO hurries off happily.

Tracking the Composite Pattern in the Wild

Are there any examples of the Composite pattern to be found already builtinto Java, where you can construct trees and treat leaves and branches inmuch the same way? Sure, there are a few, such as the Node interface you usewhen you parse XML documents.

In Java, XML nodes can be of several different types as follows:

� Document nodes contain entire XML documents of other nodes.

� Text nodes contain the text in an XML element.

� XML processing instructions.

� XML elements can contain child elements, which themselves can containchild elements, and so on.

But all these node types have one thing in common — they all implement theNode interface. XML documents are parsed into trees of nodes, and becauseall the nodes implement the Node interface, you can handle them in the sameway. There’s an example in the code for this book, Parser.java, as well as asample XML file you can run it on, sample.xml. The Parser applicationuses a Java DocumentBuilder object to parse XML files you pass to it onthe command line (run it like this: java Parser sample.xml), which cre-ates a tree of nodes. The Parser application walks that tree and prints outthe XML document properly indented.

203Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 203

Page 225: Design Patterns For Dummies

Because you can handle all the nodes in the tree in essentially the same way,Parser.java only needs one recursive method (that is, this method callsitself), display, to walk through the entire tree. The display method takestwo arguments — the current node in the tree, and the current indentationstring. Because each object in the tree implements the Node interface, itdoesn’t matter what kind of node you call the display method with — anelement node, a processing instruction node, whatever. If the current nodehas children, the display method iterates over them recursively as well. Towalk the entire tree, all you have to do is pass this method the documentnode you get when you parse the XML document with DocumentBuilder,and it works from node to node from then on. Here’s what the displaymethod looks like:

public void display(Node node, String indentation) {

if (node == null) {return;

}

int type = node.getNodeType();

switch (type) {case Node.DOCUMENT_NODE: {

text[numberOfLines] = indentation;text[numberOfLines] += “<?xml version=\”1.0\” encoding=\”” +“UTF-8” + “\”?>”;

numberOfLines++;display(((Document)node).getDocumentElement(), “”);break;

}

case Node.ELEMENT_NODE: {

text[numberOfLines] = indentation;text[numberOfLines] += “<”;text[numberOfLines] += node.getNodeName();

int length = (node.getAttributes() != null) ? node.getAttributes().getLength() : 0;

Attr attributes[] = new Attr[length];for (int loopIndex = 0; loopIndex < length; loopIndex++) {

attributes[loopIndex] = (Attr)node.getAttributes().item(loopIndex);

}

for (int loopIndex = 0; loopIndex < attributes.length; loopIndex++) {Attr attribute = attributes[loopIndex];text[numberOfLines] += “ “;

204 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 204

Page 226: Design Patterns For Dummies

text[numberOfLines] += attribute.getNodeName();text[numberOfLines] += “=\””;text[numberOfLines] += attribute.getNodeValue();text[numberOfLines] += “\””;

}text[numberOfLines]+=”>”;

numberOfLines++;

NodeList childNodes = node.getChildNodes();if (childNodes != null) {

length = childNodes.getLength();indentation += “ “;for (int loopIndex = 0; loopIndex < length; loopIndex++ ) {

display(childNodes.item(loopIndex), indentation);}

}break;

}

case Node.CDATA_SECTION_NODE: {text[numberOfLines] = indentation;text[numberOfLines] += “<![CDATA[“;text[numberOfLines] += node.getNodeValue();text[numberOfLines] += “]]>”;numberOfLines++;break;

}

case Node.TEXT_NODE: {text[numberOfLines] = indentation;String newText = node.getNodeValue().trim();if(newText.indexOf(“\n”) < 0 && newText.length() > 0) {

text[numberOfLines] += newText;numberOfLines++;

}break;

}

case Node.PROCESSING_INSTRUCTION_NODE: {text[numberOfLines] = indentation;text[numberOfLines] += “<?”;text[numberOfLines] += node.getNodeName();String value = node.getNodeValue();if (value != null && value.length() > 0) {

text[numberOfLines] += value;}text[numberOfLines] += “?>”;numberOfLines++;break;

205Chapter 8: Handling Collections with the Iterator and Composite Patterns

13_798541 ch08.qxp 3/27/06 2:23 PM Page 205

Page 227: Design Patterns For Dummies

} }

if (type == Node.ELEMENT_NODE) {text[numberOfLines] = indentation.substring(0, indentation.length()

- 4);text[numberOfLines] += “</”;text[numberOfLines] += node.getNodeName();text[numberOfLines] += “>”;numberOfLines++;indentation += “ “;

}}

That’s how it works — when you parse an XML document in Java, you get atree of nodes where each node, whether it’s the tree or a branch, implementsthe Node interface. And for that reason, you can handle trees and branches inthe same way in your code. Cool. That’s the Composite pattern at work.

206 Part II: Becoming an OOP Master

13_798541 ch08.qxp 3/27/06 2:23 PM Page 206

Page 228: Design Patterns For Dummies

Chapter 9

Getting Control of Your Objectswith the State and Proxy Patterns

In This Chapter� Using the State pattern

� Letting states determine outcomes

� Understanding the Proxy pattern

� Using proxies to stand in for your objects

� Connecting with proxies across the Internet

The CEO of Apartments-N-Stuff Inc. has reserved your services as a consul-tant and says, “We run huge, apartment-rental complexes all around the

country. Our big problem is property managers — they cost too much. Sowe’re going to convert all our apartment complexes to use rental automats —robots that will accept rental applications and dispense keys — instead. Wewant new tenants to be able to submit their rental applications to an automatand, if they’re approved, get their keys from that automat.”

“Sounds nuts,” you say.

“Here’s the idea,” says the CEO. “Normally, the automat just sits around wait-ing for a prospective tenant to show up. When a tenant does submit an appli-cation, the automat checks it. If the application is approved, the automatshould dispense keys to the tenant; otherwise, the automat should tell thetenant he was rejected and go back to waiting. Oh, and if the automat rentsout an apartment, the automat should check if there are still any apartmentsleft in the complex and not rent any more if there aren’t.”

The CEO watches as you scribble on a pad of paper and finally asks, “Whatare you doing?”

“I’m drawing a state diagram,” you say.

“Can I see it?” asks the CEO.

14_798541 ch09.qxp 3/27/06 2:23 PM Page 207

Page 229: Design Patterns For Dummies

“No,” you say. “You would need a great deal more intelligence to understandthis.”

“Oh,” says the CEO.

This chapter is about two patterns: the State pattern, where an object keepstrack of its internal state, and can change its behavior based on that state,and the Proxy pattern, where one object can act as a substitute for another.You’re going to see how both work in detail in this chapter.

Getting the State of Your Union with the State Pattern

You understand what the CEO told you. The rental automat has the followingfour states (as in, “conditions of being,” not political states or areas on amap):

� Waiting for a new tenant

� Receiving an application

� Renting an apartment

� Fully rented

Figure 9-1 shows your state diagram, where each box represents a differentstate of being, and you’ve connected the states to make a representation ofthe automat:

Waiting Fully rented

Receivingan application

Check the application

AcceptedRent an apartment

Get an application Rejected

More apartmentsavailable

Dispense keys

Full up

Figure 9-1:The rentalautomat’s

states.

208 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 208

Page 230: Design Patterns For Dummies

This, you think to yourself, is a job for the State design pattern.

Sometimes, when you’re engaged on a larger project, the coding starts to feelvery murky. There are just so many possible conditions that you have to dealwith that it’s tough to know where the boundaries are or how to divide yourcode.

When you face a large-scale application and the coding gets out of hand, itoften helps to start thinking in terms of various states. This device helps yousegment your code into independent units (states) — ideally, each stateshould be logically independent of the others, so thinking in terms of statescan automatically divide your code into discrete sections.

The Gang of Four (GoF) book (Design Patterns: Elements of Reusable Object-Oriented Software, 1995, Pearson Education, Inc. Publishing as Pearson AddisonWesley) says that the State design pattern will “Allow an object to alter itsbehavior when its internal state changes. The object will appear to change itsclass.”

In other words, your code should keep track of an internal state, such as theWaiting for a new tenant state. Any part of the code can check whatthe current state is and react accordingly. For example, if the rental automatis in the Fully rented state and a prospective new tenant gives it a rentalapplication, it should reject that application.

When you use the State pattern, any part of your code can check what stateis current. That can clarify and centralize the workings of very large pieces ofcode because you have control over what far-flung code segments do, just bychanging the current state.

In general, the State pattern is useful when you’ve got a lot of code that’s get-ting more and more murky and complex. If you can compartmentalize theworking of what you’re trying to do into a set of independent states, you cancompartmentalize your code.

Using methods to hold stateHere’s a first, simple attempt at coding the rental automat, using states. Youdecide that you might be able to write the application centered on a set ofmethods which do different things depending on the current state. Here’swhat it looks like in RentalMethods.java — you start by creating a con-stant for each of the four possible states of the rental automat, as well as aninternal variable named state that holds the current state (which is set toWAITING, when the application starts):

import java.util.*;import java.lang.Math;

public class RentalMethods

209Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 209

Page 231: Design Patterns For Dummies

{final static int FULLY_RENTED = 0;final static int WAITING = 1;final static int GOT_APPLICATION = 2;final static int APARTMENT_RENTED = 3;int state = WAITING;

.

.

.

Now any code in the application can check the current state and respondaccordingly. For example, the following code shows how the getApplicationmethod works, which is called when the automat gets a prospective tenantapplication — note how what happens depends on the internal state:

import java.util.*;import java.lang.Math;

public class RentalMethods{final static int FULLY_RENTED = 0;final static int WAITING = 1;final static int GOT_APPLICATION = 2;final static int APARTMENT_RENTED = 3;Random random; int numberApartments;int state = WAITING;

public RentalMethods(int n){numberApartments = n;random = new Random(System.currentTimeMillis());

}

public void getApplication(){switch (state){case FULLY_RENTED:System.out.println(“Sorry, we’re fully rented.”);break;

case WAITING:state = GOT_APPLICATION;System.out.println(“Thanks for the application.”);break;

case GOT_APPLICATION:System.out.println(“We already got your application.”);break;

case APARTMENT_RENTED:System.out.println(“Hang on, we’re renting you an apartment.”);

210 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 210

Page 232: Design Patterns For Dummies

break;}

}...

So if the automat gets an application and it’s in the FULLY_RENTED state, theautomat prints out Sorry, we’re fully rented. If the automat gets anapplication and it’s in the WAITING state, on the other hand, it displaysThanks for the application. and changes the internal state toGOT_APPLICATION.

Similarly, if you call the automat’s checkApplication method, the response depends on the current state: For example, if the automat is askedto check an application and it’s in the WAITING state, it tells the prospectivetenant she has to submit an application first. If the automat is in the GOT_APPLICATION state when you call its checkApplication method, it shouldcheck that application and either accept or reject the tenant. That process is simulated in this example with a random number — if the application isaccepted, the code puts the automat in the APARTMENT_RENTED state andcalls a method named rentApartment; if the application is rejected, thecode puts the automat into the WAITING state.

public void checkApplication(){int yesno = random.nextInt() % 10;

switch (state){case FULLY_RENTED:System.out.println(“Sorry, we’re fully rented.”);break;

case WAITING:System.out.println(“You have to submit an application.”);break;

case GOT_APPLICATION:if (yesno > 4 && numberApartments > 0) {System.out.println(“Congratulations, you were approved.”);state = APARTMENT_RENTED;rentApartment();

} else {System.out.println(“Sorry, you were not approved.”);state = WAITING;

}break;

case APARTMENT_RENTED:System.out.println(“Hang on, we’re renting you an apartment.”);break;

}}

211Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 211

Page 233: Design Patterns For Dummies

The rentApartment method also checks the internal state — if that state isAPARTMENT_RENTED, it decrements the number of available apartments by 1and calls the dispenseKeys method.

public void rentApartment(){switch (state){case FULLY_RENTED:System.out.println(“Sorry, we’re fully rented.”);break;

case WAITING:System.out.println(“You have to submit an application.”);break;

case GOT_APPLICATION:System.out.println(“You must have your application checked.”);break;

case APARTMENT_RENTED:System.out.println(“Renting you an apartment....”);numberApartments--;dispenseKeys();break;

}}

Finally, the dispenseKeys method also checks the current state and, if thatstate is APARTMENT_RENTED, gives the keys to the new tenant and then putsthe automat into the WATING state for the next prospective tenant.

public void dispenseKeys(){switch (state){case FULLY_RENTED:System.out.println(“Sorry, we’re fully rented.”);break;

case WAITING:System.out.println(“You have to submit an application.”);break;

case GOT_APPLICATION:System.out.println(“You must have your application checked.”);break;

case APARTMENT_RENTED:System.out.println(“Here are your keys!”);state = WAITING;break;

}}

212 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 212

Page 234: Design Patterns For Dummies

That’s the idea — you keep track of the internal state and every time externalcode calls one of your public methods, you can check that current state tosee what to do. Here’s a test harness for the RentalMethods class you justdeveloped, TestRentalMethods.java. This test harness creates a newRentalMethods object, passing the constructor a value of 9 to indicate thatthere are nine apartments for rent. Then the code calls the getApplicationand checkApplication methods to mimic a new tenant.

public class TestRentalMethods{RentalMethods rentalMethods;

public static void main(String args[]){TestRentalMethods t = new TestRentalMethods();

}

public TestRentalMethods(){rentalMethods = new RentalMethods(9);

rentalMethods.getApplication();rentalMethods.checkApplication();

}}

And here’s the result:

Thanks for the application.Congratulations, you were approved.Renting you an apartment....Here are your keys!

Not bad — you were able to implement the rental automat.

But there’s a problem with this method-based approach. As you add morestates, each method becomes longer and longer, and each method has to be rewritten for all the new states. What should you do? When in doubt,encapsulate.

Using objects to encapsulate stateInstead of giving each state its own constant, it’s a better idea to give eachstate its own class. That way, you can call methods like dispenseKeys orcheckApplication on a state object anywhere in your code. All you have

213Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 213

Page 235: Design Patterns For Dummies

to do is load the correct state object into a generic variable and call variousmethods of that variable. For example, if the current state object corre-sponds to a waiting state, you’re going to get a very different response whenyou call its gotApplication method than if the current state object corre-sponds to a fully rented state, where no more apartments are available.

You decide to try holding the current state in an object to make your codecleaner. How would you design the automat to use such state objects? Theautomat stores the current state in a state object, which can hold any of thefour possible state objects: WaitingState, GotApplicationState,ApartmentRentedState, and FullyRentedState (see Figure 9-2).

The automat code can then simply work with the current state object, call-ing that object’s methods, such as checkApplication — depending onwhat the current state is, you get an appropriate response from the stateobject.

You start putting the automat together, beginning with an interface that lists the methods the automat should support. The automat should be ableto interact with the user with the same methods you’ve already seen —checkApplication, rentApartment, and so on, so you add those meth-ods first, as shown in the following:

public interface AutomatInterface {public void gotApplication();public void checkApplication();public void rentApartment();

.

.

.}

Automat

State

WaitingState

GotApplicationState

ApartmentRentedState

FullyRentedState

Figure 9-2:The states

of the rentalautomat.

214 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 214

Page 236: Design Patterns For Dummies

While it’s doing its work, a particular state object might decide that it’s timefor the automat to change state. For example, if the current state is representedby a WaitingState object and you tell it that you got a rental application, thatobject might want to change the current state to a GotApplicationStateobject. To allow state objects to change the state stored in the automat, theautomat should support a setState method. And you can also add methods to create the new state objects, which can be called as needed.

public interface AutomatInterface {public void gotApplication();public void checkApplication();public void rentApartment();public void setState(State s);public State getWaitingState();public State getGotApplicationState();public State getApartmentRentedState();public State getFullyRentedState();

.

.

.}

Finally, the state objects need to know how many apartments are available torent (to check if the automat should go to a FullyRentedState state or notafter an apartment is rented), so you might add a getCount and setCountmethod that gets and sets the current number of apartments for rent.

public interface AutomatInterface {public void gotApplication();public void checkApplication();public void rentApartment();public void setState(State s);public State getWaitingState();public State getGotApplicationState();public State getApartmentRentedState();public State getFullyRentedState();public int getCount();public void setCount(int n);

}

Those are the methods the automat supports; now it’s time to create theautomat itself. You start the Automat class by implementing this new inter-face, AutomatInterface.

public class Automat implements AutomatInterface{

.

.

.}

215Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 215

Page 237: Design Patterns For Dummies

You pass the number of apartments available for rent to the automat con-structor. The constructor also creates four state objects corresponding to the four possible states — WaitingState, GotApplicationState,ApartmentRentedState, and FullyRentedState — so it can switchbetween those states as needed. The automat’s current state is stored in avariable named state, and the constructor sets that to a WaitingStateobject initially.

public class Automat implements AutomatInterface{State waitingState;State gotApplicationState;State apartmentRentedState;State fullyRentedState;State state;int count;

public Automat(int n){count = n;waitingState = new WaitingState(this);gotApplicationState = new GotApplicationState(this);apartmentRentedState = new ApartmentRentedState(this);waitingState = new WaitingState(this);state = waitingState;

}...

}

Now you can add methods like gotApplication to the automat so that it can interact with a prospective tenant. For example, when the automat gets an application, all it has to do is call the current state object’s gotApplication method, and that method returns text which the automat can display. Here’s how you implement the methods like gotApplicationand checkApplication that let the automat interact with a prospectivetenant — note that all you have to do is call methods of the current stateobject, simple as pie:

public class Automat implements AutomatInterface{State waitingState;State gotApplicationState;State apartmentRentedState;State fullyRentedState;State state;int count;

216 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 216

Page 238: Design Patterns For Dummies

public Automat(int n){count = n;waitingState = new WaitingState(this);gotApplicationState = new GotApplicationState(this);apartmentRentedState = new ApartmentRentedState(this);waitingState = new WaitingState(this);state = waitingState;

}

public void gotApplication(){System.out.println(state.gotApplication());

}

public void checkApplication(){System.out.println(state.checkApplication());

}

public void rentApartment(){System.out.println(state.rentApartment());System.out.println(state.dispenseKeys());

}...

}

All that’s left to do now is implement the utility methods that return newstate objects as needed, set the state as needed, and get or set the count of available apartments, as shown here:

public class Automat implements AutomatInterface{State waitingState;State gotApplicationState;State apartmentRentedState;State fullyRentedState;State state;int count;

.

.

.public State getApartmentRentedState(){return apartmentRentedState;

}

217Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 217

Page 239: Design Patterns For Dummies

public State getFullyRentedState(){return fullyRentedState;

}

public int getCount(){return count;

}

public void setCount(int n){count = n;

}

public void setState(State s){state = s;

}

That completes the Automat class. You’ve offloaded most of the work tostate objects, and now it’s time to create those objects.

Creating the state objectsEach state object supports the methods gotApplication, checkApplication, rentApplication, and dispenseKeys, but of course, eachstate object handles those methods in a different way. If you try to calldispenseKeys when the automat is in the fully rented state, for example,you’re not going to get any keys. To make sure each state object imple-ments all the methods it should, you create an interface named State.

public interface State{public String gotApplication();public String checkApplication();public String rentApartment();public String dispenseKeys();

}

The WaitingState class corresponds to the waiting state, and because it’s astate class, it implements the State interface.

public class WaitingState implements State{

.

.

.}

218 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 218

Page 240: Design Patterns For Dummies

The automat object is passed to each state object’s constructor, so thecode in WaitingState starts by storing the automat object.

public class WaitingState implements State{AutomatInterface automat;

public WaitingState(AutomatInterface a){automat = a;

}...

}

If the automat is in the waiting state and gets an application, the automatshould switch to the GotApplicationState state and return an acknowl-edgement that it received that application. Here’s what that looks like in theWaitingState class’s gotApplication method:

public class WaitingState implements State{AutomatInterface automat;

public WaitingState(AutomatInterface a){automat = a;

}

public String gotApplication(){automat.setState(automat.getGotApplicationState());return “Thanks for the application.”;

}...

}

Now you’ve delegated what happens to the state objects and even let themswitch the automat’s state as needed. Here are the other methods of theWaitingState class:

public class WaitingState implements State{AutomatInterface automat;

public WaitingState(AutomatInterface a){automat = a;

}

219Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 219

Page 241: Design Patterns For Dummies

public String gotApplication(){automat.setState(automat.getGotApplicationState());return “Thanks for the application.”;

}

public String checkApplication(){return “You have to submit an application.”;

}

public String rentApartment(){return “You have to submit an application.”;

}

public String dispenseKeys(){return “You have to submit an application.”;

}}

The GotApplicationState class handles the state where the automat gets an application. The big method here is checkApplication, whichaccepts or rejects the application and changes the automat’s state to match(to the ApartmentRentedState if the application is accepted, or to theWaitingState if it’s not).

import java.util.*;import java.lang.Math;

public class GotApplicationState implements State{AutomatInterface automat;Random random;

public GotApplicationState(AutomatInterface a){automat = a;random = new Random(System.currentTimeMillis());

}

public String gotApplication(){return “We already got your application.”;

}

public String checkApplication(){

220 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 220

Page 242: Design Patterns For Dummies

int yesno = random.nextInt() % 10;

if (yesno > 4 && automat.getCount() > 0) {automat.setState(automat.getApartmentRentedState());return “Congratulations, you were approved.”;

} else {automat.setState(automat.getWaitingState());return “Sorry, you were not approved.”;

}}

public String rentApartment(){return “You must have your application checked.”;

}

public String dispenseKeys(){return “You must have your application checked.”;

}}

If the prospective renter’s application is accepted, the automat’s internalstate is set to an ApartmentRentedState object. This state object has two important methods: rentApartment and dispenseKeys. ThedispenseKeys method is the final step of the whole automat process; ifthere are more apartments to rent, the automat goes back to the waitingstate, but if there are no more apartments to rent, it goes to the fully rented state.

public class ApartmentRentedState implements State{AutomatInterface automat;

public ApartmentRentedState(AutomatInterface a){automat = a;

}

public String gotApplication(){return “Hang on, we’re renting you an apartment.”;

}

public String checkApplication(){return “Hang on, we’re renting you an apartment.”;

}

221Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 221

Page 243: Design Patterns For Dummies

public String rentApartment(){automat.setCount(automat.getCount() - 1);return “Renting you an apartment....”;

}

public String dispenseKeys(){if(automat.getCount() <= 0){ automat.setState(automat.getFullyRentedState());

} else {automat.setState(automat.getWaitingState());

}return “Here are your keys!”;

}}

The fully rented state is easy to code — the automat has nothing to rent, sothis state just blocks all actions and returns the message Sorry, we’refully rented.

public class FullyRentedState implements State{AutomatInterface automat;

public FullyRentedState(AutomatInterface a){automat = a;

}

public String gotApplication(){return “Sorry, we’re fully rented.”;

}

public String checkApplication(){return “Sorry, we’re fully rented.”;

}

public String rentApartment(){return “Sorry, we’re fully rented.”;

}

public String dispenseKeys(){return “Sorry, we’re fully rented.”;

}}

That gives you the Automat class and the four state object classes. Now it’stime to give this code a test drive.

222 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 222

Page 244: Design Patterns For Dummies

Putting the rental automat to the testA likely looking prospective candidate walks through the door and plunksdown a rental application, saying, “How about it?”

Having just finished creating the rental automat, you look up from your key-board and say, “You’re just in time. I’m writing the test harness now.” To testthe automat — say you’ve got 9 apartments to rent — you can create anAutomat object by passing 9 to the Automat constructor, then call thatobject’s gotApplication, checkApplication, and rentApartmentmethods; the automat changes the internal state automatically, as needed.The test harness, TestAutomat.java, looks like the following:

public class TestAutomat{Automat automat;

public static void main(String args[]){TestAutomat t = new TestAutomat();

}

public TestAutomat(){automat = new Automat(9);

automat.gotApplication();automat.checkApplication();automat.rentApartment();

}}

The result? Does the applicant get an apartment? Take a look for yourselfwhen you run the test harness.

Thanks for the application.Congratulations, you were approved.Renting you an apartment....Here are your keys!

Beautiful. Note what you’ve done — you’ve simplified the code in theautomat dramatically by offloading it to state objects. The code in theautomat doesn’t have to change to handle different states; only the stateobject itself changes. And each new state object has its own built-in methods to handle any requests made of it, appropriately, for the state it represents. By encapsulating how you handle each state in separate state objects, the code is easier to modify and maintain.

223Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 223

Page 245: Design Patterns For Dummies

Standing In for Other Objects with Proxies

The CEO of Apartments-N-Stuff Inc. is back with congratulations. “Yourautomat works terrific,” the CEO says. “So now we’d like to modify it.”

“You haven’t paid my bill yet,” you point out.

“Here’s the idea,” the CEO says. “We’ve installed your automats at all ourrental developments throughout the country — and now we’re after the inter-national market. Is there some way to let prospective tenants interact withyour automat no matter where they are in the world?”

“Sure,” you say, “using the Proxy design pattern, you can have a local objectthat ‘stands in’ for a remote object. As far as the local code knows, it’s deal-ing with the real thing instead of the proxy.”

“Fine,” says the CEO. “Get to work.”

“Fine,” you say, “pay my bill.”

Here’s the problem though: You’ve got a client somewhere in the world, and the automat somewhere else, and the two are separate, as shown inFigure 9-3.

And here’s how proxies fix the situation: You can give the client code a proxyobject that “stands in” or substitutes for the automat object and looks justlike it as far as the programming goes (that is, it supports the same methods).The proxy can communicate with the remote automat code in an automatserver, as shown in Figure 9-4.

Client

Automat serverAutomat Proxy

Figure 9-4:A proxy

acting likean automat.

ClientAutomat

Figure 9-3:Separate

client andautomat.

224 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 224

Page 246: Design Patterns For Dummies

To the client code, which is working with the automat proxy, it feels just asthough it’s working with an automat object directly. In fact, the automatproxy is just there to communicate with the automat server, which does thereal work of the automat and communicates with the proxy.

The GoF book says you can use the Proxy design pattern to, “Provide a surro-gate or placeholder for another object to control access to it.”

The Proxy design pattern is your best friend when you have a remote objectyou want to work with and make that object seem local, or when you want tocontrol access to that remote object in some way.

The Proxy pattern is easy enough to put to work. After accepting your fat feefrom the CEO of Apartments-N-Stuff Inc., you set to work. The CEO wants theautomat proxy to be able to connect to an automat server anywhere in theworld, so you decide to use the Internet. There are various connection tech-niques you can use in Java, such as RMI, to enable proxies to talk to remoteobjects. Since all you have to do is send text back and forth from automatproxy to automat server, you decide that it’s simpler to go with Java socketsand text streams.

The code you’re about to develop can send text back and forth between anytwo points on the Internet — if you want to, it’s easily adaptable to createyour own messaging service or private e-mail system. All you need to do ismake sure the server has a fixed IP address — and if you have broadband,you should.

Can you hear me now? Creating the automat serverYou set to work on the automat server first. This is just an automat that cantalk to an automat proxy over the Internet. For example, the proxy can sendtext messages like “checkApplication” or “rentApartment” to theautomat server, and the server can call those methods and send back theresponse to the proxy.

So how do you set up an automat so it can talk to an automat proxy over theInternet? All you need to do is use a Java ServerSocket and set up anInputStream and an OutputStream to communicate with the automatproxy. You can make life easy on yourself by using the OutputStream tocreate a PrintWriter object that lets you use the println method to sendtext back to the proxy. And the InputStream has to handle text whenever itcomes in from the proxy, so you can handle that in a new thread.

225Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 225

Page 247: Design Patterns For Dummies

The server can be configured to listen for connections on port 8765 — that’sjust a random port; if you want to use a different port, just change that valuein the code. The following code shows how to set up the PrintWriter foroutgoing text and the thread to handle the incoming text in the AutomatServer class’s constructor:

import java.io.*;import java.net.*;

public class AutomatServer implements Runable, AutomatInterface{State waitingState;State gotApplicationState;State apartmentRentedState;State fullyRentedState;State state;int count;private Thread thread;ServerSocket socket;PrintWriter out;Socket communicationSocket;

public static void main(String args[]){AutomatServer d = new AutomatServer();

}

public AutomatServer(){count = 9;waitingState = new WaitingState(this);gotApplicationState = new GotApplicationState(this);apartmentRentedState = new ApartmentRentedState(this);waitingState = new WaitingState(this);state = waitingState;

try { socket = new ServerSocket(8765);

communicationSocket = socket.accept();

out = new PrintWriter (communicationSocket.getOutputStream(), true);

thread = new Thread(this);thread.start();

}catch (Exception e) {

226 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 226

Page 248: Design Patterns For Dummies

System.err.println(e.getMessage());}

}...

The next step is to set up an InputStream to handle text sent from the proxyin the worker thread’s run method. You can make life easier here, too, byusing that InputStream to create a BufferedReader object that lets youread incoming text, line by line, with its readLine method. The messagessent from the proxy can be “checkApplication” or “rentApartment”,and so on, and you should call the appropriate Automat methods to match.Here’s how the automat server waits for messages from the proxy and callsthe correct local Automat methods as needed:

public void run() {String incomingString;try {

BufferedReader in = new BufferedReader (new InputStreamReader(communicationSocket.getInputStream()));while((incomingString = in.readLine()) != null){if (incomingString.equals(“gotApplication”)){gotApplication();

} else if (incomingString.equals(“checkApplication”)) {checkApplication();

} else if (incomingString.equals(“rentApartment”)) {rentApartment();

}}

}catch (Exception e) {System.err.println(e.getMessage());

} }

Before using a proxy, the Automat methods like checkApplication andrentApartment used to display text returned from the current stateobject this way:

public void gotApplication(){System.out.println(state.gotApplication());

}

public void checkApplication()

227Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 227

Page 249: Design Patterns For Dummies

{System.out.println(state.checkApplication());

}

public void rentApartment(){System.out.println(state.rentApartment());System.out.println(state.dispenseKeys());

}

But that’s not going to work here — you have to use the PrintWriterobject, out, to send text back to the proxy. Here’s what the Automatmethods look like as adapted for the automat server, sending text back to the proxy as appropriate:

public void gotApplication(){out.println(state.gotApplication());

}

public void checkApplication(){out.println(state.checkApplication());

}

public void rentApartment(){out.println(state.rentApartment());out.println(state.dispenseKeys());

}

That completes the automat server. When the automat proxy connects to it,it can accept commands and send the results back. How about creating theproxy?

Anyone there? Creating the automat proxyThe automat proxy’s job is to connect to the automat server across theInternet while letting the client code think that it’s interacting with a stan-dard, local automat. The automat server has to be running and listening onits machine before the automat proxy can connect to it. Here’s how the con-nection process works — you pass the IP address and port number to theSocket constructor. In this example, the IP address is 127.0.0.1, which standsfor the same machine you’re executing the code on. (So to make this work inWindows, for example, open a second DOS window and start the automatserver there before starting the test harness.) If you want to connect across

228 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 228

Page 250: Design Patterns For Dummies

the Internet to another machine, just replace the IP address with the IPaddress of the machine where the automat server is running. The followingcode shows how the automat proxy sets up the connection to the server, creating objects named in and out to receive and send data:

import java.io.*;import java.net.*;

public class AutomatProxy implements Runable{private Thread thread;Socket socket;InputStream in;PrintWriter out;int character;

public AutomatProxy(){try{socket = new Socket(“127.0.0.1”, 8765);System.out.println(“Connecting....”);

in = socket.getInputStream();out = new PrintWriter (socket.getOutputStream(), true);

thread = new Thread(this);thread.start();

}catch (IOException ioe){System.err.println(“The server must be running.”);System.err.println(“Not connected”);

}catch (Exception e){System.err.println(e.getMessage());

}

if(socket != null && socket.isConnected()){System.out.println(“Connected”);

}}...

When the client code calls the proxy’s standard automat methods — gotApplication, checkApplication, and rentApartment, the proxy sendsthe name of the called method to the automat server using its PrintWriterobject named out.

229Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 229

Page 251: Design Patterns For Dummies

public void gotApplication(){out.println(“gotApplication”);

}

public void checkApplication(){out.println(“checkApplication”);

}

public void rentApartment(){out.println(“rentApartment”);

}

That takes care of sending commands to the automat server. What about lis-tening for a response? Like the automat server, the automat proxy launches a new thread to listen with. The following code shows how it listens for textcoming back from the server in the thread’s run method — when text comesback from the server, the proxy prints that text out.

public void run() {try{while ((character = in.read()) != -1) {System.out.print((char) character);

}}catch(Exception ex){System.out.println(ex.getMessage());

}}

Now you’ve built an automat proxy that connects to an automat server andadded the code that lets the two communicate. Time to test this out.

Using the proxy to connect around the worldTo test the automat proxy and server, start the server (if you’re testing thison a single machine in Windows, start the server in a new DOS window) and run the code in the test harness, TestAutomatProxy.java. This testharness uses an automat proxy in the same way as it would use an automatobject. Behind the scenes, the automat proxy connects to the automat server and passes on all it’s asked to do to the automat server.

230 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 230

Page 252: Design Patterns For Dummies

Here’s the code that shows how the test harness uses the automat proxy toget an application, check it, and rent an apartment:

public class TestAutomatProxy{AutomatProxy automatProxy;

public static void main(String args[]){TestAutomatProxy t = new TestAutomatProxy();

}

public TestAutomatProxy(){automatProxy = new AutomatProxy();

automatProxy.gotApplication();automatProxy.checkApplication();automatProxy.rentApartment();

}}

What’s the result? First the proxy connects to the server, then it sends thecommands the automat server should run, and then it displays the text itgets back. Here’s what a prospective tenant in another country sees:

Connecting....ConnectedThanks for the application.Congratulations, you were approved.Renting you an apartment....Here are your keys!

“There you go,” you say to the CEO of Apartments-N-Stuff Inc. “Now you’rerenting apartments internationally, over the Internet.”

“Yeah,” says the CEO thoughtfully. “Maybe we better change that last line toWe’re mailing you the keys. now.”

231Chapter 9: Getting Control of Your Objects with the State and Proxy Patterns

14_798541 ch09.qxp 3/27/06 2:23 PM Page 231

Page 253: Design Patterns For Dummies

232 Part II: Becoming an OOP Master

14_798541 ch09.qxp 3/27/06 2:23 PM Page 232

Page 254: Design Patterns For Dummies

Chapter 10

Coordinating Your Objects withthe Command and Mediator

PatternsIn This Chapter� Using the Command pattern to build a command toolkit

� Creating command queues and implementing an undo command

� Understanding the Mediator design pattern

� Connecting objects using the Mediator design pattern

� Building a Web site based on a mediator

You’re consulting for GlobalHugeCo, the computer manufacturer, whenthe Chief Information Officer comes in, looks at a monitor on the wall,

and says, “Uh oh.”

“What’s the problem?” you ask.

“We run servers for different regions of the world, and it’s mission-criticalthat we keep those servers operating.”

“And there’s a problem?” you ask.

The CIO looks wearily at the monitor on the wall and says, “We’ve got a 24-hour Crisis Center that handles calls from our major customers. If there’s aproblem with the servers, we know about it instantly. However, there’s aproblem with the Crisis Center.”

“And that is?”

“Our software is so confusing that the Crisis Center typically gets all bollixedup before it can handle any problem. If there’s a problem with the Asiaserver, our techs have to connect to the Asia server, run diagnostics, and dis-connect again. Meanwhile, a problem with the Euro server might have come

15_798541 ch10.qxp 3/27/06 2:24 PM Page 233

Page 255: Design Patterns For Dummies

up, and they have to connect to the Euro server, reboot it, and disconnect.Then the U.S. server starts acting up again. So they get all confused makingdozens of method calls among all the different servers.”

“Hmm,” you say, “this sounds like a job for the Command design pattern.”

“That’s just what I said to them,” the CIO says.

This chapter is about two related design patterns — the Command andMediator design patterns, which are all about letting you interact with andcoordinate other objects.

The Command design pattern lets you package complex commands into asingle object. Rather than having to perform the multiple steps needed toexecute each command every time, you can create a bunch of ready-to-usecommand objects, each of which can handle multiple steps internally. Eachcommand is already configured with its target (such as the Asia server) andthe action it’s supposed to perform (such as reboot a server), so a set ofcommand objects can act as a ready-made toolkit, already configured and allset to operate on the target objects they’re supposed to handle.

The Mediator design pattern also supports coordination between objects.You may have, for example, a dozen different windows in a GUI, all connectedin intricate ways. When the user clicks one button in one window (such asthe Exit, Purchase Now!, or Shop buttons), a window has to pass control onto another window and let that next window know what the current state is —for example, “the user wants to make a purchase”, “the userwants to exit”, and so on. The more windows, the more difficult it is tocoordinate them all because they’re tightly coupled. A mediator makes thecoupling looser by having all objects report state changes to the mediatorand take commands from the mediator. That way, each window in your GUIonly has to interact with the mediator, and doesn’t have to understand all themethods to call in the various other windows. This chapter shows you howto simplify your windows with the Mediator design pattern.

Taking Command with the Command Pattern

There you are, the famous and well-paid design pattern consultant, at workon the CIO of GlobalHugeCo’s problem. You understand the problem; when acrisis happens in one of the company’s three servers, the Crisis Center has to react fast. But the programmers in the Crisis Center only have a bunch ofmethods ready for use, as illustrated in Figure 10-1.

234 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 234

Page 256: Design Patterns For Dummies

When there’s a crisis, the Crisis Center programmers have to call the connectmethod of the correct server, then take actions like shutting down the serveror running diagnostics on it, and then have to disconnect from the server.That confuses them — sometimes commands are sent to the wrong server, orprogrammers forget to connect to a server before issuing commands to it,and so on. But the Command design pattern is here to fix all that.

The Command design pattern says that in cases like this, you should encap-sulate all the separate actions into objects configured for specific targets.That gives you a number of objects that act like a set of tools, ready to beused. Figure 10-2 shows what the Crisis Center’s toolkit might look like, withready-to-use command objects.

In other words, the idea here is encapsulation. You’re encapsulating a set ofcomplex actions, targeted at a particular target, into an easily handled object.When you want to execute a command, you no longer have to take all the sep-arate steps — connect to the target, perform the action, check on the action,and disconnect from the target. You just use the specific prebuilt, preconfig-ured command object, and it does the work.

Crisis Center Asia server

shutDownAsia

rebootAsia

runDiagnosticsAsia

Euro server

US server

Figure 10-2:The Crisis

Center’stoolkit.

Crisis Centerconnect()shutdown()reboot()disconnect()diagnostics() . . .

Asia server

Euro server

US server

Figure 10-1:The Crisis

Center andits methods.

235Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 235

Page 257: Design Patterns For Dummies

The Gang of Four (GoF) book (Design Patterns: Elements of Reusable Object-Oriented Software, 1995, Pearson Education, Inc. Publishing as PearsonAddison Wesley) says you use the Command pattern to, “Encapsulate arequest as an object, thereby letting you parameterize clients with differentrequests, queue or log requests, and support undoable operations.”

In simple terms, the target of a command object is called its receiver. Whenyou create a command object, you typically pass it the receiver it’s supposedto work on so it can access that receiver. When you want to execute a com-mand, you typically pass it to an object that acts as an invoker. The invokercalls the methods of the command object — such as execute (to executethe primary action on the receiver) or undo (which can undo the most recentaction.

You use the Command design pattern when you’ve got a complex set of com-mands that get annoying. When the interface to those commands is so com-plex that it gets in the way, it makes sense to encapsulate those commands.

The inspiration behind this design pattern is that it takes encapsulation toanother level. Programmers often use encapsulation to extract a set of meth-ods and data and wrap them in an object to simplify their code. But you don’t usually think of encapsulating commands. By preconfiguring those com-mands to handle the receivers of their actions and bundling complex stepsinto single, easy-to-handle objects, you end up with a prebuilt toolkit, readyto use. And that’s what encapsulation is all about — bundling methods anddata to get it out of the way. When you use this pattern, though, the objectsyou’re creating aren’t so much nouns as verbs, encapsulating commands.

Aiming at the target: Creating your receiver objectsThe receiver is what a command object works on. In the previous example,that’s one of the three company servers: the server that handles Asia, theEuro server, or the U.S. server. Each of these act as receivers of the commandobject’s actions.

Each of these three servers has various methods, such as connect to con-nect to them, diagnostics to run their diagnostics, reboot, shutdown,and disconnect. Because there are three servers, you should put thosemethods into an interface, named, in this case, Receiver, as shown in thefollowing:

public interface Receiver{public void connect();public void diagnostics();

236 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 236

Page 258: Design Patterns For Dummies

public void reboot();public void shutdown();public void disconnect();

}

Each receiver — that is, each server — can implement the Receiver inter-face. For example, here’s how the AsiaServer class starts:

public class AsiaServer implements Receiver{

.

.

.}

To make life a little easier, each of the server’s methods can print out a mes-sage on the Crisis Center console, as shown in the following:

public class AsiaServer implements Receiver{public AsiaServer(){}

public void connect(){System.out.println(“You’re connected to the Asia server.”);

}

public void diagnostics(){System.out.println(“The Asia server diagnostics check out OK.”);

}

public void shutdown(){System.out.println(“Shutting down the Asia server.”);

}

public void reboot(){System.out.println(“Rebooting the Asia server.”);

}

public void disconnect(){System.out.println(“You’re disconnected from the Asia server.”);

}

}

237Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 237

Page 259: Design Patterns For Dummies

The EuroServer class should look like the following:

public class EuroServer implements Receiver{public EuroServer(){}

public void connect(){System.out.println(“You’re connected to the Euro server.”);

}

public void diagnostics(){System.out.println(“The Euro server diagnostics check out OK.”);

}

public void shutdown(){System.out.println(“Shutting down the Euro server.”);

}

public void reboot(){System.out.println(“Rebooting the Euro server.”);

}

public void disconnect(){System.out.println(“You’re disconnected from the Euro server.”);

}

}

And here’s the USServer class:

public class USServer implements Receiver{public USServer(){}

public void connect(){System.out.println(“You’re connected to the US server.”);

}

public void diagnostics(){

238 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 238

Page 260: Design Patterns For Dummies

System.out.println(“The US server diagnostics check out OK.”);}

public void shutdown(){System.out.println(“Shutting down the US server.”);

}

public void reboot(){System.out.println(“Rebooting the US server.”);

}

public void disconnect(){System.out.println(“You’re disconnected from the US server.”);

}

}

That gives you the three receivers that receive commands — that is, thethree GlobalHugeCo servers. The next step is to create the commands thatlet you work with those servers.

Be the boss: Creating your commandsCommands are preconfigured to perform various actions. To make them do their thing, you typically call an execute method. Say you want three command classes here: ShutDownCommand, RebootCommand, and RunDiagnosticsCommand. Each of these can perform the action correspondingto its name, and each of these can be configured to work with a specificreceiver. To keep things constant over these three command classes, youmight set up an interface, Command, which supports an execute method.

public interface Command{public void execute();

}

As with all commands, the ShutDownCommand class is configurable to handlea specific receiver (that is, a server in this example). This class is supposedto shut down a server, so when you create an object of this class, you pass aserver to it as the command’s receiver as shown in the following code:

public class ShutDownCommand implements Command{Receiver receiver;

public ShutDownCommand(Receiver r)

239Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 239

Page 261: Design Patterns For Dummies

{receiver = r;

}...

}

When the command’s execute method is called, it’s supposed to shut downthe server — which means connecting to the server, shutting it down, andthen disconnecting. All that happens in the execute method.

public class ShutDownCommand implements Command{Receiver receiver;

public ShutDownCommand(Receiver r){receiver = r;

}

public void execute(){receiver.connect();receiver.shutdown();receiver.disconnect();System.out.println();

}}

Good, you’ve created a configurable command class that can shut downservers. Here’s the RunDiagnosticsCommand command class, which connects to servers, runs diagnostics on them, and then disconnects:

public class RunDiagnosticsCommand implements Command{Receiver receiver;

public RunDiagnosticsCommand(Receiver r){receiver = r;

}

public void execute(){receiver.connect();receiver.diagnostics();receiver.disconnect();System.out.println();

}}

240 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 240

Page 262: Design Patterns For Dummies

And here’s the RebootCommand class, which reboots a server:

public class RebootCommand implements Command{Receiver receiver;

public RebootCommand(Receiver r){receiver = r;

}

public void execute(){receiver.connect();receiver.reboot();receiver.disconnect();System.out.println();

}}

That gives you the receivers (that is, the three servers) and the commandclasses that act on those receivers. How about putting these commandclasses to work?

Getting your commands to actually do something: Creating the invokerThe invoker is the class that actually puts the commands to work. You typi-cally load a command object into the invoker and tell the invoker to run it.

When you implement the Command design pattern, you don’t need to use an invoker if you don’t want to — if your commands only have an executemethod, for example, you might want to dispense with the invoker altogetherand just call that method. However, as I discuss in this chapter, invokers canalso keep track of multiple commands in a log or a queue, which makes undo-ing a sequence of commands possible.

The invoker in this example starts with only a constructor, a setCommandmethod that lets you load a command into the invoker, and a run methodthat runs the command, as you can see in the following code:

public class Invoker{Command command;

public Invoker()

241Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 241

Page 263: Design Patterns For Dummies

{}

public void setCommand(Command c){command = c;

}

public void run(){command.execute();

}}

You’re set. You have receivers, you have the commands, you have theinvoker — it’s time to put this to work.

Putting commands to the testHere’s a test harness, TestCommands.java, which instantiates serverobjects and a set of commands that are ready to be used with those servers,such as shutDownAsia, runDiagnosticsAsia, and rebootAsia. Aftercreating a server object, you pass it to a given command, and the commandstores the server as the receiver of its actions. Then when you call the execute method of the command, such as shutDownAsia, the commandcalls all the necessary methods (connect, shutdown, and disconnect) to shut down the server it’s been configured for.

You say to yourself with satisfaction: Now, when it’s time to take action, theCrisis Center staff only has to load a prebuilt command into the invoker andcall the invoker’s run method to run the command. The staff no longer has tofumble around with multi-step sequences of actions that are prone to error.For example, here’s how the test harness shuts down the Asia server, rebootsit, runs diagnostics on it, as well as shuts down the Euro server and runsdiagnostics on that server:

public class TestCommands{public static void main(String args[]){TestCommands t = new TestCommands();

}

public TestCommands(){Invoker invoker = new Invoker();

// Create the receivers

242 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 242

Page 264: Design Patterns For Dummies

AsiaServer asiaServer = new AsiaServer();EuroServer euroServer = new EuroServer();USServer usServer = new USServer();

//Create the commandsShutDownCommand shutDownAsia = new ShutDownCommand(asiaServer);RunDiagnosticsCommand runDiagnosticsAsia = new RunDiagnosticsCommand(asiaServer);

RebootCommand rebootAsia = new RebootCommand(asiaServer);ShutDownCommand shutDownEuro = new ShutDownCommand(euroServer);RunDiagnosticsCommand runDiagnosticsEuro = new RunDiagnosticsCommand(euroServer);

RebootCommand rebootEuro = new RebootCommand(euroServer);ShutDownCommand shutDownUS = new ShutDownCommand(usServer);RunDiagnosticsCommand runDiagnosticsUS = new RunDiagnosticsCommand(usServer);

RebootCommand rebootUS = new RebootCommand(usServer);

invoker.setCommand(shutDownAsia);invoker.run();

invoker.setCommand(rebootAsia);invoker.run();

invoker.setCommand(runDiagnosticsAsia);invoker.run();

invoker.setCommand(shutDownEuro);invoker.run();

invoker.setCommand(runDiagnosticsEuro);invoker.run();

}}

And here’s what you see when you run this code:

You’re connected to the Asia server.Shutting down the Asia server.You’re disconnected from the Asia server.

You’re connected to the Asia server.Rebooting the Asia server.You’re disconnected from the Asia server.

You’re connected to the Asia server.The Asia server diagnostics check out OK.You’re disconnected from the Asia server.

You’re connected to the Euro server.Shutting down the Euro server.You’re disconnected from the Euro server.

243Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 243

Page 265: Design Patterns For Dummies

You’re connected to the Euro server.Rebooting the Euro server.You’re disconnected from the Euro server.

You’re connected to the Euro server.The Euro server diagnostics check out OK.You’re disconnected from the Euro server.

Excellent. Just what you wanted. Now you’ve got a prebuilt toolkit of com-mands, ready to use on the various servers.

Supporting undoYou might add an undo method to each command object to let client codeundo an operation.

public interface Command{public void execute();public void undo();

}

For example, an undo method might reboot a server in a shutdown command.

public class ShutDownCommand implements Command{Receiver receiver;

public ShutDownCommand(Receiver r){receiver = r;

}

public void execute(){receiver.connect();receiver.shutdown();receiver.disconnect();System.out.println();

}

public void undo(){System.out.println(“Undoing...”);receiver.connect();receiver.reboot();receiver.disconnect();System.out.println();

}}

244 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 244

Page 266: Design Patterns For Dummies

And when you undo a reboot command, you would shut down the server.

public class RebootCommand implements Command{Receiver receiver;

public RebootCommand(Receiver r){receiver = r;

}

public void execute(){receiver.connect();receiver.reboot();receiver.disconnect();System.out.println();

}

public void undo(){System.out.println(“Undoing...”);receiver.connect();receiver.shutdown();receiver.disconnect();System.out.println();

}}

245Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

Why invoke the invoker?But did you really need the invoker? All you didwas call the invoker’s run method, whichcalled the command’s execute method; youcould have called the command’s executemethod yourself.

But take a look at the GoF definition for this pat-tern again: “Encapsulate a request as an object,thereby letting you parameterize clients withdifferent requests, queue or log requests, andsupport undoable operations.” What about that“parameterize clients with different requests”?What’s that all about?

Say you had a dedicated set of invokers, eachwith different names — for example, one might

be called panicbutton. When there’s a prob-lem, you don’t have to think about what you’redoing — you just hit the panicbuttoninvoker’s runmethod. As the code enters differ-ent states, the command loaded into the panicbutton invoker may differ, but you don’t haveto think about that — if there’s a problem, youjust hit the panicbutton invoker’s runmethod. That’s one reason to use invokers.

Another reason comes from the rest of the GoFdefinition: “ . . . queue or log requests, and sup-port undoable operations.” Invokers can keeptrack of entire queues of commands, which isuseful if you want to start undoing sequences ofcommands. That’s coming up next.

15_798541 ch10.qxp 3/27/06 2:24 PM Page 245

Page 267: Design Patterns For Dummies

On the other hand, you can’t really undo a run diagnostics command — onceyou’ve run the diagnostics, you can’t undo them.

public class RunDiagnosticsCommand implements Command{Receiver receiver;

public RunDiagnosticsCommand(Receiver r){receiver = r;

}

public void execute(){receiver.connect();receiver.diagnostics();receiver.disconnect();System.out.println();

}

public void undo(){System.out.println(“Can’t Undo.”);System.out.println();

}}

Now an invoker comes in handy by storing a queue of commands. If you wantto undo multiple commands, you only have to call the invoker’s undo methodmultiple times. For example, say that you want to store a maximum of fivecommands in the invoker, which you might do in an array. Every time a newcommand is loaded into the invoker, it goes into a new position in the array.

public class Invoker{Command commands[] = new Command[5];int position;

public Invoker(){position = -1;

}

public void setCommand(Command c){if (position < commands.length - 1){position++;commands[position] = c;

} else {

246 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 246

Page 268: Design Patterns For Dummies

for (int loopIndex = 0; loopIndex < commands.length - 2; loopIndex++){commands[loopIndex] = commands[loopIndex + 1];

}commands[commands.length - 1] = c;

}}...

Next, the invoker’s run method should run the current command. And theinvoker’s undo method should undo the current command, and then stepback one position in the command queue.

.

.

.public void run(){commands[position].execute();

}

public void undo(){if (position >= 0){commands[position].undo();

}position--;

}

Testing the undoNow you’ve got an invoker that can keep track of a queue of commands,which means it can perform multi-step undo operations. To test that out, youmight change the test harness to shut down the Asia server, then reboot it —and then undo those two operations in sequence like this:

public class TestCommands{public static void main(String args[]){TestCommands t = new TestCommands();

}

public class TestCommands{public static void main(String args[])

247Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 247

Page 269: Design Patterns For Dummies

{TestCommands t = new TestCommands();

}

public TestCommands(){Invoker invoker = new Invoker();

// Create the receiversAsiaServer asiaServer = new AsiaServer();EuroServer euroServer = new EuroServer();USServer usServer = new USServer();

//Create the commandsShutDownCommand shutDownAsia = new ShutDownCommand(asiaServer);RunDiagnosticsCommand runDiagnosticsAsia = new RunDiagnosticsCommand(asiaServer);

RebootCommand rebootAsia = new RebootCommand(asiaServer);ShutDownCommand shutDownEuro = new ShutDownCommand(euroServer);RunDiagnosticsCommand runDiagnosticsEuro = new RunDiagnosticsCommand(euroServer);

RebootCommand rebootEuro = new RebootCommand(euroServer);ShutDownCommand shutDownUS = new ShutDownCommand(usServer);RunDiagnosticsCommand runDiagnosticsUS = new RunDiagnosticsCommand(usServer);

RebootCommand rebootUS = new RebootCommand(usServer);

invoker.setCommand(shutDownAsia);invoker.run();

invoker.setCommand(rebootAsia);invoker.run();

invoker.undo();invoker.undo();

}}

When you run this test harness, you can see that each command is first exe-cuted and then undone in sequence.

You’re connected to the Asia server.Shutting down the Asia server.You’re disconnected from the Asia server.

You’re connected to the Asia server.Rebooting the Asia server.You’re disconnected from the Asia server.

Undoing...

248 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 248

Page 270: Design Patterns For Dummies

You’re connected to the Asia server.Shutting down the Asia server.You’re disconnected from the Asia server.

Undoing...You’re connected to the Asia server.Rebooting the Asia server.You’re disconnected from the Asia server.

Cool. That’s what the Command design pattern is all about — encapsulatingcommands. As mentioned earlier, this encapsulation is a little different fromthe usual, where you end up with an object that you can think of as a noun.Here, you think of the resulting object more as a verb. And when you use aninvoker, you can handle whole sequences of commands and undo them ifneeded.

Coordinating with the Mediator Pattern“Hmm,” say the programmers at agribusiness Rutabagas-R-Us Inc. “We’rehaving trouble with our Web site.”

“What’s the problem?” you ask.

“There are too many pages,” they say.

“How many do you have?”

“Four,” they say.

“Four? That doesn’t sound like too many.”

“It’s not really that,” the programmers say. “It’s the code that takes usersfrom one page to another — what if they’re on the Shopping page looking atour delicious rutabagas and want to go back to the Welcome page? Or to theExit page? What if they’re on the Purchase page, about to buy a few crates ofrutabagas, but suddenly want to jump to the Exit page without buying any-thing? Each page has to be crammed with code that knows how to deal withother pages.”

“Ah,” you say, “there’s no problem. I’ll just put the Mediator pattern to work.”

Like the Command pattern, the Mediator pattern involves coordinationbetween objects. Figure 10-3 shows the current situation, with the fourRutabagas-R-Us Inc. Web pages: the Welcome page, the Store page for lookingat the delicious rutabagas for sale, the Purchase page where you can buyfresh rutabagas to be delivered every month, and the Exit page. Note thatevery page has to be able to connect to every other page.

249Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 249

Page 271: Design Patterns For Dummies

The Mediator design pattern brings a central processing hub into the picture. All the pages now have to interact with the mediator only. When a page’s internal state changes, it just reports that state change to the mediator, which decides where to transfer control next, acting something like a controller in Model/View/Controller architecture.

You can take the navigation code out of the separate windows and place itinto the mediator object instead. The mediator can also be built to deal witheach window so that the various windows don’t have to know the internals of the other windows, such as which methods to call. Figure 10-4 shows howthe Mediator pattern solves the traffic jam at Rutabagas-R-Us Inc.

When you use a mediator, you’re encapsulating the interaction betweenobjects. Each object no longer has to know in detail how to interact with theother objects. The coupling between objects goes from tight and brittle toloose and agile. And one of the design insights of this book is that you shouldgo for loose coupling when possible.

Welcome

Mediator

Store

Purchase Goodbye

Figure 10-4:Adding amediator

to theRutabagas-

R-Us Inc.Web pages.

Welcome Store

Purchase Goodbye

Figure 10-3:The four

Rutabagas-R-Us Inc.

Web pages.

250 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 250

Page 272: Design Patterns For Dummies

The Gang of Four book says you can use the Mediator pattern to, “Define anobject that encapsulates how a set of objects interact. Mediator promotesloose coupling by keeping objects from referring to each other explicitly, andit lets you vary their interaction independently.”

The Mediator design pattern should be your first choice as a possible solution any time you have a set of objects that are tightly coupled. If every one of a series of objects has to know the internal details of the otherobjects, and maintaining those relationships becomes a problem, think of the Mediator. Using a Mediator means the interaction code has to reside inonly one place, and that makes it easier to maintain.

Using a mediator can hide a more serious problem: If you have multipleobjects that are too tightly coupled, your encapsulation may be faulty. Might be time to rethink how you’ve broken your program into objects.

The Mediator pattern is something like a multiplexed Façade pattern where,instead of supplanting the interface of a single object, you’re making the multiplexed interface among multiple objects easier to work with.

Designing the Rutabagas-R-Us siteMediators are often used in GUIs, as at Rutabagas-R-Us Inc. To revamp theirWeb site to work with a mediator, you rewrite their Web pages to simplyreport state changes to the mediator. The mediator, in turn, can activate new pages by calling that page’s go method.

For example, the Welcome page asks the user if he or she wants to shop or exit and, when the user makes a selection, passes the matching statechange, “welcome.shop” or “welcome.exit”, to the mediator. To give theWelcome page access to the mediator, you pass the mediator object to theWelcome page’s constructor. Here’s what the Welcome page’s code looks like:

import java.io.*;

public class Welcome{Mediator mediator;String response = “n”;

public Welcome(Mediator m){mediator = m;

}

251Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 251

Page 273: Design Patterns For Dummies

public void go(){System.out.print(“Do you want to shop? [y/n]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}

if (response.equals(“y”)){mediator.handle(“welcome.shop”);

} else {mediator.handle(“welcome.exit”);

}}

}

The Shopping page displays photos of those luscious rutabagas, and fromthis page, the user can decide to go to the Purchase page or the Exit page.

import java.io.*;

public class Shop{Mediator mediator;String response = “n”;

public Shop(Mediator m){mediator = m;

}

public void go(){System.out.print(“Are you ready to purchase? [y/n]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}

if (response.equals(“y”)){

252 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 252

Page 274: Design Patterns For Dummies

mediator.handle(“shop.purchase”);} else {mediator.handle(“shop.exit”);

}}

}

The Purchase page asks the user if he or she wants to buy now, and if so,thanks the user for the purchase and moves him or her to the Exit page. If theuser doesn’t want to buy now, the page moves him or her to the Exit page,but without displaying a message.

import java.io.*;

public class Purchase{Mediator mediator;String response = “n”;

public Purchase(Mediator m){mediator = m;

}

public void go(){System.out.print(“Buy the item now? [y/n]? “);

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

try{response = reader.readLine();

} catch (IOException e){ System.err.println(“Error”);

}

if (response.equals(“y”)){System.out.println(“Thanks for your purchase.”);

}

mediator.handle(“purchase.exit”);}

}

253Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 253

Page 275: Design Patterns For Dummies

The Exit page just displays the following “Please come again some-time.” message.

public class Exit{Mediator mediator;

public Exit(Mediator m){mediator = m;

}

public void go(){System.out.println(“Please come again sometime.”);

}}

Those are the four pages — now it’s time to connect them.

Connecting it all up with the mediatorThe mediator connects all four pages together. You start the mediator by cre-ating the individual pages and passing the mediator to its constructors sothat each page has access to it.

public class Mediator{Welcome welcome;Shop shop;Purchase purchase;Exit exit;

public Mediator(){welcome = new Welcome(this);shop = new Shop(this);purchase = new Purchase(this);exit = new Exit(this);

}...

And each page passes state changes on to the mediator’s handle method,which calls other pages’ go method as appropriate.

254 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 254

Page 276: Design Patterns For Dummies

public class Mediator{Welcome welcome;Shop shop;Purchase purchase;Exit exit;

public Mediator(){welcome = new Welcome(this);shop = new Shop(this);purchase = new Purchase(this);exit = new Exit(this);

}

public void handle(String state){if(state.equals(“welcome.shop”)){shop.go();

} else if(state.equals(“shop.purchase”)){purchase.go();

} else if(state.equals(“purchase.exit”)){exit.go();

} else if(state.equals(“welcome.exit”)){exit.go();

} else if(state.equals(“shop.exit”)){exit.go();

} else if(state.equals(“purchase.exit”)){exit.go();

}}

public Welcome getWelcome(){return welcome;

}}

That’s it. All that’s left is to put the new mediator to the test.

Testing the Rutabagas-R-Us sitePutting this to the test is easy. Here’s the test harness, TestMediator.java,which creates a new mediator, gets the Welcome page from the mediator, andcalls the Welcome page’s go method to get it all started.

255Chapter 10: Coordinating Your Objects with the Command and Mediator Patterns

15_798541 ch10.qxp 3/27/06 2:24 PM Page 255

Page 277: Design Patterns For Dummies

public class TestMediator{public static void main(String args[]){TestMediator t = new TestMediator();

}

public TestMediator(){Mediator mediator = new Mediator();

mediator.getWelcome().go();}

}

The Welcome page asks the user if she wants to shop for some rutabagas.

Do you want to shop? [y/n]?

Here’s a customer who’s not ready to shop, and the response she gets:

Do you want to shop? [y/n]? nPlease come again sometime.

Here’s a customer who’s ready to shop, but doesn’t want any of those succu-lent rutabagas:

Do you want to shop? [y/n]? yAre you ready to purchase? [y/n]? nPlease come again sometime.

Here’s a customer of the kind Rutabagas-R-Us Inc. wants to see — one whowants to purchase a few crates of rutabagas:

Do you want to shop? [y/n]? yAre you ready to purchase? [y/n]? yBuy the item now? [y/n]? yThanks for your purchase.Please come again sometime.

As you can see, the mediator is able to coordinate all the pages. When some-thing happens, a page lets the mediator know, and the mediator takes theappropriate next step.

256 Part II: Becoming an OOP Master

15_798541 ch10.qxp 3/27/06 2:24 PM Page 256

Page 278: Design Patterns For Dummies

Part IIIThe Part of Tens

16_838183 pt03.qxp 3/27/06 2:24 PM Page 257

Page 279: Design Patterns For Dummies

In this part . . .

In this part, you see ten more design patterns — the restof the Gang of Four patterns, and some new ones that

don’t come from the Gang of Four. You’re also going to seehow to create your own design pattern from scratch. You’llsee what’s considered a design pattern and what’s not,how to document a new one, and how to let the worldknow all about your new discovery.

16_838183 pt03.qxp 3/27/06 2:24 PM Page 258

Page 280: Design Patterns For Dummies

Chapter 11

Ten More Design Patterns In This Chapter� The Abstract Factory pattern

� The Prototype pattern

� The Bridge pattern

� The Interpreter pattern

� The Memento pattern

� The Visitor pattern

� The Circular Buffer pattern

� The Double Buffer pattern

� The Recycle Bin pattern

� The Model/View/Controller pattern

“O kay,” say the programmers at GlobalHugeCo, the computer manu-facturer, “we’ve got the patterns you’ve suggested so far imple-

mented and running. What’s next?”

“Bad news,” you say. “We’re coming to the end of the book.”

“Oh no!”

“But we’re going out with a bang,” you say. “This chapter contains not one,not two, but ten additional patterns.”

“Woo hoo!” the programmers cry.

So far, you’ve seen most of the Gang of Four (GoF) patterns, but there are sixmore left in the original set of 23. You see those six in this chapter. They’re allgood patterns, but some aren’t used often these days. And some are just

17_798541 ch11.qxp 3/27/06 2:26 PM Page 259

Page 281: Design Patterns For Dummies

plain hard to implement, like the Interpreter pattern, which says, “Given alanguage, define a representation for its grammar along with an interpreterthat uses the representation to interpret sentences in the language.” Thatsounds like a good afternoon’s work.

Besides getting the remaining Gang of Four patterns, you also get a glimpse of some more modern patterns here that don’t come from the GoF. These patterns are all in very common use today and come from the PortlandPattern Repository, hosted by Cunningham & Cunningham at http://c2.com. Anyone can get involved with these patterns, make suggestions andcomments, and post all kinds of feedback. If you want to get involved withpatterns and their use today, take a look at the site.

Another good patterns site is http://hillside.net/patterns, whichmaintains a Patterns Library.

Creating a Factory Factory: The Abstract Factory Pattern

In a way, the Abstract Factory pattern describes a factory of factories, or,more properly thought of, an abstract specification for an actual object fac-tory. (If you want to know more about the plain old Factory pattern, turn toChapter 3.) Here’s the problem: Sometimes, you might need more than onefactory to create objects of a similar nature. For example, say you’re dealingwith Swing’s pluggable look-and-feel (the graphical Java package) across sev-eral different platforms. You might want to create the same application usinga different look-and-feel for each, so you might want to create a number of dif-ferent factories.

An Abstract Factory is usually implemented as an abstract class that real,concrete factories extend. That unifies what the concrete factories do, whileallowing leeway to fit differing requirements, as when you are using a differ-ent look and feel for each application. Figure 11-1 shows how you can repre-sent the Abstract Factory pattern.

260 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 260

Page 282: Design Patterns For Dummies

The GoF book (Design Patterns: Elements of Reusable Object-Oriented Software,1995, Pearson Education, Inc. Publishing as Pearson Addison Wesley) saysthat the Abstract Factory pattern should: “Provide an interface for creatingfamilies of related or dependent objects without specifying their concreteclasses.”

Cloning when You Need It: The Prototype Pattern

You’ve been asked to help out at the local cheesecake production facility.“There’s a problem,” the cheesecakers say. “We’re getting inundated withrequests for birthday cheesecakes, where each cheesecake has to be person-alized with the recipient’s name on top.”

“What’s the problem?” you ask. “Sounds like business is good.”

“The trouble is it’s taking us too long to have to specify the ingredients of eachcake, item by item, in our code. We can’t produce enough cheesecakes — youhave to call the eggs method, the creamCheese method, the bake method,the getOutOfThePan method, the. . . .”

“I get the idea,” you say. “How about you just produce a single cheesecake,clone it multiple times, and then customize each one?”

Factory 1

Abstract Factory

Product 1

Product 2

Product 3

Factory 2

Product 1

Product 2

Figure 11-1:An Abstract

Factorypattern

example.

261Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 261

Page 283: Design Patterns For Dummies

“You can do that?” they ask.

“You can in Java,” you say.

The Prototype pattern says that when it takes a lot of resources, or a lot ofcode, to create an object, you should consider simply copying an existingobject and customizing it instead. In Java, you can copy objects if they havecopy constructors, or you can use the clone method. Figure 11-2 illustrateshow you can represent the Prototype design pattern — repeat this process asneeded to create as many objects as you need.

In code, all you have to do is set up a prototypical cheesecake and keep call-ing the clone method on it — no need to create a cheesecake from scratchin your code every time — and then add some customization to the newcheesecake, as needed.

The GoF book says the Prototype pattern should: “Specify the kinds ofobjects to create using a prototypical instance, and create new objects by copying this prototype.”

Decoupling Abstractions fromImplementations with the Bridge Pattern

There you are, designing car remotes for various types of cars. But it’s gettingconfusing. You have an abstract class that’s extended to create various types

Prototypical object

Object cloner

Object customizer

Customized object

Figure 11-2:The

Prototypepattern at

work.

262 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 262

Page 284: Design Patterns For Dummies

of car remotes: those that just control the car alarm, those that start the carremotely, and so on. But you need to deal with various different car types,such as Toyota, Honda, and so on. And to support new remotes that areplanned, your abstract Remote class has to change as needed.

This could get pretty messy. Your abstract Remote class can change, and italso needs to know what type of car it’s dealing with before you can extend itto create various types of remotes — in other words, the car that the remotehas to work with can also change. So you’ve got two things that can change:your abstract Remote class and the Car implementation the remote is sup-posed to work with.

As you’d expect, where there are two things that can change, and they’re tiedtogether, there’s a pattern that can help out. The Bridge pattern comes to therescue by saying that you should separate out the Car type into its own class.The remote will contain a car using a “has-a” relationship so that it knowswhat kind of car it’s dealing with. This relationship looks like the one shownin Figure 11-3 — the “has-a” connection between the remote and the car typeis called the bridge.

The inspiration here is that when you have an abstraction that can vary, and that’s tied to an implementation that can also vary, you should decouplethe two.

The GoF book says the Bridge design pattern should, “Decouple an abstrac-tion from its implementation so that the two can vary independently.”

RemoteBridge

Has-a relationship

Alarm remote

Remote starter

Toyota

Honda

Door lock/unlocker

Car

Figure 11-3:Using the

Bridgepattern.

263Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 263

Page 285: Design Patterns For Dummies

Creating Your Own Language: The Interpreter Pattern

This is a heavy-duty pattern. It’s all about putting together your own pro-gramming language, or handling an existing one, by creating an interpreterfor that language.

To use this pattern, you have to know a fair bit about formal grammars to puttogether a language. As you can imagine, this is one of those patterns thatdoesn’t see a lot of everyday use because creating your own language is notsomething many people do. For example, defining an expression in your newlanguage might look something like the following snippet in terms of formalgrammars:

expression ::= <command> | <repetition> | <sequence>

Each expression in your new language, then, might be made up of commands,repetitions of commands, and sequences expressions. Each item might berepresented as an object with an interpret method to translate your newlanguage into something you can run in Java, as shown in Figure 11-4.

Needless to say, implementing this pattern can get very involved. I cover ithere for completeness, but as you can imagine, it’s not one you want to starttangling with on a daily basis.

The GoF book says the Interpreter pattern should, “Given a language, define arepresentation for its grammar along with an interpreter that uses the repre-sentation to interpret sentences in the language.”

Forget Me Not: The Memento Pattern“Oh no!” cries the CEO. “The database crashed and we lost a lot of data.”

Command

Expression

interpret()

interpret()

Sequence

interpret()

Repetition

interpret()

Figure 11-4:An exampleshowing the

Interpreterpattern.

264 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 264

Page 286: Design Patterns For Dummies

“What kind of data?” you ask.

“Oh,” says the CEO slyly, “salary and payment information, mostly — all thedata that will let us pay you for your consulting work here.”

“Don’t worry about it,” you say, pulling out a flash drive stick and plugging itinto a networked machine. “I’ve been studying the Memento design patternand have a nice, private backup object that’s saved the database’s state. It’llbe easy to undo the problem.”

“Swell,” says the CEO glumly.

Here’s the problem. The client code has total access to the database, as out-lined in Figure 11-5, so if someone flubs an operation, the database is indanger.

The GoF comes to the rescue with the Memento design pattern, which givesyou a way to restore an object’s state.

The GoF book says that the Memento pattern is designed to, “Without violat-ing encapsulation, capture and externalize an object’s internal state so thatthe object can be restored to this state later.”

More than just a save-state undo command, the idea here is to “capture andexternalize an object’s internal state” for backup. You might do that with asave-state object accessible from both the client code and the database, asshown in Figure 11-6.

ClientCode

SaveState

Object

Database

Figure 11-6:Saving an

object’sstate.

ClientCode Database

Figure 11-5:The client

has fullaccess

to thedatabase.

265Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 265

Page 287: Design Patterns For Dummies

That solution, however, violates the database’s encapsulation, and the Memento design pattern starts off by saying, “Without violating encapsulation. . . .”

So what do you do? You make the save-state object private to the database,as illustrated in Figure 11-7.

Now the save-state object is inaccessible outside of the database — you’renot violating the database’s encapsulation. That’s the Memento design pat-tern — using it, you can create save-state objects that enable commands likeundo, without violating the main object’s encapsulation.

The Visitor Stops In for a MomentIf you read Chapter 8, remember the Composite you built to hold the corpo-rate structure of GiantDataPool Inc., with all the divisions and vice presi-dents? Well, now the CEO is back with a problem. “They say I can only fire thevice presidents who have been here less than a year, so I need you to alterthe Composite.”

“Yes?” you ask.

“Each object in the Composite tree structure already has a hireDatemethod that returns the hire date of each vice president. I want you to add a new method named fireable that returns true if the vice presidenthas been here less than a year. And do the same for all the directors and managers that have been added to the composite as well.”

“Hmm,” you say, “that means changing the VP, Director, and Managerclasses to add the new fireable method. Might be easier just to use theVisitor design pattern.”

“And cheaper?” asks the CEO.

“Not cheaper,” you say.

ClientCode

PrivateSaveState

Object

Database

Figure 11-7:A private

save-stateobject.

266 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 266

Page 288: Design Patterns For Dummies

With the Visitor design pattern, you can add a new operation to a structure ofobjects, like a Composite structure, without changing the objects in the struc-ture. A visitor object moves from object to object in the structure, visitingeach one and capturing its state. When the visitor has captured all the data itneeds from the objects in the structure it’s visiting, you can call the methodsof the visitor, such as the fireable method that will return a list of person-nel eligible for termination of employment.

The GoF book says the Visitor pattern should, “Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which itoperates.”

In practice, you usually use a traverser object of some kind that can movearound the object structure whose data you want, feeding data to theVisitor object like this, where the Visitor is acquiring data aboutGiantDataPool Inc, as shown in the Figure 11-8.

R&D Division

Corporation

VP: Steve

VP: Mike

VP: Nancy

VP: Wally

VP: Andre

VP: CarySales Division

VP: Ted Traverser Visitor

VP: Bob

VP: Carol

VP: Alice

Western Sales DivisionFigure 11-8:

A visitortraversingan objectstructure.

267Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 267

Page 289: Design Patterns For Dummies

The traverser moves the Visitor object from item to item in the Composite,as shown in Figure 11-9.

Alternatively, you can build the traverser into the Visitor object. Note thatwhile this works — the Visitor can move over the entire object structure,gathering information, and you can then interrogate the Visitor about theinformation it’s gathered — it violates the encapsulation of the objects in thestructure. Naughty, naughty.

That completes the 23 GoF design patterns — now you’ve seen them all.

In the rest of this chapter, I take a look at additional design patterns from thePortland Pattern Repository, as hosted by Cunningham & Cunningham athttp://c2.com.

Going in Circles with Circular Buffers“Here’s another problem,” say the company programmers at GiantDataPoolInc. “We’ve got data coming in on this line and going out on that line.”

R&D Division

Corporation

VP: Steve

VP: Mike

VP: Nancy

VP: Wally

VP: Andre

VP: CarySales Division

VP: Ted

Traverser VisitorVP: Bob

VP: Carol

VP: Alice

Western Sales DivisionFigure 11-9:

The visitor isvisiting

anotherobject.

268 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 268

Page 290: Design Patterns For Dummies

“So what’s the problem?” you ask.

“How the heck do we store that data?” they ask. “We keep running out ofspace.”

“Try a circular buffer,” you say. “It’s perfect when one part of your codestores data and another part reads that data asynchronously. Makes very efficient use of memory.”

According to the Portland Pattern Repository’s definition of the CircularBuffer design patterns, “A circular buffer is a memory allocation schemewhere memory is reused (reclaimed) when an index, incremented modulo thebuffer size, writes over a previously used location. A circular buffer makes abounded queue when separate indices are used for inserting and removingdata. The queue can be safely shared between threads (or processors) with-out further synchronization so long as one processor enqueues data and theother dequeues it.” — http://c2.com/cgi/wiki?CircularBuffer

Take a look at Figure 11-10 to see how a circular buffer, also called a ringbuffer, works. You store data items in the various locations in a ring bufferand keep track of reading and writing operations by labeling one location thehead and one the tail.

When you store an item in the circular buffer, you store the item at the tail location, and the tail advances to the next location, as you can see inFigure 11-11.

Head

Tail

Figure 11-10:A head and

tail in acircular

buffer.

269Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 269

Page 291: Design Patterns For Dummies

When you read an item, you read the item at the current head location, andthe head advances to the next position (see Figure 11-12).

By writing to the tail and reading from the head, two streams can store andread data from the same circular buffer at the same time. The following codeillustrates an example, CircularBuffer.java, which sets up an array hold-ing the number of items you pass to the constructor.

public class CircularBuffer{private Integer data[];private int head;private int tail;

public CircularBuffer(Integer number)

Head

Tail

Figure 11-12:When you

read anitem, the

headadvances.

Head Tail

Figure 11-11:The tailmoves

around asyou store

items.

270 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 270

Page 292: Design Patterns For Dummies

{data = new Integer[number];head = 0; tail = 0;

}...

}

The store method stores an item and advances the tail.

public class CircularBuffer{private Integer data[];private int head;private int tail;

public CircularBuffer(Integer number){data = new Integer[number];head = 0; tail = 0;

}

public boolean store(Integer value){if (!bufferFull()) {

data[tail++] = value;if(tail == data.length){tail = 0;

}return true;

} else {return false;

}}...

private boolean bufferFull(){if(tail + 1 == head){return true;

}if(tail == (data.length - 1) && head == 0){return true;

}return false;

}}

271Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 271

Page 293: Design Patterns For Dummies

And the read method reads the item at the head location, and advances thehead, as you can see here:

public class CircularBuffer{private Integer data[];private int head;private int tail;

public CircularBuffer(Integer number){data = new Integer[number];head = 0; tail = 0;

}...

public Integer read(){if (head != tail) { int value = data[head++];if(head == data.length){head = 0;

}return value;

} else {return null;

}}...

}

Want to give this a test spin? Try TestCircularBuffer.java (see theIntroduction for the Web address where you can get this), which loads thecircular buffer with data and reads it.

public class TestCircularBuffer{public static void main(String args[]){TestCircularBuffer t = new TestCircularBuffer();

}

public TestCircularBuffer(){CircularBuffer c = new CircularBuffer(8);

System.out.println(“Storing: 1”);

272 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 272

Page 294: Design Patterns For Dummies

c.store(1);System.out.println(“Reading: “ + c.read());System.out.println(“Storing: 2”);c.store(2);System.out.println(“Storing: 3”);c.store(3);System.out.println(“Storing: 4”);c.store(4);System.out.println(“Reading: “ + c.read());System.out.println(“Storing: 5”);c.store(5);System.out.println(“Storing: 6”);c.store(6);System.out.println(“Storing: 7”);c.store(7);System.out.println(“Reading: “ + c.read());System.out.println(“Storing: 8”);c.store(8);System.out.println(“Storing: 9”);c.store(9);System.out.println(“Storing: 10”);c.store(10);System.out.println(“Storing: 11”);c.store(11);System.out.println(“Storing: 12”);c.store(12);System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());System.out.println(“Reading: “ + c.read());

}}

When you run TestCircularBuffer.java, you see the following output;note that the buffer fills up when the test code stores a value of 10 — thevalues after that point aren’t stored because no data has been read from thebuffer to make room. That means that when you try to read the values past10, you simply get null. (The CircularBuffer class handles its data inter-nally as Integer objects, not int values, to be able to return null values ifthe buffer is empty.)

Storing: 1Reading: 1Storing: 2Storing: 3Storing: 4

273Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 273

Page 295: Design Patterns For Dummies

Reading: 2Storing: 5Storing: 6Storing: 7Reading: 3Storing: 8Storing: 9Storing: 10Storing: 11Storing: 12Reading: 4Reading: 5Reading: 6Reading: 7Reading: 8Reading: 9Reading: 10Reading: null

Do circular buffers exist in Java as it stands? They sure do — take a look atthe PipedInputStream and PipedOutputStream classes in the Java docu-mentation. You connect a piped input stream to a piped output stream, andthe result acts like a circular buffer. You write to the piped output stream inone thread and read from the piped input stream in another thread.

Doing Your Magic Off-Screen with the Double Buffer Pattern

The Portland Pattern Repository also includes a definition for the DoubleBuffer design pattern. You may have come across this one before; doublebuffering is often used in Java to avoid screen flicker when you’re displayinggraphics. The idea is that you perform your multi-step graphics creation off-screen in a buffer and then flash the results on the screen when they’re com-plete. The process is called double buffering because the screen display bufferis one buffer and the buffer in which the images are prepared is the secondbuffer.

Figure 11-13 gives you an idea of how the process works.

ScreenDisplay

DrawOff-screen

buffer

Figure 11-13:An overview

of doublebuffering.

274 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 274

Page 296: Design Patterns For Dummies

Regarding the Double Buffer design patterns, the Portland Pattern Repositorymakes the following recommendation: “Use a DoubleBuffer, i.e. two buffers,when generating revised datasets for an asynchronous processor. When thenew data is complete and self consistent, redirect the asynchronous proces-sor to the alternate buffer.” — http://c2.com/cgi/wiki?DoubleBuffer

Will you find any support for double buffering in Java? Yep, you can finddouble buffering sprinkled all around Java. One of the primary places youfind double buffering is in the Component class’s createImage method,which is often used for double buffering. Here’s how this method is defined in the Java 1.5 documentation:

“Image Component.createImage(int width, int height) Creates an off-screendrawable image to be used for double buffering.”

The idea is that you use createImage to create an Image object compatiblewith a particular visual component in your application and draw in thatImage object. When you want to flash the completed image onscreen, youcan use a Graphics object’s drawImage method.

How about an example showing createImage at work? DoubleBuffer.java in the downloadable code for this book (see the Introduction for theWeb address where you can get that) shows how this works. It uses a workerthread to draw a set of increasingly deeper red rectangles off-screen and thenflashes them onscreen.

The main method creates the window and gets everything started by creat-ing and displaying a window, then calling the drawGraphics method to display the rectangles.

import java.awt.*;import java.awt.event.*;

public class DoubleBuffer extends Frame implements Runable{Image image; Thread thread;Graphics graphics = null;int loopIndex = 0;

public static void main(String [] args){DoubleBuffer d = new DoubleBuffer();

d.setSize(200, 200);

275Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 275

Page 297: Design Patterns For Dummies

d.addWindowListener(new WindowAdapter() {public voidwindowClosing(WindowEvent e) {System.exit(0);}});

d.setTitle(“Double buffering example”);

d.setVisible(true);

d.drawGraphics();}

public DoubleBuffer(){}

The drawGraphics method creates the Image object for double bufferingand gets a Graphics object for that image to do the actual drawing. It alsostarts the worker thread, which repaints the window ten times a second inthe run method.

public void drawGraphics() {image = createImage(100, 100);graphics = image.getGraphics();thread = new Thread(this);thread.start();

}

public void run() {while(true){repaint();try {Thread.sleep(100);}catch(InterruptedException e) {System.err.println(e);}

}}

Every time the repaint method is called, the window calls the paintmethod, which is where the rectangles are drawn in the Image object doublebuffer and then copied to the screen with the drawImage method.

public void paint (Graphics g) {if(graphics != null){loopIndex += 4;if(loopIndex >= 100){loopIndex = 4;

}graphics.setColor(new Color(255, 255, 255)); graphics.fillRect(0, 0, 100, 100);

276 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 276

Page 298: Design Patterns For Dummies

graphics.setColor(new Color(2 * loopIndex, 0, 0)); graphics.drawRect(0, 0, loopIndex, loopIndex);

g.drawImage(image, 60, 60, this);}

}}

There you go — the images are drawn off-screen in a new buffer and thentransferred onscreen as needed.

Getting Multiple-Use Objects Out of the Recycle Bin Design Pattern

If your code uses many objects and the object-creation process is time- andresource-intensive, you might want to use the Recycle Bin design pattern.The idea is that when you’re done with an object, you toss it into the recyclebin, and when you need an object of the same kind again, you can grab it outof the recycle bin. Figure 11-14 shows how this pattern works, in overview.

The Portland Pattern Repository’s definition of the Recycle Bin design pat-tern is as follows: “You can store freed resources in a local bin so that subse-quent requests for these resources can reuse the ones in the bin. A clientrequests resources through the bin. The bin will reuse an existing one if avail-able or create a new one if necessary. The recycle bin may request moreresources than actually needed to optimize performance. When the use of theresource is complete, it should be returned to the bin.” — http://c2.com/cgi/wiki?RecycleBin

Code

Recycle bin

Store

Retrieve

Object

Object

Object

Figure 11-14:Working

with objectsin the

recycle bin.

277Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 277

Page 299: Design Patterns For Dummies

You can also find recycle bins in Java, such as in the thread pooling that youcan configure using classes like ScheduledThreadPoolExecutor andThreadPoolExecutor.

Entering the Big Time with theModel/View/Controller Pattern

Another popular design pattern you see at the Portland Pattern Repository isthe Model/View/Controller, or MVC, design pattern. This pattern represents agood design insight: separating the code used for presentation from thatwhich works on and handles data. Very often, Java-based online applicationsare written with a few JavaServer Pages (JSPs), and JSP is notorious formixing presentation code (including HTML) with logic code (Java code).

Larger online Java applications, particularly those based on an applicationframework like Jakarta Struts, very often use MVC architecture these days.The controller (which is often a Java servlet) oversees the whole application,calling code in the model (often a JavaBean) to handle the internal logic andbusiness rules and then sending the results to the presentation layer, theview (often made up of JSPs), which interacts with the user. Here’s anoverview of these three components:

� Model: Implements the data crunching of the application. This is thecore code that does the application’s internal work. The model doesn’tknow anything about the view or the controller — you just pass it dataand it goes from there, returning its results. In online Java applications,the model is often implemented using JavaBeans.

� View: Implements the presentation layer that interacts with the user.When the user starts interacting with an online Java application, theWeb page(s) they see are part of the view. The view also takes data sup-plied to it (usually from the controller) and displays it. In online Javaapplications, the view is often implemented using JSP.

� Controller: Acts as the boss of the application and is responsible forrouting data to the right model and view components. The controlleroversees the model and the view by reacting to the data the user sends.In online Java applications, the controller is often implemented as aservlet.

Figure 11-15 provides a schematic overview of MVC architecture:

278 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 278

Page 300: Design Patterns For Dummies

The Portland Pattern Repository says that the Model/View/Controller designpattern is, “A triad of three modules linked by the ObserverPattern, all resid-ing within a RepresentationLayer. The View drives a presentation within aGUILayer, and elements within the View observe the Model. Elements withinthe Controller observe the View and Model, and elements within the Modelobserve the Controller. The Model fronts data objects within the LogicLayer.This pattern decouples changes to how data are manipulated from how theyare displayed or stored, while unifying the code in each component.” —http://c2.com/cgi/wiki?ModelViewController

If you’re interested in creating MVC applications in Java, take a look at theJakarta Struts application framework at http://struts.apache.org. Thisframework does a lot of the work for you, including setting up a standard con-troller servlet that you can customize by creating your own objects based onthe Struts Action class, which you can pass to the controller. For more onthis topic, see Jakarta Struts for Dummies, by Mike Robinson and EllenFinkelstein (Wiley Publishing, Inc.).

UserView

(Presentation)

Model

(datacruncher)

Controller

(Application overseer)

Figure 11-15:The Model/

View/Controller

architecture.

279Chapter 11: Ten More Design Patterns

17_798541 ch11.qxp 3/27/06 2:26 PM Page 279

Page 301: Design Patterns For Dummies

280 Part III: The Part of Tens

17_798541 ch11.qxp 3/27/06 2:26 PM Page 280

Page 302: Design Patterns For Dummies

Chapter 12

Ten Easy Steps to Create Your Own Patterns

In This Chapter� Introducing the pattern catalog style

� Understanding the Rule of Three standard

� Creating your own pattern

� Sharing your pattern with others

Suddenly, there’s a terrific roar on the grounds of Missiles-N-Stuff, thecompany where you’ve been hired as a consultant. As you watch, a mis-

sile thunders off over the horizon.

“Darn,” say the Missiles-N-Stuff programmers. “That one wasn’t supposed togo off.”

“Isn’t it heading towards town?” you ask.

“Yep,” they say, “but don’t worry about it. They’re used to evacuations. Thereal problem is our code. Somehow we just can’t make sure that missilesdon’t go off by accident. The code’s gotten too large to handle it easily —everything’s become too interwoven. Isn’t there a design pattern that willhelp us out?”

“Nope,” you say, “but you can invent one.”

This Part of Tens chapter gives you a guide for how to build your own pattern in ten easy steps. Just follow along, and you’re on the route to fameand fortune (well, maybe not fame . . . and the fortune part isn’t all that sureeither. . . .).

18_798541 ch12.qxp 3/27/06 2:26 PM Page 281

Page 303: Design Patterns For Dummies

Don’t see an established design pattern where you think there should be one?You can create your own design pattern, and you can publicize that pattern,getting it into design pattern repositories around the world, leading to inter-national fame (if not necessarily fortune).

Don’t forget — design patterns are supposed to make solutions easier. Don’tcreate a design pattern just for the sake of creating a new pattern if it’s not going to be helpful. After all, patterns are supposed to be tools, not hindrances.

A design pattern, after all, is just a solution to a particular class of problem.The idea is to create a pattern that uses good object-oriented programmingpractices and that offers a solution template for a commonly encounteredproblem.

Technically speaking, the goals and constraints that a pattern works with arecalled forces by design pattern designers. I won’t use that term in the discus-sion here, but if you start designing patterns for a living, don’t be surprised ifyou come across it.

282 Part III: The Part of Tens

The Rule of ThreeDesign patterns were actually invented byChristopher Alexander, an architect at Berkeley.His book on the topic is named A PatternLanguage: Towns, Buildings, Construction(Oxford University Press), and it deals witharchitectural, not computing, problems. So youcan have design patterns in any field.

And if you can abstract such a pattern, why notshare it? For example, say you’re a painter whospecializes in painting porch floors. That’s all youpaint, and you’re the best at it. But sometimes youpaint yourself into a corner. You notice that thishappens when you’ve left yourself only one wayout and then paint over it. So you come up with anew design pattern for porch painters: “Always

leave yourself a way out when approaching cor-ners. And don’t paint over it.” Not bad, you think,and post it all over the Internet for the benefit ofother porch painters.

Are you a little premature in doing that? Could be.Patterns generally are expected to pass the “Ruleof Three” before they can be taken seriously. TheRule of Three says that a pattern has to be usedin at least three real-world applications before itcan be considered for true patternhood. In fact,it’s even a little more rigorous than that — thesedays, you list ten criteria for a new pattern andenter it into a pattern catalog. (See the “Followingthe Pattern Catalog Style” section in this chapterfor more information on pattern catalogs.)

18_798541 ch12.qxp 3/27/06 2:26 PM Page 282

Page 304: Design Patterns For Dummies

Following the Pattern Catalog StyleThe best way to start anything is with a guide of some kind, and for designpatterns, that guide is the pattern catalog style. There are ten sections in apattern catalog, and here they are — you’re going to see a definition of eachof these in the remainder of this chapter.

1. Intent

2. Motivation

3. Applicability

4. Structure

5. Participants

6. Collaborations

7. Consequences

8. Implementation/Sample Code

9. Known Uses

10. Related Patterns

In the Gang of Four (GoF) book (Design Patterns: Elements of Reusable Object-Oriented Software, 1995, Pearson Education, Inc. Publishing as PearsonAddison Wesley), each of the 23 patterns is written in catalog style, with eachof these ten topics carefully covered for each pattern in the GoF book.

When you want to create a pattern for formal submission to the pattern-usingcommunity, you start by giving your new pattern a name, and then you canwrite about the pattern’s intent, motivation, applicability, and so on.

Introducing the Veto PatternHow’s creating a pattern work in practice? I take a look at the Missiles-N-Stuffproblem mentioned at the beginning of the chapter as an example, creating anew pattern here on the fly.

The programmers’ problem is that their code had gotten too unmanageable,and you (the brilliant design pattern expert) start thinking about it. You cometo the conclusion that they should encapsulate the components that need toapprove firing a missile. Encapsulating the components of the code that have

283Chapter 12: Ten Easy Steps to Create Your Own Patterns

18_798541 ch12.qxp 3/27/06 2:26 PM Page 283

Page 305: Design Patterns For Dummies

to approve a missile launch into their own objects means that they won’tinterfere with each other. The idea is that instead of a mass of interrelatedcode where who’s doing what isn’t clear, you now have a number of discrete,self-contained objects that all have to agree before the missile is launched.

Encapsulating each yes/no condition into its own object cleans up the code.And by connecting the objects into a chain, you can make sure that eachobject has its chance to say no if it wants to — to get a request approved,that request has to pass through the entire chain.

So you now have a discrete set of objects, all of which have to approve a mis-sile launch before it happens. And if any one of those objects says no, thelaunch doesn’t happen. In other words, any one of these objects can veto thelaunch, so let’s call this new pattern the Veto pattern — does that soundcatchy enough?

Alright, now that the pattern has a name, it’s time to fill in the ten topics thatyou need to enter this pattern into a pattern catalog, starting with the pat-tern’s intent.

1. IntentThe Intent design pattern catalog entry describes the pattern and what it’ssupposed to do. This is a short overview of the pattern that someone is sup-posed to be able to read and understand to know if the pattern solves herproblem.

So how does your new Veto pattern work? Each object has to approve anaction, such as a missile launch, before it can occur, so you can arrange theobjects into a chain. Each object becomes a mission-critical link in the chain,and each link has to approve a request before the request is approved over-all. Here’s how you might write the Intent of the Veto pattern:

“Process a veto-able request by sending it through a chain of encapsulatedobjects, each of which can veto that request.”

When you write the intent of a pattern, keep it simple, even if it means notincluding every little detail. This is an overview of your pattern, sort of likethe descriptions in TV Guide, that lets readers know if they’re going to beinterested in your pattern.

284 Part III: The Part of Tens

18_798541 ch12.qxp 3/27/06 2:26 PM Page 284

Page 306: Design Patterns For Dummies

2. MotivationThe Motivation section of a design pattern catalog entry lists a scenario thatdescribes the problem the pattern is supposed to solve, using a concrete scenario.

In this example, you might phrase that this way:

“Say you’re in charge of a missile-launch system, and that three separate mission-critical components must confirm a missile launch before it happens.If those components are part of a monolithic program, they can be interwovenin unexpected ways, and the result is that unclear code may launch missileswhen they shouldn’t be launched. For maximum clarity of action, separatethe components that will decide the missile launch and chain them as encap-sulated links, each one of which must agree to the launch in successionbefore it can occur.”

3. ApplicabilityThe Applicability section of a pattern’s catalog entry describes general sce-narios where a pattern can be applied. You usually provide a set of condi-tions — and if a problem meets those conditions, your pattern is a goodcandidate to solve it.

For example, for your new Veto pattern, you might say the following:

“If you have a situation where you have mission-critical components that mayconflict with one another when in the same piece of code, this pattern maybe a good one for you. If you don’t want to undertake an action unless severalwell-defined criteria are met, the Veto pattern may help.”

4. StructureThe Structure section of a pattern in a pattern catalog usually shows a dia-gram indicating how the pattern works. In the case of the Veto pattern, youwant to arrange the objects that can veto a request as links in a chain, eachof which has to approve before a particular action can be taken. You mightdraw the diagram for this pattern as shown in Figure 12-1.

285Chapter 12: Ten Easy Steps to Create Your Own Patterns

18_798541 ch12.qxp 3/27/06 2:26 PM Page 285

Page 307: Design Patterns For Dummies

As you can see, the idea here is that you send a request through all the linksin the object chain and if any one of the links vetoes the request, the requestis denied.

5. ParticipantsThe Participants section of a pattern’s catalog entry lists the classes andobjects that take part in the pattern, as well as their roles. To create the linkobjects in the veto chain, for instance, you might want to make sure they alluse the same methods — so you should have a Link interface. And youshould list the Link classes here that implement that interface, as well as the client code that attempts to send requests through the chain of links.

Here’s how you might list the participants in the Veto pattern:

� Link interface: Lists the methods you want each link in the veto chain toimplement.

� Link objects: Each link in the chain represents an object that can vetothe request being sent through the chain.

� Client code: The client code sends a request to the first link in the chain,which sends it on to the next link and so on, until the result is sent backto the client code.

Check for a veto

Processresults

Link 1

Link 2

Link 3Figure 12-1:

The Vetopattern inoverview.

286 Part III: The Part of Tens

18_798541 ch12.qxp 3/27/06 2:26 PM Page 286

Page 308: Design Patterns For Dummies

6. CollaborationsThe Collaborations section of a pattern’s catalog entry indicates how the par-ticipants (listed in the previous section) work together.

In the case of the Veto pattern, that might look something like this:

“You use the Link interface to specify the methods that each link in the vetochain must implement. After creating a chain of links, you send a requestfrom the client code to the first link, which passes the request on to the nextlink, which passes it on to the next link after that, and so on. The request ispassed in this way from link to link — if any link vetoes the request, all follow-ing links must pass that veto on to the client code. The last link passes theresults back to the client code. Because the request is passed in sequencefrom link to link, all links in the chain get the chance to veto the request ifneeded.”

7. ConsequencesThe Consequences section of a pattern’s catalog entry lists both the goodand bad effects of the pattern. Your pattern, being the most advanced andexcellent one the world has yet seen, may not have any apparent drawbacks,but think hard on this point — it wouldn’t be good if you steered someoneinto using your pattern if that pattern’s going to cause him or her problems.

For your new Veto pattern, you might say:

“The consequence of this pattern is that it allows you to encapsulate thevoting objects so that any object may make its decisions independently ofthe code in other objects, and any object may veto a request. You are alsoassured that each link in the object chain gets a chance to veto a requestbefore sending it on to the next object.

On the other hand, encapsulating all the decision-making components intodiscrete objects can be a problem because doing so can deny one objectneeded information from the rest of the objects. If that’s the case in yourimplementation, consider combining two or more link objects into one asneeded so that encapsulation won’t be violated.

Another potential problem comes when one object in the chain of objectsdoesn’t pass on a veto correctly. Because the objects are in a chain, you’redependent on the correct functioning of each link in the chain to get theproper results.”

287Chapter 12: Ten Easy Steps to Create Your Own Patterns

18_798541 ch12.qxp 3/27/06 2:26 PM Page 287

Page 309: Design Patterns For Dummies

8. Implementation/Sample CodeThe Implementation/Sample Code section of a pattern’s entry in a patterncatalog outlines the techniques you use when implementing this patternand/or sample code.

For the Veto design pattern, you might say something like this:

“When you want to check if a request will be accepted or vetoed, give eachlink (and the Link interface) a method that will be passed a Boolean value. Ifany link vetoes the request, that link should pass a value of false to the nextlink in the chain, and any such veto should be passed on by having each sub-sequent link in the chain pass on a value of false if it was passed a value offalse. The last link in the chain should be connected back to the client codeso that that code may receive the results of the accept/veto process.

Here’s some sample code that implements the new Veto pattern. Each link inthe chain can veto a request sent to it, and in this example, it’s simply passeda Boolean true/false value to a method named check that must be imple-mented by each link. Here’s what that method looks like in the Link interface:

public interface Link{public void check(boolean b);

}

To connect the links in a chain, you pass the next link in the chain to the cur-rent link’s constructor when you instantiate the current link. The followingcode shows what that looks like in the Link1 class, the first of the links inour chain, which implements the Link interface:

public class Link1 implements Link{Link next;

public Link1(Link n){next = n;

}...

}

If the link’s check method is passed a value of true, this link just passes thatvalue along to the next link in the chain.

288 Part III: The Part of Tens

18_798541 ch12.qxp 3/27/06 2:26 PM Page 288

Page 310: Design Patterns For Dummies

public class Link1 implements Link{Link next;

public Link1(Link n){next = n;

}

public void check(boolean b){if(b){next.check(true);...

}}

On the other hand, if the check method is passed a value of false, meaningsome link in the chain has already vetoed the request, this link should passon that veto by calling the next link’s check method with a value of false.

public class Link1 implements Link{Link next;

public Link1(Link n){next = n;

}

public void check(boolean b){if(b){next.check(true);

} else {next.check(false);

}}

}

The Link2 class also does the same.

public class Link2 implements Link{Link next;

public Link2(Link n){

289Chapter 12: Ten Easy Steps to Create Your Own Patterns

18_798541 ch12.qxp 3/27/06 2:26 PM Page 289

Page 311: Design Patterns For Dummies

next = n;}

public void check(boolean b){if(b){next.check(true);

} else {next.check(false);

}}

}

. . . as does the Link3 class.

public class Link3 implements Link{Link next;

public Link3(Link n){next = n;

}

public void check(boolean b){if(b){next.check(true);

} else {next.check(false);

}}

}

Use the client code, TestVeto.java, to test this out. This client code ispassed the results of the veto chain, which means that it should implementthe Link interface itself, allowing it to be passed to the last link in the chain.

public class TestVeto implements Link{

.

.

.}

Here’s how you form a chain of three links and connect them:

public class TestVeto implements Link{Link link1, link2, link3;

public static void main(String args[])

290 Part III: The Part of Tens

18_798541 ch12.qxp 3/27/06 2:26 PM Page 290

Page 312: Design Patterns For Dummies

{TestVeto t = new TestVeto();

}

public TestVeto(){link3 = new Link3(this);link2 = new Link2(link3);link1 = new Link1(link2);

}...

}

You’ve created the link of objects that can veto the request — all you need todo now is send that request through the link of objects, and this code doesthat with a method called getOK, which is called from the constructor, andwhich sends a value of true to the first link.

public class TestVeto implements Link{Link link1, link2, link3;

public static void main(String args[]){TestVeto t = new TestVeto();

}

public TestVeto(){link3 = new Link3(this);link2 = new Link2(link3);link1 = new Link1(link2);

getOK();}

public void getOK(){link1.check(true);

}...

}

The client is passed the results by the last link in the chain, which calls thecheck method of the client code. If the value passed to the check method is

291Chapter 12: Ten Easy Steps to Create Your Own Patterns

18_798541 ch12.qxp 3/27/06 2:26 PM Page 291

Page 313: Design Patterns For Dummies

true, the request is accepted — if the value is false, however, the requestis vetoed. Here’s how the client code indicates the results:

public class TestVeto implements Link{Link link1, link2, link3;

public static void main(String args[]){TestVeto t = new TestVeto();

}

public TestVeto(){link3 = new Link3(this);link2 = new Link2(link3);link1 = new Link1(link2);

getOK();}

public void getOK(){link1.check(true);

}

public void check(boolean b){if(b){System.out.println(“OK”);

} else {System.out.println(“Not OK”);

}}

}

When you run this test, the results show that the request is granted:

OK

Very nice.

9. Known UsesThe Known Uses section of a pattern’s catalog entry gives some real-worldexamples where the pattern has been used. In this case, you may have

292 Part III: The Part of Tens

18_798541 ch12.qxp 3/27/06 2:26 PM Page 292

Page 314: Design Patterns For Dummies

already put your Veto pattern to work in several applications and/or seen itin other applications. Or you may just have watched presidential vetoes onthe news. In any case, bear in mind the Rule of Three (see the sidebar earlierin the chapter) — you should have three real-world applications to list herein the Known Uses section.

10. Related PatternsFinally, the Related Patterns section lists other patterns that might be relatedto this one. For example, you might consider the Veto pattern to be a cousinof the GoF Chain of Responsibility pattern, where a request is sent down achain of objects until one of the objects handles the request. That’s similar toyour Veto pattern — it’s related but distinct (for one thing, requests have topass all the way through the object chain in the Veto pattern). So you mightlist that pattern in this section.

And that’s it. Congratulations — you’ve created your own new pattern. Allyou’ve got to do now is to submit your new pattern catalog entry to a designpatterns repository.

Getting Your Pattern into a Pattern Catalog

How do you tell people about your pattern? You list your pattern in a pattern catalog, which is then stored in a pattern repository, such as thePortland Pattern Repository, as hosted by Cunningham & Cunningham athttp://c2.com. (I cover some of the patterns supported by the PortlandPatterns Repository in Chapter 11.)

293Chapter 12: Ten Easy Steps to Create Your Own Patterns

18_798541 ch12.qxp 3/27/06 2:26 PM Page 293

Page 315: Design Patterns For Dummies

294 Part III: The Part of Tens

18_798541 ch12.qxp 3/27/06 2:26 PM Page 294

Page 316: Design Patterns For Dummies

• A •abstract class and Composite pattern,

193–194Abstract Factory pattern, 260–261abstraction

decoupling from implementation,262–263

description of, 19–20accessing elements inside object.

See Iterator patternAce class

methods, 121objects, creating, 123–124AceToAcmeAdapter class, 125–126Acme class

methods, 122objects, creating, 124–125AcmeInterface interface, 125–126Adapter classes (Java), 144Adapter patternAce object, creating, 123–124Ace-to-Acme object adapter, creating,

125–127Acme object, creating, 124–125connection problems and, 121–123description of, 11–12, 119inheriting class adapters, 128–134scenario for, 119–121testing adapter, 127–128add methodCorporate class, 193–194Division class, 182Vector class, 71addAssemble method, 162–163, 165

addGetParts method, 165adding new operation to structure of

objects, 266–268addObserver method, 84addStart method, 162–163, 165addStop method, 162–163, 165addTest method, 162–163, 165Alexander, Christopher (A Pattern

Language: Towns, Buildings,Construction), 282

algorithmadding hook to, 158–160client code and, 161–164creating, 29–30description of, 29redefining steps in, 150selecting at runtime, 33–35storing, 30using, 30–33ApartmentRentedState class, 221–222Applicability section of pattern

catalog, 285Application object, 89Archiver class, 74, 82array, collections and, 181ArrayList object

Builder pattern and, 166–167, 169Composite pattern and, 198–199iterators and, 188, 190AsiaServer class, 237assemble method, 146, 152automat proxy

creating, 228–230testing, 230–231

automat server, creating, 225–228

Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 295

Page 317: Design Patterns For Dummies

AutomatInterface interface, 214–218AutomatProxy class, 229AutomatServer class, 226–227AutomotiveRobot class, 153–154AutomotiveRobotBuilder object, 163

• B •Boss class, 75, 83Bridge pattern, 262–263BufferedInputStream object, 49BufferedReader object, 227Builder pattern

buildable robot, creating, 168–172client rules and, 161–164description of, 146, 161letting client build robot, 165–168Template Method pattern compared to,

161–162, 164testing, 172–175

button, creating, 69

• C •CD wrapper, 47Chain of Responsibility pattern

chainable objects, creating, 87–89description of, 66, 86–87help interface, creating, 87Help system, testing, 89–90loose coupling and, 77

chainable objects, creating, 87–89change, handling

composition and, 23–27databases and Observer pattern, 66–68design patterns and, 41“has-a” and, 27–28reusing parts of code and, 27–28, 52checkApplication method, 211Checkbox class, 130

CheckboxAdapter object, 132–133Checkboxes object, 131Circular Buffer pattern, 269–274class loader, multiple, using, 106classes

abstract, and Composite pattern,193–194

abstract Connection, creating, 54–55Ace, 121, 123–124AceToAcmeAdapter, 125–126Acme, 122, 124–125Adapter (Java), 144ApartmentRentedState, 221–222Archiver, 74, 82AsiaServer, 237AutomatProxy, 229AutomatServer, 226–227AutomotiveRobot, 153–154Boss, 75, 83Checkbox, 130Client, 74–75, 83Component, 275ComponentDecorator, 45–46Computer, 41, 45concrete Connection, creating, 55–56ConnectionFactory, 59, 60CookieHookRobot, 159–160CookieRobot, 154–155CookieRobotBuildable, 169–172CookieRobotBuilder, 162–163,

165–168Corporate, 193–194Database, 72, 76, 94, 95–96DatabaseThreaded.java, 103–104Decorator pattern and, 40, 43–44DifficultProduct, 137–140, 141Division, 181–183, 196–198DivisionIterator, 197–198EuroServer, 238final, 58

296 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 296

Page 318: Design Patterns For Dummies

FirstFactory, 53–54, 58FormulaOne, 24, 31FrontEnd, 88FullyRentedState, 222gotApplicationState, 220–221Graphics and Graphics2D, 95Helicopter, 25, 27, 32improving behavior of, 134interface between objects and, fixing,

121–123, 128–134IntermediateLayer, 89Invoker, 246–247Java file system, 49Java window, 156Jet, 25–26, 32JFrame, 156–157Mediator, 254MySqlConnection, 56Observable, 79–81, 84–85OracleConnection, 50, 55–56PipedInputStream andPipedOutputStream, 274

RealJet.java, 34–35RebootCommand, 241, 245RentalMethods, 209–213Robot, 146–148RobotHookTemplate, 158–159RobotTemplate, 152–153RunDiagnosticsCommand, 240, 246ScheduledThreadPoolExecutor, 278secure Connection, creating, 61–62SecureFactory, 60Shape, 20, 22ShutDownCommand, 239–240, 244SimpleProductFacade, 140–142single responsibility and, 179spreading out handling of changeable

task over generations of, 26SqlServerConnection, 56StartTheRace.java, 32

StreetRacer, 24, 31Student, 109–110StudentThreaded, 113–114testing, 48–50ThreadPoolExecutor, 278USServer, 238–239Vector, 71Vehicle, 23, 30–31VP, 180–181, 194–195VPIterator, 194–195WaitingState, 218–220XMLReaderFactory, 58Client class, 74–75, 83cloning object, 261–262code

closing for modification, 41–42extracting for specific task, 35–38opening for extension, 41–42reusing parts of to handle change,

27–28, 52segmenting into states, 209wrapper, 43

Collaborations section of patterncatalog, 287

Collection interface, 189–190collections. See also Composite pattern;

Iterator patternarray and, 181iterators and, 178Command interface, 239, 244Command pattern

commands, creating, 239–241description of, 234–236invoker, creating, 241–242receiver objects, creating, 236–239testing, 242–244undo method and, 244–249

compartmentalizing code, 209Component class, 275ComponentDecorator class, 45

297Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 297

Page 319: Design Patterns For Dummies

Composite patternabstract classes and, 193–194branches, creating, 196–198complex organization, building,

198–200description of, 178, 191–193leaves, creating, 194–196Node interface and, 203–206testing, 200–203

compositioninheritance compared to, 23–27object adapters and, 125Computer class, 41, 45connecting objects in chain of

notification. See Chain ofResponsibility pattern

connecting to remote object. See Proxypattern

Connection class, creatingabstract, 54–55concrete, 55–56secure, 61–62

connection problems, fixing. See Adapterpattern

ConnectionFactory class, 59, 60Consequences section of pattern

catalog, 287constructor

private, 95ServerSocket, 225, 228

controller, 278CookieHookRobot class, 159–160CookieRobot class, 154–155CookieRobotBuildable class, 169–172CookieRobotBuilder class, 162–163,

165–168copying object, 261–262Corporate class, 193–194createConnection method, 52, 53,

59, 60

createImage method, 275Crisis Center example

commands, creating, 239–241description of, 233–235encapsulation and, 235–236invoker, creating, 241–242receiver objects, creating, 236–239testing commands, 242–244toolkit, 235

• D •Database class

Observer pattern and, 72, 76Singleton pattern and, 94, 95–96testing Observable code and, 85

database connection object, building,50–52

Database objectcreating, 75–76Observable object and, 78update method and, 82DatabaseThreaded.java class,

103–104Decorator pattern

additional wrappers, adding, 47–48concrete wrapper, adding, 46–47core component, creating, 45decorator, creating, 45description of, 40, 42–44testing, 48–50

decoupling abstraction fromimplementation, 262–263

description method, 41–42, 43–45,46–47, 50

design pattern. See also specific patternscreating, 282description of, 1, 8finding, 8–9

298 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 298

Page 320: Design Patterns For Dummies

Design Patterns: Elements of ReusableObject-Oriented Software(GoF book, Gamma, Helm,Johnson, and Vlissides), 1, 9

DifficultProduct class, 137–140, 141

Disk wrapper, 46–47dispenseKeys method, 212, 221–222display method, 204–206Division class, 181–183, 196–198DivisionIterator class, 197–198document node, 203documents, different types of,

creating, 164Double Buffer pattern, 274–277draw method, 20drawGraphics method, 275–276drawImage method, 276

• E •editRecord methodDatabase class, 72, 76, 85, 94Observable class, 80

encapsulationof code components for Veto pattern,

283–284Command pattern and, 235–236description of, 20effective, 136global objects and, 107of interaction between objects,

250–251loose coupling and, 77using objects to encapsulate state,

213–218EuroServer class, 238

event listenerObserver pattern compared to, 68registering observer and, 14–15execute method, 236, 240, 241, 245Exit page, 254extending functionality of class and

Decorator pattern, 40extension, opening code for, 41–42extracting code for specific task, and

Strategy pattern, 35–38extracting generic template class from

existing object. See Flyweightpattern

• F •Facade pattern

description of, 119, 135–136difficult object, dealing with, 137–140Mediator pattern compared to, 251scenario for, 134–135simplifying facade, creating, 140–142testing facade, 143–144

Factory Method pattern. See alsoFactory pattern

deciding when to use, 58–59using, 59–63factory object

abstract Connection class, creating,54–55

abstract, creating, 59building, 52–54concrete Connection class, creating,

55–56concrete, creating, 60–61secure Connection class, creating,

61–62testing, 56–59, 62–63

factory of factories, creating, 260–261

299Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 299

Page 321: Design Patterns For Dummies

Factory pattern. See also FactoryMethod pattern; factory object

Builder pattern compared to, 164description of, 40formal GoF, 58–59new object and, 50–52XML parser class and, 9FilteredInputStream object, 49final class, 58finding design pattern, 8–9Finkelstein, Ellen (Jakarta Struts For

Dummies), 279FirstFactory class

creating, 53–54rewriting, 58

Flyweight patterndescription of, 106–109drawbacks to, 115Singleton pattern compared to, 93student, creating, 109–110testing, 110–112threading and, 112–115

forces, 282for/in statement, 190–191FormulaOne class, 24, 31FrontEnd class, 88FullyRentedState class, 222functionality of class, extending, and

Decorator pattern, 40, 43–44

• G •Gamma, Erich (Design Patterns: Elements

of Reusable Object-OrientedSoftware), 1, 9

Gang of Four (GoF) book, (DesignPatterns: Elements of Reusable Object-Oriented Software) (Gamma,Helm, Johnson, and Vlissides), 1, 9

getApplication method, 210–211

getCount method, 215getFirstName method, 122, 124–125,

126–127getHelp method, 87, 89, 90getInstance method

Flyweight pattern and, 113Singleton pattern and, 96, 97, 98stripping all object-creation code from,

103–106synchronized keyword and, 99–100synchronizing, 102getLastName method, 122, 124–125,

126–127getName methodAce class, 121, 123, 126AutomotiveRobot class, 154Database class, 94DifficultProduct class, 139, 142VP class, 180getParts method, 152getRobot method, 163, 165, 167getStanding method, 109–110getState method, 130–131getter methods, 81global object, as singleton, 107go here method, 147go method

algorithms and, 29, 31CookieRobotBuildable class, 169customizing inherited, 152–153Helicopter class, 27overriding, 26RobotBuildable interface, 168–169Vehicle class, 23GoAlgorithm interface, 29GoByDrivingAlgorithm interface,

29, 31, 34GoByFlyingAlgorithm interface,

29, 32, 33GoByFlyingFast interface, 30, 32

300 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 300

Page 322: Design Patterns For Dummies

GoF book (Design Patterns: Elements ofReusable Object-Oriented Software)(Gamma, Helm, Johnson, andVlissides), 1, 9

gotApplication method, 219gotApplicationState class, 220–221Graphics and Graphics2D classes, 95

• H •handle method, 254“has-a” relationship, 28hasNext method, 179–180, 183, 185head in circular buffer, 269Helicopter class, 25, 27, 32Helm, Richard (Design Patterns: Elements

of Reusable Object-Oriented Software),1, 9

help interface, creating, 87Help system, testing, 89–90hierarchy, part-whole. See Composite

patternhook

adding to algorithm, 158–160testing, 160–161

• I •Image object, 276implementation, decoupling abstraction

from, 262–263Implementation/Sample Code section of

pattern catalog, 288–292improving behavior of class or

object, 134inheritance

class adapters and, 128–134composition compared to, 23–27description of, 22–23as “is-a” relationship, 27–28

Strategy pattern and, 36template base class and, 150–151InputStream object, 49, 227instantiating one object. See Singleton

patternIntent section of pattern catalog, 284interfaceAcmeInterface, 125–126algorithm and, 29AutomatInterface, 214–218Collection, 189–190Command, 239, 244GoAlgorithm, 29GoByDrivingAlgorithm, 29, 31, 34GoByFlyingAlgorithm, 29, 32, 33GoByFlyingFast, 30, 32help, creating, 87ItemListener, 131java.util.Iterator, 179, 183–186Node, 203–206between objects and classes, fixing,

121–123, 128–134Observer, 70, 78, 82–83OOP, and Facade pattern, 135Receiver, 236–237RobotBuildable, 168–172RobotBuilder, 165simplifying with facade, 135–136Subject, 69–70IntermediateLayer class, 89Interpreter pattern, 264invoker

creating, 241–242description of, 236Invoker class, 246–247“is-a” relationship, 28isSelected method, 130–131, 133itemChanged method, 133ItemListener interface, 131iterator method, 193–194

301Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 301

Page 323: Design Patterns For Dummies

Iterator patternaccessing objects and, 179–181Composite pattern and, 193description of, 178–179for/in statement and, 190–191gathering objects into collection,

181–183iterating over objects, 186–190iterator, creating, 183–186

• J •Jakarta Struts, 278, 279Jakarta Struts For Dummies (Robinson

and Finkelstein), 279Java

Adapter classes, 144built-in template methods, 156–158circular buffer and, 274collections, 178double buffering, 274, 275facades and, 143file system classes, 49garbage collector, 106iterators, 188–190knowledge of, 2recycle bins, 278ServerSocket constructor, 225, 228single inheritance and, 129–130window, 156WindowAdapter, 144

Java All-In-One Desk Reference ForDummies (Doug Lowe), 40

Java Virtual Machine (JVM), 103JavaServer Pages, 278java.util.Iterator interface,

179, 183–186Jet class, 25–26, 32JFrame class, 156–157JFrame object, 131

Johnson, Ralph (Design Patterns: Elementsof Reusable Object-Oriented Software),1, 9

JVM (Java Virtual Machine), 103

• K •Known Uses section of pattern catalog,

292–293

• L •language, programming, putting together

own, 264Law of Demeter, 136listening for response from automat

proxy, 230loadActions method, 167, 169loose coupling

Facade pattern and, 136Mediator pattern and, 250–251Observer pattern and, 75, 77

Lowe, Doug (Java All-In-One DeskReference For Dummies), 40

• M •main method, 275Mediator class, 254Mediator pattern

connecting pages and, 254–255description of, 10–11, 234, 249–251Rutabagas-R-Us site, designing, 251–254Rutabagas-R-Us site, testing, 255–256

Memento pattern, 264–266memory and Circular Buffer pattern,

269–274methods. See also specific methodsAce class, 121Acme class, 122CookieRobotBuilder class, 166–167

302 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 302

Page 324: Design Patterns For Dummies

iterators and, 179Observable class, 79–80state objects and, 218–222using to hold state, 209–213

model, 278Model/View/Controller pattern, 278–279modification, closing code for, 41–42Monitor wrapper, 47–48Motivation section of pattern

catalog, 285multithreading, 93, 99–100MySqlConnection class, 56

• N •navigating Web site. See Mediator

patternnew object, 40, 50–52new operator

Flyweight pattern and, 112–113Singleton pattern and, 92, 94–95next method, 179–180, 183–184Node interface, 203–206notification, passing, 13–15, 78notifying objects, 86–87notifying observer. See Observer patternnotifyObservers methodObservable class, 78, 79–80Observer pattern and, 69, 70, 72–73

• O •object. See also factory object

accessing elements inside, 178adding new operation to structure of,

266–268Application, 89ArrayList, 166–167, 169, 188, 190,

198–199AutomotiveRobotBuilder, 163BufferedInputStream, 49

BufferedReader, 227chainable, creating, 87–89CheckboxAdapter, 132–133Checkboxes, 131cloning, 261–262composites of, 28copying and customizing, 261–262Database, 75–76, 78, 82database connection, building, 50–52description of, 18–19FilteredInputStream, 49global, as singleton, 107Image, 276improving behavior of, 134InputStream, 49, 227interface between classes and, fixing,

121–123, 128–134JFrame, 131mass producing, 145–148new, 40, 50–52notifying, 86–87PrintWriter, 225–227, 228–230receiver, 236–239registry, 93remote, connecting to, 12–13restoring state of, 264–266save-state, 264–266singleObject, 96–97state, and methods, 218–222traverser, 267–268using to encapsulate state, 213–218

object, packaging complex commandsinto single. See Command pattern

object-oriented programming (OOP)abstraction and, 19–20composition and, 23–27, 125encapsulation and, 20, 107extending, 18–19inheritance and, 22–23overview of, 9–10polymorphism and, 20–22

303Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 303

Page 325: Design Patterns For Dummies

Observable classaddObserver method, 84extending, 80–81, 85methods of, 79–80testing code, 84–85

observer, creating, 73–75Observer interface

building, 70description of, 78objects, creating, 82–83

Observer patterndescription of, 13–15, 66–68in Java, 69loose coupling and, 77observer, creating, 73–75observer interface, creating, 70subject, creating, 70–73subject interface, creating, 69–70testing, 75–77

one-to-many dependency and Observerpattern, 66

online development, 121OOP (object-oriented programming)

abstraction and, 19–20composition and, 23–27, 125encapsulation and, 20, 107extending, 18–19inheritance and, 22–23overview of, 9–10polymorphism and, 20–22

OOP interface and Facade pattern, 135OracleConnection class, 50, 55–56overridingpaint method, 156–158steps in algorithm, 150

• P •packaging complex commands into

single object. See Command patternpaint methodImage object and, 276JFrame class and, 156–158

parameterizing clients with differentrequests, 245

Parser.java code, 203–206parsing XML files, 203–206Participants section of pattern

catalog, 286passing notification. See Observer

patternpattern. See also specific patterns

creating, 282description of, 1, 8finding, 8–9

pattern catalogApplicability section, 285Collaborations section, 287Consequences section, 287Implementation/Sample Code section,

288–292Intent section, 284Known Uses section, 292–293listing pattern in, 293Motivation section, 285Participants section, 286Related Patterns section, 293Structure section, 285–286style, 283

A Pattern Language: Towns, Buildings,Construction (Alexander), 282

Patterns Library, 260PipedInputStream and

PipedOutputStream classes, 274planning for change, 27–28polymorphism, 20–22Portland Pattern Repository, 260, 293Principle of Least Knowledge, 136print method

Composite pattern and, 192Corporate class, 193–194, 199–200VP class, 180PrintWriter object, 225–227, 228–230private constructor, 95Prototype pattern, 261–262proxy, definition of, 13

304 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 304

Page 326: Design Patterns For Dummies

Proxy patternautomat proxy, creating, 228–230automat proxy, testing, 230–231automat server, creating, 225–228description of, 12–13, 208, 224–225

Purchase page, 253

• Q •queue of commands, 245

• R •reading item in circular buffer, 270, 272RealJet.java class, 34–35RebootCommand class, 241, 245Receiver interface, 236–237receiver object, 236–239Rectangle class, 21, 23Recycle Bin pattern, 277–278redefining steps in algorithm, 150registering

as observer, 71to receive notification, 67registerObserver methodDatabase class, 76Observer pattern, 69, 70–71

registry object, 93Related Patterns section of pattern

catalog, 293remote object, connecting to. See Proxy

patternremove method, 179–180, 183, 185–186removeObserver method, 70, 71removing object from vector, 71rental automat example

methods for state objects and,218–222

methods, using to hold state, 209–213state objects and, 213–218states of, 208–209testing, 223RentalMethods class, 209–213

rentApartment method, 212repaint method, 276restoring object state, 264–266restricting resource use, 93reusing parts of code to handle change,

27–28, 52ring buffer, 269Robinson, Mike (Jakarta Struts For

Dummies), 279Robot class, 146–148RobotBuildable interface, 168–172RobotBuilder interface, 165RobotHookTemplate class, 158–159RobotTemplate class, 152–153Rule of Three, 282run method, 241–242, 245RunDiagnosticsCommand class,

240, 246runtime, selecting algorithm at, 33–35Rutabagas-R-Us Inc. Web site example

designing, 251–254Mediator pattern and, 249–251testing, 255–256

• S •save-state object, 264–266ScheduledThreadPoolExecutor

class, 278secure Connection class, creating,

61–62SecureFactory class, 60selecting algorithm at runtime, 33–35sending test back and forth between

points on Internet. See Proxy patternseparating parts of code that change,

27–28, 52ServerSocket constructor, 225, 228setChanged method, 79setCommand method, 241–242setCount method, 215setFirstName method, 122, 124–125,

126–127

305Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 305

Page 327: Design Patterns For Dummies

setGoAlgorithm method, 30, 35setName methodAce class, 121, 123DifficultProduct class, 142Shape class, 20, 22sharing data in object, 93Shopping page, 252–253ShutDownCommand class, 239–240, 244SimpleProductFacade class, 140–142single responsibility, 179singleObject object, creating, 96–97Singleton pattern

alternatives to, 107database, creating, 94–97description of, 92–93Flyweight pattern compared to, 93multithreading and, 99–100pre-thread solution and, 104–106synchronized solution and, 100–102testing, 98–99threading and, 103–104SqlServerConnection class, 56start method, 146, 152StartTheRace.java class, 32State pattern

description of, 208–209methods, using to hold state, 209–213objects, using to encapsulate state,

213–218state objects, creating, 218–222testing, 223stop method, 152storing

algorithm, 30item in circular buffer, 269–270, 271

Strategy pattern, 35–38StreetRacer class, 24, 31structure of objects, adding new

operation to, 266–268Structure section of pattern catalog,

285–286Student class, 109–110

StudentThreaded class, 113–114subclasses

Factory pattern and, 58singleton and, 107

subject, creating, 70–73Subject interface, creating, 69–70synchronized keyword, 99–100

• T •tail in circular buffer, 269task, extracting code for specific, 35–38template class, generic, extracting from

existing object. See Flyweightpattern

Template Method patternBuilder pattern compared to,

161–162, 164built-in template methods in Java,

156–158description of, 146, 149–150hook, adding, 158–160robots, creating, 150–155testing hook method, 160–161testing robot creation, 155–156test method, 146, 152TestAdapter.java test harness,

127–128TestAutomat.java test harness, 223TestAutomatProxy.java test harness,

230–231TestCircularBuffer.java test

harness, 272–274TestCommands.java test harness,

242–244, 247–249TestConnection.java test harness,

56–59TestCorporation.java test harness,

200–203TestDivision.java test harness,

186–190

306 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 306

Page 328: Design Patterns For Dummies

TestFacade.java test harness,143–144

TestFactory.java test harness, 62–63TestFlyweight.java test harness,

110–112TestFlyweightThreaded.java test

harness, 114–115TestHookTemplate.java test

harness, 160testing

adapter, 127–128automat proxy, 230–231circular buffer, 272–274class, 48–50commands, 242–244Composite pattern, 200–203facade, 143–144factory object, 56–59, 62–63Flyweight pattern, 110–112Help system, 89–90hook method, 160–161iterator, 186–190Observable code, 84–85Observer pattern, 75–77rental automat, 223RentalMethods class, 213Robot class, 147robot creation, 155–156Rutabagas-R-Us site, 255–256Singleton pattern, 98–99undo method, 247–249Veto pattern, 290–292Test.java test harness, 48–50TestMediator.java test harness,

255–256TestObservable.java test harness,

84–85TestObserver.java test harness,

75–77testOK hook method, 158–160

TestRentalMethods.java testharness, 213

TestRobotBuilder.java test harness,172–175

TestSingleton.java test harness, 98TestSingletonSynchronized.java

test harness, 100–102TestSingletonThreaded.java test

harness, 104–105TestTemplate.java test harness,

155–156TestVeto.java test harness, 290–292text node, 203threading

Flyweight pattern and, 112–115Singleton pattern and, 99–100ThreadPoolExecutor class, 278traverser object, 267–268tree-like structures, creating, 178, 192

• U •undo method

Command pattern and, 236, 244–247testing, 247–249

unregistering, 68update methodArchiver class, 74Database object, 82Java window classes and, 156Observable class, 79–80Observer interface, 70, 78, 82

upgrading and Adapter pattern, 11–12USServer class, 238–239

• V •Vector class, 71vector, using, 70–71Vehicle class, 23, 30–31

307Index

19_798541 bindex.qxp 3/27/06 2:26 PM Page 307

Page 329: Design Patterns For Dummies

Veto pattern exampleApplicability section, 285Collaborations section, 287Consequences section, 287description of, 283–284Implementation/Sample Code section,

288–292intent, 284Known Uses section, 292–293motivation, 285Participants section, 286Related Patterns section, 293Structure section, 285–286testing, 290–292

view, 278Visitor pattern, 266–268Vlissides, John (Design Patterns: Elements

of Reusable Object-Oriented Software),1, 9

VP class, 180–181, 194–195VPIterator class, 194–195

• W •WaitingState class, 218–220Web site. See also Mediator pattern

Jakarta Struts, 279Patterns Library, 260Portland Pattern Repository, 293

Welcome page, 251–252, 256WindowAdapter (Java), 144wrapper code, 43, 46–48. See also Facade

pattern

• X •XML element, 203XML nodes, 203XML parser class, 9XMLReaderFactory class, 58

308 Design Patterns For Dummies

19_798541 bindex.qxp 3/27/06 2:26 PM Page 308

Page 330: Design Patterns For Dummies

Notes____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

19_798541 bindex.qxp 3/27/06 2:26 PM Page 309

Page 331: Design Patterns For Dummies

Notes____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

19_798541 bindex.qxp 3/27/06 2:26 PM Page 310

Page 332: Design Patterns For Dummies

Notes____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

19_798541 bindex.qxp 3/27/06 2:26 PM Page 311

Page 333: Design Patterns For Dummies

Notes____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

19_798541 bindex.qxp 3/27/06 2:26 PM Page 312

Page 334: Design Patterns For Dummies

Notes____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

19_798541 bindex.qxp 3/27/06 2:26 PM Page 313

Page 335: Design Patterns For Dummies

Notes____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

19_798541 bindex.qxp 3/27/06 2:26 PM Page 314

Page 336: Design Patterns For Dummies

BUSINESS, CAREERS & PERSONAL FINANCE

Also available:�Accounting For Dummies †

0-7645-5314-3�Business Plans Kit For Dummies †

0-7645-5365-8�Cover Letters For Dummies

0-7645-5224-4�Frugal Living For Dummies

0-7645-5403-4�Leadership For Dummies

0-7645-5176-0�Managing For Dummies

0-7645-1771-6

�Marketing For Dummies0-7645-5600-2

�Personal Finance For Dummies *0-7645-2590-5

�Project Management For Dummies 0-7645-5283-X

�Resumes For Dummies †0-7645-5471-9

�Selling For Dummies0-7645-5363-1

�Small Business Kit For Dummies *†

0-7645-5093-4

Also available:�Bass Guitar For Dummies

0-7645-2487-9�Diabetes Cookbook For Dummies

0-7645-5230-9�Gardening For Dummies *

0-7645-5130-2�Guitar For Dummies

0-7645-5106-X�Holiday Decorating For Dummies

0-7645-2570-0�Home Improvement All-in-One

For Dummies 0-7645-5680-0

�Knitting For Dummies0-7645-5395-X

�Piano For Dummies0-7645-5105-1

�Puppies For Dummies0-7645-5255-4

�Scrapbooking For Dummies 0-7645-7208-3

�Senior Dogs For Dummies0-7645-5818-8

�Singing For Dummies0-7645-2475-5

�30-Minute Meals For Dummies0-7645-2589-1

FOOD, HOME, GARDEN, HOBBIES, MUSIC & PETS

0-7645-5307-0 0-7645-5331-3 *†

0-7645-5295-3 0-7645-5232-5

Available wherever books are sold. For more information or to order direct: U.S. customers visit www.dummies.com or call 1-877-762-2974.U.K. customers visit www.wileyeurope.com or call 0800 243407. Canadian customers visit www.wiley.ca or call 1-800-567-4797.

HOME & BUSINESS COMPUTER BASICS

Also available:�ACT! 6 For Dummies

0-7645-2645-6�iLife ‘04 All-in-One Desk Reference

For Dummies0-7645-7347-0

�iPAQ For Dummies0-7645-6769-1

�Mac OS X Panther TimesavingTechniques For Dummies0-7645-5812-9

�Macs For Dummies0-7645-5656-8

�Microsoft Money 2004 For Dummies0-7645-4195-1

�Office 2003 All-in-One Desk ReferenceFor Dummies0-7645-3883-7

�Outlook 2003 For Dummies0-7645-3759-8

�PCs For Dummies0-7645-4074-2

�TiVo For Dummies0-7645-6923-6

�Upgrading and Fixing PCs For Dummies0-7645-1665-5

�Windows XP Timesaving Techniques For Dummies0-7645-3748-2

0-7645-4074-2 0-7645-3758-X

Also available:�2005 Online Shopping Directory

For Dummies0-7645-7495-7

�CD & DVD Recording For Dummies0-7645-5956-7

�eBay For Dummies0-7645-5654-1

�Fighting Spam For Dummies0-7645-5965-6

�Genealogy Online For Dummies0-7645-5964-8

�Google For Dummies0-7645-4420-9

�Home Recording For Musicians For Dummies0-7645-1634-5

�The Internet For Dummies0-7645-4173-0

�iPod & iTunes For Dummies0-7645-7772-7

�Preventing Identity Theft For Dummies0-7645-7336-5

�Pro Tools All-in-One Desk Reference For Dummies0-7645-5714-9

�Roxio Easy Media Creator For Dummies0-7645-7131-1

INTERNET & DIGITAL MEDIA

0-7645-1664-7 0-7645-6924-4

* Separate Canadian edition also available† Separate U.K. edition also available

20_798541 bob.qxp 3/27/06 2:27 PM Page 315

Page 337: Design Patterns For Dummies

Also available:�Adobe Acrobat 6 PDF For Dummies

0-7645-3760-1�Building a Web Site For Dummies

0-7645-7144-3�Dreamweaver MX 2004 For Dummies

0-7645-4342-3�FrontPage 2003 For Dummies

0-7645-3882-9�HTML 4 For Dummies

0-7645-1995-6�Illustrator CS For Dummies

0-7645-4084-X

�Macromedia Flash MX 2004 For Dummies0-7645-4358-X

�Photoshop 7 All-in-One DeskReference For Dummies0-7645-1667-1

�Photoshop CS Timesaving TechniquesFor Dummies0-7645-6782-9

�PHP 5 For Dummies0-7645-4166-8

�PowerPoint 2003 For Dummies0-7645-3908-6

�QuarkXPress 6 For Dummies0-7645-2593-X

SPORTS, FITNESS, PARENTING, RELIGION & SPIRITUALITY

Also available:�Adoption For Dummies

0-7645-5488-3�Basketball For Dummies

0-7645-5248-1�The Bible For Dummies

0-7645-5296-1�Buddhism For Dummies

0-7645-5359-3�Catholicism For Dummies

0-7645-5391-7�Hockey For Dummies

0-7645-5228-7

�Judaism For Dummies0-7645-5299-6

�Martial Arts For Dummies0-7645-5358-5

�Pilates For Dummies0-7645-5397-6

�Religion For Dummies0-7645-5264-3

�Teaching Kids to Read For Dummies0-7645-4043-2

�Weight Training For Dummies0-7645-5168-X

�Yoga For Dummies0-7645-5117-5

Also available:�Alaska For Dummies

0-7645-1761-9�Arizona For Dummies

0-7645-6938-4�Cancún and the Yucatán For Dummies

0-7645-2437-2�Cruise Vacations For Dummies

0-7645-6941-4�Europe For Dummies

0-7645-5456-5�Ireland For Dummies

0-7645-5455-7

�Las Vegas For Dummies0-7645-5448-4

�London For Dummies0-7645-4277-X

�New York City For Dummies 0-7645-6945-7

�Paris For Dummies0-7645-5494-8

�RV Vacations For Dummies0-7645-5443-3

�Walt Disney World & Orlando For Dummies 0-7645-6943-0

TRAVEL

GRAPHICS, DESIGN & WEB DEVELOPMENT

0-7645-5146-9 0-7645-5418-2

0-7645-5438-7 0-7645-5453-0

0-7645-4345-8 0-7645-5589-8

Also available:�A+ Certification For Dummies

0-7645-4187-0�Access 2003 All-in-One Desk

Reference For Dummies0-7645-3988-4

�Beginning Programming For Dummies0-7645-4997-9

�C For Dummies0-7645-7068-4

�Firewalls For Dummies0-7645-4048-3

�Home Networking For Dummies0-7645-42796

�Network Security For Dummies0-7645-1679-5

�Networking For Dummies0-7645-1677-9

�TCP/IP For Dummies0-7645-1760-0

�VBA For Dummies0-7645-3989-2

�Wireless All In-One Desk Reference For Dummies0-7645-7496-5

�Wireless Home Networking For Dummies0-7645-3910-8

NETWORKING, SECURITY, PROGRAMMING & DATABASES

0-7645-6852-3 0-7645-5784-X

20_798541 bob.qxp 3/27/06 2:27 PM Page 316

Page 338: Design Patterns For Dummies

Available wherever books are sold. For more information or to order direct: U.S. customers visit www.dummies.com or call 1-877-762-2974.U.K. customers visit www.wileyeurope.com or call 0800 243407. Canadian customers visit www.wiley.ca or call 1-800-567-4797.

Get smart @ dummies.com®

• Find a full list of Dummies titles

• Look into loads of FREE on-site articles

• Sign up for FREE eTips e-mailed to you weekly

• See what other products carry the Dummies name

• Shop directly from the Dummies bookstore

• Enter to win new prizes every month!

Also available:�Alzheimer’s For Dummies

0-7645-3899-3�Asthma For Dummies

0-7645-4233-8�Controlling Cholesterol For Dummies

0-7645-5440-9�Depression For Dummies

0-7645-3900-0�Dieting For Dummies

0-7645-4149-8�Fertility For Dummies

0-7645-2549-2

�Fibromyalgia For Dummies0-7645-5441-7

�Improving Your Memory For Dummies0-7645-5435-2

�Pregnancy For Dummies †0-7645-4483-7

�Quitting Smoking For Dummies0-7645-2629-4

�Relationships For Dummies0-7645-5384-4

�Thyroid For Dummies0-7645-5385-2

HEALTH & SELF-HELP

0-7645-6820-5 *† 0-7645-2566-2

Also available:�Algebra For Dummies

0-7645-5325-9�British History For Dummies

0-7645-7021-8�Calculus For Dummies

0-7645-2498-4�English Grammar For Dummies

0-7645-5322-4�Forensics For Dummies

0-7645-5580-4�The GMAT For Dummies

0-7645-5251-1�Inglés Para Dummies

0-7645-5427-1

�Italian For Dummies0-7645-5196-5

�Latin For Dummies0-7645-5431-X

�Lewis & Clark For Dummies0-7645-2545-X

�Research Papers For Dummies0-7645-5426-3

�The SAT I For Dummies 0-7645-7193-1

�Science Fair Projects For Dummies0-7645-5460-3

�U.S. History For Dummies0-7645-5249-X

EDUCATION, HISTORY, REFERENCE & TEST PREPARATION

0-7645-5194-9 0-7645-4186-2

* Separate Canadian edition also available† Separate U.K. edition also available

20_798541 bob.qxp 3/27/06 2:27 PM Page 317

Page 339: Design Patterns For Dummies

Check out the Dummies Specialty Shop at www.dummies.com for more information!

Do More with Dummies

Products for the Rest of Us!

From hobbies to health,discover a wide

variety of fun products

DVDs/Videos • Music CDs • GamesConsumer Electronics • Software

Craft Kits • Culinary Kits • and More!

20_798541 bob.qxp 3/27/06 2:27 PM Page 318