Applied Design Patterns with Java

Behavioral :: Chain of Responsibility (223) {C ch 16}

Intent
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

Motivation

In a context-sensitive help facility for a GUI, the user can obtain help information on any part of the interface just by clicking on it. The help that's provided depends on the part of the interface that's selected and its context; a button widget in a dialog box might have different help information than a similar button in the main window. If no specific help information exists for that part of the interface, then the help system should display a more general help message about the immediate context—the dialog box as a whole.

It's natural to organize help information according to its generality—from the most specific to the most general. A help request is handled by one of several user interface objects; which one depends on the context and how specific the available help is. The problem is that the object that ultimately provides the help isn't known explicitly to the object (e.g., the button) that initiates the help request. There is a need to decouple the button that initiates the help request from the objects that might provide help information. The
Chain of Responsibility pattern defines how that happens. The idea of this pattern is to decouple senders and receivers by giving multiple objects a chance to handle a request. The request gets passed along a chain of objects until one of them handles it.

The first object in the chain receives the request and either handles it or forwards it to the next candidate on the chain, etc. The object that made the request has no explicit knowledge of who will handle it—so the request has an implicit receiver. Assume the user clicks for help on a button widget marked "Print." The button is contained in an instance of PrintDialog, which knows the application object it belongs to. The following interaction diagram illustrates how the help request gets forwarded along the chain:

Neither aPrintButton nor aPrintDialog handles the request; it stops at anApplication, which can handle it or ignore it. The client that issued the request has no direct reference to the object that ultimately fulfills it. To forward the request along the chain, and to ensure receivers remain implicit, each object on the chain shares a common interface for handling requests and for accessing its successor on the chain. The help system might define a HelpHandler class with a corresponding HandleHelp operation. HelpHandler can be the parent class for candidate object classes, or it can be defined as a mix-in class. Then classes that want to handle help requests can make HelpHandler a parent:

The Button, Dialog, and Application classes use HelpHandler operations to handle help requests. HelpHandler's HandleHelp operation forwards the request to the successor by default. Subclasses can override this operation to provide help under the right circumstances; otherwise they can use the default implementation to forward the request.

Catalog Behavioral Prev Next