0% found this document useful (0 votes)
15 views

Chain of Responsibility

Uploaded by

mashate ayoub
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Chain of Responsibility

Uploaded by

mashate ayoub
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

permissions must have full access to all orders.

After a bit of planning, you realized that these checks must be performed sequentially. The
  
application can attempt to authenticate a user to the system whenever it receives a request
that contains the user’s credentials. However, if those credentials aren’t correct and
authentication fails, there’s no reason to proceed with any other checks.
 / Design Patterns / Behavioral Patterns

Chain of Responsibility
Also known as: CoR, Chain of Command

 Intent
Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain
of handlers. Upon receiving a request, each handler decides either to process the request or to
pass it to the next handler in the chain.
The request must pass a series of checks before the ordering system itself can handle it.

During the next few months, you implemented several more of those sequential checks.

One of your colleagues suggested that it’s unsafe to pass raw data straight to the ordering
system. So you added an extra validation step to sanitize the data in a request.

Later, somebody noticed that the system is vulnerable to brute force password cracking. To
negate this, you promptly added a check that filters repeated failed requests coming from
the same IP address.

Someone else suggested that you could speed up the system by returning cached results on
repeated requests containing the same data. Hence, you added another check which lets the
request pass through to the system only if there’s no suitable cached response.

 Problem
Imagine that you’re working on an online ordering system. You want to restrict access to the
system so only authenticated users can create orders. Also, users who have administrative
In our example with ordering systems, a handler performs the processing and then decides
whether to pass the request further down the chain. Assuming the request contains the right
data, all the handlers can execute their primary behavior, whether it’s authentication checks or
caching.

Handlers are lined up one by one, forming a chain.

The bigger the code grew, the messier it became. However, there’s a slightly different approach (and it’s a bit more canonical) in which, upon
receiving a request, a handler decides whether it can process it. If it can, it doesn’t pass the
request any further. So it’s either only one handler that processes the request or none at all. This
The code of the checks, which had already looked like a mess, became more and more bloated approach is very common when dealing with events in stacks of elements within a graphical
as you added each new feature. Changing one check sometimes affected the others. Worst of all, user interface.
when you tried to reuse the checks to protect other components of the system, you had to
duplicate some of the code since those components required some of the checks, but not all of For instance, when a user clicks a button, the event propagates through the chain of GUI
them. elements that starts with the button, goes along its containers (like forms or panels), and ends
up with the main application window. The event is processed by the first element in the chain
The system became very hard to comprehend and expensive to maintain. You struggled with the that’s capable of handling it. This example is also noteworthy because it shows that a chain can
code for a while, until one day you decided to refactor the whole thing. always be extracted from an object tree.

 Solution
Like many other behavioral design patterns, the Chain of Responsibility relies on transforming
particular behaviors into stand-alone objects called handlers. In our case, each check should be
extracted to its own class with a single method that performs the check. The request, along
with its data, is passed to this method as an argument.

The pattern suggests that you link these handlers into a chain. Each linked handler has a field
for storing a reference to the next handler in the chain. In addition to processing a request,
handlers pass the request further along the chain. The request travels along the chain until all
handlers have had a chance to process it.

Here’s the best part: a handler can decide not to pass the request further down the chain and
A chain can be formed from a branch of an object tree.
effectively stop any further processing.
It’s crucial that all handler classes implement the same interface. Each concrete handler should  Structure
only care about the following one having the execute method. This way you can compose
chains at runtime, using various handlers without coupling your code to their concrete classes.

 Real-World Analogy

A call to tech support can go through multiple operators.

1. The Handler declares the interface, common for all concrete handlers. It usually contains just
You’ve just bought and installed a new piece of hardware on your computer. Since you’re a geek, a single method for handling requests, but sometimes it may also have another method for
the computer has several operating systems installed. You try to boot all of them to see whether setting the next handler on the chain.
the hardware is supported. Windows detects and enables the hardware automatically. However,
your beloved Linux refuses to work with the new hardware. With a small flicker of hope, you 2. The Base Handler is an optional class where you can put the boilerplate code that’s common
decide to call the tech-support phone number written on the box. to all handler classes.

The first thing you hear is the robotic voice of the autoresponder. It suggests nine popular Usually, this class defines a field for storing a reference to the next handler. The clients can
solutions to various problems, none of which are relevant to your case. After a while, the robot build a chain by passing a handler to the constructor or setter of the previous handler. The
connects you to a live operator. class may also implement the default handling behavior: it can pass execution to the next
handler after checking for its existence.
Alas, the operator isn’t able to suggest anything specific either. He keeps quoting lengthy
excerpts from the manual, refusing to listen to your comments. After hearing the phrase “have 3. Concrete Handlers contain the actual code for processing requests. Upon receiving a request,
you tried turning the computer off and on again?” for the 10th time, you demand to be each handler must decide whether to process it and, additionally, whether to pass it along
connected to a proper engineer. the chain.

Eventually, the operator passes your call to one of the engineers, who had probably longed for a Handlers are usually self-contained and immutable, accepting all necessary data just once
live human chat for hours as he sat in his lonely server room in the dark basement of some via the constructor.
office building. The engineer tells you where to download proper drivers for your new hardware
and how to install them on Linux. Finally, the solution! You end the call, bursting with joy.
4. The Client may compose chains just once or compose them dynamically, depending on the A simple component can show brief contextual tooltips, as long as the component has some
application’s logic. Note that a request can be sent to any handler in the chain—it doesn’t help text assigned. But more complex components define their own way of showing contextual
have to be the first one. help, such as showing an excerpt from the manual or opening a page in a browser.

 Pseudocode
In this example, the Chain of Responsibility pattern is responsible for displaying contextual help
information for active GUI elements.

That’s how a help request traverses GUI objects.

When a user points the mouse cursor at an element and presses the F1 key, the application
detects the component under the pointer and sends it a help request. The request bubbles up
through all the element’s containers until it reaches the element that’s capable of displaying
the help information.

// The handler interface declares a method for executing a


// request.
interface ComponentWithContextualHelp is
method showHelp()

// The base class for simple components.


abstract class Component implements ComponentWithContextualHelp is
field tooltipText: string

The GUI classes are built with the Composite pattern. Each element is linked to its container element. At any // The component's container acts as the next link in the
point, you can build a chain of elements that starts with the element itself and goes through all of its // chain of handlers.
container elements. protected field container: Container

// The component shows a tooltip if there's help text


// assigned to it. Otherwise it forwards the call to the
The application’s GUI is usually structured as an object tree. For example, the Dialog class, // container, if it exists.
which renders the main window of the app, would be the root of the object tree. The dialog method showHelp() is
contains Panels , which might contain other panels or simple low-level elements like Buttons if (tooltipText != null)

and TextFields . // Show tooltip.


else panel.modalHelpText = "This panel does..."
container.showHelp() ok = new Button(250, 760, 50, 20, "OK")
ok.tooltipText = "This is an OK button that..."
cancel = new Button(320, 760, 50, 20, "Cancel")
// Containers can contain both simple components and other // ...
// containers as children. The chain relationships are panel.add(ok)
// established here. The class inherits showHelp behavior from panel.add(cancel)
// its parent. dialog.add(panel)
abstract class Container extends Component is
protected field children: array of Component // Imagine what happens here.
method onF1KeyPress() is
method add(child) is component = this.getComponentAtMouseCoords()
children.add(child) component.showHelp()
child.container = this

 Applicability
// Primitive components may be fine with default help
// implementation...
class Button extends Component is
// ...  Use the Chain of Responsibility pattern when your program is expected to process different
kinds of requests in various ways, but the exact types of requests and their sequences are
// But complex components may override the default
unknown beforehand.
// implementation. If the help text can't be provided in a new
// way, the component can always call the base implementation
// (see Component class).  The pattern lets you link several handlers into one chain and, upon receiving a request, “ask”
class Panel extends Container is each handler whether it can process it. This way all handlers get a chance to process the
field modalHelpText: string
request.

method showHelp() is
if (modalHelpText != null)
// Show a modal window with the help text.
 Use the pattern when it’s essential to execute several handlers in a particular order.
else
super.showHelp()
 Since you can link the handlers in the chain in any order, all requests will get through the
// ...same as above... chain exactly as you planned.
class Dialog extends Container is
field wikiPageURL: string

method showHelp() is  Use the CoR pattern when the set of handlers and their order are supposed to change at
if (wikiPageURL != null) runtime.
// Open the wiki help page.
else
super.showHelp()
 If you provide setters for a reference field inside the handler classes, you’ll be able to insert,
remove or reorder handlers dynamically.

// Client code.

 How to Implement
class Application is
// Every application configures the chain differently.
method createUI() is
dialog = new Dialog("Budget Reports") 1. Declare the handler interface and describe the signature of a method for handling requests.
dialog.wikiPageURL = "http://..."
panel = new Panel(0, 0, 400, 800)
Decide how the client will pass the request data into the method. The most flexible way is to from classes that perform operations.
convert the request into an object and pass it to the handling method as an argument.  Open/Closed Principle. You can introduce
new handlers into the app without
2. To eliminate duplicate boilerplate code in concrete handlers, it might be worth creating an breaking the existing client code.
abstract base handler class, derived from the handler interface.

This class should have a field for storing a reference to the next handler in the chain.
Consider making the class immutable. However, if you plan to modify chains at runtime, you
 Relations with Other Patterns
need to define a setter for altering the value of the reference field.
Chain of Responsibility, Command, Mediator and Observer address various ways of
connecting senders and receivers of requests:
You can also implement the convenient default behavior for the handling method, which is
to forward the request to the next object unless there’s none left. Concrete handlers will be
able to use this behavior by calling the parent method.
Chain of Responsibility passes a request sequentially along a dynamic chain of potential
receivers until one of them handles it.

3. One by one create concrete handler subclasses and implement their handling methods. Each Command establishes unidirectional connections between senders and receivers.
handler should make two decisions when receiving a request: Mediator eliminates direct connections between senders and receivers, forcing them to
communicate indirectly via a mediator object.
Whether it’ll process the request.
Observer lets receivers dynamically subscribe to and unsubscribe from receiving requests.
Whether it’ll pass the request along the chain.
Chain of Responsibility is often used in conjunction with Composite. In this case, when a leaf
4. The client may either assemble chains on its own or receive pre-built chains from other component gets a request, it may pass it through the chain of all of the parent components
objects. In the latter case, you must implement some factory classes to build chains down to the root of the object tree.
according to the configuration or environment settings.
Handlers in Chain of Responsibility can be implemented as Commands. In this case, you can
5. The client may trigger any handler in the chain, not just the first one. The request will be execute a lot of different operations over the same context object, represented by a request.
passed along the chain until some handler refuses to pass it further or until it reaches the
end of the chain. However, there’s another approach, where the request itself is a Command object. In this
case, you can execute the same operation in a series of different contexts linked into a chain.
6. Due to the dynamic nature of the chain, the client should be ready to handle the following
scenarios: Chain of Responsibility and Decorator have very similar class structures. Both patterns rely
on recursive composition to pass the execution through a series of objects. However, there
The chain may consist of a single link. are several crucial differences.
Some requests may not reach the end of the chain.
The CoR handlers can execute arbitrary operations independently of each other. They can
Others may reach the end of the chain unhandled.
also stop passing the request further at any point. On the other hand, various Decorators can
extend the object’s behavior while keeping it consistent with the base interface. In addition,
decorators aren’t allowed to break the flow of the request.
 Pros and Cons
 You can control the order of request  Some requests may end up unhandled.
handling.
 Code Examples
 Single Responsibility Principle. You can
decouple classes that invoke operations

You might also like