问题
This answer almost describes the first half of the question.
It says:
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.
The structure of both patterns is almost identical. What forces the decorator pattern to be implemented this way? Instead of having a ConcreteElement
and some Decorator
s, what prevents me from just having each Decorator
pointing to the object it's wrapping and when the pointer to the object being wrapped is null
, then do the same as what happens in the ConcreteElement
? What makes each structure specific to its pattern?
Also, why are they in different categories? Furthermore, reading the other answers here, it looks like even though the structure is almost the same, the intent is different. The CoR
is intended for having couple of potential objects that may handle the request, and the object that will handle the request is not known in advance. Whereas the decorator is intended for wrapping an object and adding some functionality at runtime (why can't I do that with CoR?). Does it really make sense that the CoR
(which is intended for structuring several objects that are capable of processing the request together in a chain) to be behavioral
? Doesn't it seem like it should be structural
? Also, does it really make sence for the Decorator
(which is intended for encapsulating some behavior and attach it to some given object later) to be structural
? Doesn't it seem like it should be behavioral
?
回答1:
I think the answers in the linked (canonical) thread are mostly good, and the combination of them gives a fairly complete picture of these two design patterns; but perhaps a bit more from the book along with slightly different terminology could be useful as well.
One concept mentioned is that Decorators are additive. Every Decorator handles every message. This implies a cardinality of two or more. There is a basic behavior that a client wishes to enhance with one or more additional behaviors, thus a minimum of two behaviors.
Chain of Responsibility is described in the book as one behavior or less. The potential for multiple links to handle one message is easy enough to imagine, but not mentioned in the book. The cardinality is zero to one.
The biggest difference though, is in where the composing object is instantiated. Typically, Decorators are instantiated directly by the client, because the client knows exactly which enhancements it wants to wrap around some basic behavior. When the client makes a request, it explicitly knows the receivers, because it wrapped them together before sending the request.
A Chain of Responsibility is invisible to clients.
The object that made the request has no explicit knowledge of who will handle it—we say the request has an implicit receiver.
This leads to the biggest reason a client would invoke a CoR rather than a Decorator: because the client doesn't have enough information to choose a Decorator. The CoR is configured elsewhere, and the client has no knowledge of which alternative handlers are available, or even of the fact that the handler it is invoking is part of a chain at all.
Decorators benefit from a smarter client. Chain of Responsibility is a product of configuration.
Another compelling reason to implement a CoR is when your application is already designed as some form of hierarchy or tree structure. In the case where "successor" links are already in place between objects, it is relatively simple to add the Responsibility part, because the Chain is already there. The GoF notes more than once how CoR works nicely with the Composite Pattern, because the latter provides links for a CoR to piggyback on.
I believe this may also be the reason for categorizing CoR as a behavioral pattern. In the case where an object tree already exists (which is fairly common) there is no structural change required to implement a CoR. It is purely a change in behavior to the pre-existing structure. On the other hand, a new Decorator always introduces a new composition relationship, which is a structural change according to the GoF categories.
来源:https://stackoverflow.com/questions/61673275/what-is-the-difference-between-the-cor-and-the-decorator-why-is-cor-a-behaviora