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

后端 未结 11 1904
[愿得一人]
[愿得一人] 2020-12-04 12:58

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

11条回答
  •  离开以前
    2020-12-04 13:23

    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?)

提交回复
热议问题