Why would I ever use a Chain of Responsibility over a Decorator?

OopDesign PatternsDecoratorChain of-Responsibility

Oop Problem Overview


I'm just reading up on the Chain of Responsibility pattern and I'm having trouble imagining a scenario when I would prefer its use over that of decorator.

What do you think? Does CoR have a niche use?

Oop Solutions


Solution 1 - Oop

The fact that you can break the chain at any point differentiates the Chain of Responsibility pattern from the Decorator pattern. Decorators can be thought of as executing all at once without any interaction with the other decorators. Links in a chain can be thought of as executing one at a time, because they each depend on the previous link.

Use the Chain of Responsibility pattern when you can conceptualize your program as a chain made up of links, where each link can either handle a request or pass it up the chain.

When I used to work with the Win32 API, I would sometimes need to use the hooking functionality it provides. Hooking a Windows message roughly follows the Chain of Responsibility pattern. When you hooked a message such as WM_MOUSEMOVE, your callback function would be called. Think of the callback function as the last link in the chain. Each link in the chain can decide whether to throw away the WM_MOUSEMOVE message or pass it up the chain to the next link.

If the Decorator pattern had been used in that example, you would have been notified of the WM_MOUSEMOVE message, but you would be powerless to prevent other hooks from handling it as well.

Another place the Chain of Command pattern is used is in game engines. Again, you can hook engine functions, events, and other things. In the case of a game engine, you don't want to simply add functionality. You want to add functionality and prevent the game engine from performing its default action.

Solution 2 - Oop

Chain

> 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.

vs

Decorator

> Attach additional responsibilities to > an object dynamically. Decorators > provide a flexible alternative to > subclassing for extending > functionality.

I'd say its around the order in which things will happen. If you chain them, the will be called along the chain. With a decorator you're not guaranteed this order, only that additional responsibilities can be attached.

Solution 3 - Oop

I'd say that a Chain of Responsibility is a particular form of Decorator.

Solution 4 - Oop

Decorator is used when you want to add functionality to an object.

COR is used when one of many actors might take action on an object.

A particular Decorator is called to take an action, based on the type; while COR passes the object along a defined chain until one of the actors decides the action is complete.

COR might be used when there are multiple levels of escalation to different handlers -- for instance, a call center where the customer's value to the company determines if the call goes to a particular level of support.

Solution 5 - Oop

Well I can think of 2 situations:

  • You don't have a core object, i.e. you don't know what to do with the request after it passed all the layers/filters. (something like an aspect like interceptor chains that don't really care where the request ends).
  • You need to selectively apply some pre or post processing to the request. Not in a general enhancement form as the decorator does. i.e. Filters may or maynot handle a specific request but adding a decorator always enhances your object with some functionality.

Can't think of any more right now, would love to hear more in this topic.

Solution 6 - Oop

I agree that from structural standpoint this two patterns are very similar. My thought is about the final behavior:

In the classic interpretation of CoR element which handles the request breaks the chain.

If any element in decorator breaks the chain then it will be wrong implementation of decorator, because base part of behavior will be lost. And the idea of decorator is transparent addition of new behavior when the base behavior remains untouched.

Solution 7 - Oop

Decorator

  1. Decorator pattern allows behaviour to be added to an individual object dynamically.

  2. It provides a flexible alternative to sub classing for extending functionality. Even though it uses inheritance, it inherit from Lowest Common Denominator ( LCD ) interface.

UML diagram for Decorator

UML diagram for Decorator

Consequences:

  1. With decoration it is also possible to remove the added functionalities dynamically.
  2. Decoration adds functionality to objects at runtime which would make debugging system functionality harder.

Useful links:

https://stackoverflow.com/questions/1549743/when-to-use-the-decorator-pattern/37504043#37504043

Decorator_pattern from wikipedia

decorator from sourcemaking

Chain of responsibility:

> Chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain

UML Diagram

enter image description here

This pattern is more effective when:

  1. More than one object can handle a command
  2. The handler is not known in advance
  3. The handler should be determined automatically
  4. It’s wished that the request is addressed to a group of objects without explicitly specifying its receiver
  5. The group of objects that may handle the command must be specified in a dynamic way

Useful links:

Chain-of-responsibility_pattern from wikipedia

chain-of-responsibility-pattern from oodesign

chain_of_responsibility from sourcemaking

Real world example : In a company, a designated role have particular limits to process purchase request. If person with a designated role does not have enough power to approve purchase bill, he will forward the command/request to his successor, who have more power. This chain will continue until the command is processed.

Solution 8 - Oop

  1. keyword 'extends' - static extension.
  2. Decorator pattern - dynamic extension.
  3. Chain Of Responsibility pattern - just processing of a command object with a set of processing objects and those objects don't know each other.

Solution 9 - Oop

After reading the Gang of Four definitions, I'm not convinced there's a real difference. (included for convenience)

  • Decorator: Allows for the dynamic wrapping of objects in order to modify their existing responsibilities and behaviours
  • Chain of Responsibility: Gives more than one object an opportunity to handle a request by linking receiving objects together

Wikipedia fleshes them out a little, but some of it's kinda arbitrary.

  • Decorator is typically implemented as a Linked List. But I think that's too low-level to be considered "part" of the pattern.
  • Chain of Responsibility links only handle data if it's their responsibility; but determining responsibility and data handling are both part of behavior. Decorators can do this just as easily.
  • Decorator requires you to call the delegate.
  • A "pure" CoR link should only call the delegate if it doesn't handle the data.

The first two attributes don't really distinguish the patterns. The second two do, but the way Decorator and CoR are usually implemented don't enforce those attributes--the designer just hopes no one writes a Decorator that breaks the chain or a CoRLink that continues the chain after handling the data.

To actually implement these attributes, you'd need something like the following.

Enforced Decorator:

abstract class Decorated {

public Decorated delegate;

public final Object doIt(Object args) {
	Object returnVal = behavior(arg);
	if(delegate != null) returnVal = delegate.doit(returnVal);
	return returnVal;
}

protected abstract Object behavior(Object args); //base or subclass behavior
}

Enforced Chain of Responsibility:

abstract class Link {

public Link delegate;

public final Object processIt(Obect args) {
	Object returnVal = args;
	if(isMyResponsibility) returnVal = processingBehavior(returnVal);
	else returnVal = delegate.processIt(returnVal);
	return returnVal;
}

protected abstract Boolean isMyResponsibility(Object args);

protected abstract Object processingBehavior(Object args);
}

(Alternately, you could just add a line to the javadoc, if all you want is to absolve yourself of the responsibiity in case someone else screws up your design--but why leave it to chance?)

Solution 10 - Oop

I think the situations to apply these two patterns are different. And by the way, for decorator pattern, the decorator should know the component which it wrapped. And for CoR, the different interceptors could know nothing of each other.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorge MauerView Question on Stackoverflow
Solution 1 - OopWilliam BrendelView Answer on Stackoverflow
Solution 2 - OopBrianView Answer on Stackoverflow
Solution 3 - OoptroelsknView Answer on Stackoverflow
Solution 4 - OopRagoczyView Answer on Stackoverflow
Solution 5 - OopMahdeToView Answer on Stackoverflow
Solution 6 - Oopxenn_33View Answer on Stackoverflow
Solution 7 - OopRavindra babuView Answer on Stackoverflow
Solution 8 - OopOleksandr MarkushynView Answer on Stackoverflow
Solution 9 - OopKevin SaganView Answer on Stackoverflow
Solution 10 - Oophewei1997View Answer on Stackoverflow