데코레이터보다 책임 체인을 사용하는 이유는 무엇입니까?
나는 책임 의 사슬 패턴 에 대해 읽고 있는데 데코레이터 보다 그것을 선호하는 시나리오를 상상하는 데 어려움을 겪고 있습니다.
어떻게 생각해? CoR은 틈새 시장에서 사용됩니까?
언제든지 체인을 끊을 수 있다는 사실은 책임 체인 패턴과 데코레이터 패턴을 구별합니다 . 데코레이터는 다른 데코레이터와의 상호 작용없이 한 번에 모두 실행하는 것으로 생각할 수 있습니다. 체인의 링크는 각각 이전 링크에 의존하기 때문에 한 번에 하나씩 실행되는 것으로 생각할 수 있습니다.
프로그램을 링크로 구성된 체인으로 개념화 할 수있는 경우 책임 체인 패턴을 사용하십시오. 여기서 각 링크는 요청을 처리하거나 체인 위로 전달할 수 있습니다.
Win32 API로 작업 할 때는 가끔 제공하는 후킹 기능을 사용해야했습니다. Windows 메시지를 후크하는 것은 대략적인 책임 체인 패턴을 따릅니다. WM_MOUSEMOVE와 같은 메시지를 연결하면 콜백 함수가 호출됩니다. 콜백 함수를 체인의 마지막 링크라고 생각하십시오. 체인의 각 링크는 WM_MOUSEMOVE 메시지를 버릴 것인지 아니면 체인을 통해 다음 링크로 전달할 것인지 결정할 수 있습니다.
이 예제에서 Decorator 패턴이 사용 되었다면 WM_MOUSEMOVE 메시지에 대한 알림을 받았을 것입니다. 그러나 다른 후크도 처리하는 것을 막을 수는 없습니다.
Chain of Command 패턴이 사용되는 또 다른 장소는 게임 엔진입니다. 다시 말하지만, 엔진 기능, 이벤트 및 기타 사항을 연결할 수 있습니다. 게임 엔진의 경우 단순히 기능을 추가하고 싶지는 않습니다. 기능을 추가하고 게임 엔진이 기본 작업을 수행하지 못하게하려고합니다.
이러한 패턴 간의 차이는 체인이 끊어 질 수있는시기 또는 방법 (체인을 가정) 또는 추가 동작이 실행되는시기와 관련이 없습니다. 둘 다 더 유연한 솔루션을 제공하기 위해 상속을 선호하는 구성을 사용한다는 점에서 관련이 있습니다.
주요 차이점은 데코레이터가 원래 인터페이스를 확장하는 새로운 동작을 추가 한다는 것입니다. "서브 클래스"가 참조에 의해서만 결합된다는 점을 제외하면 일반 확장이 메소드를 추가 할 수있는 방법과 유사합니다. 이는 "슈퍼 클래스"를 사용할 수 있음을 의미합니다.
COR 패턴은 상속을 사용하여 기존 메서드를 재정의하는 것과 유사한 기존 동작을 수정할 수 있습니다. super.xxx ()를 호출하여 "체인"을 계속하거나 메시지를 직접 처리하도록 선택할 수 있습니다.
따라서 차이는 미묘하지만 데코레이터의 예가 도움이 될 것입니다.
interface Animal
{
Poo eat(Food food);
}
class WalkingAnimal implements Animal
{
Animal wrapped;
WalkingAnimal(Animal wrapped)
{
this.wrapped = wrapped;
}
Position walk(Human walker)
{
};
Poo eat(Food food)
{
return wrapped.eat(food);
}
}
class BarkingAnimal implements Animal
{
Animal wrapped;
BarkingAnimal(Animal wrapped)
{
this.wrapped = wrapped;
}
Noise bark()
{
};
Poo eat(Food food)
{
bark();
return wrapped.eat();
}
}
우리가 걷고, 짖는 동물을 구성 할 수 있다는 것을 알 수 있습니다. 또는 실제로 어떤 동물에게도 짖는 능력을 추가 할 수 있습니다. 이 추가 동작을 직접 사용하려면 BarkingAnimal 데코레이터에 대한 참조를 유지해야합니다.
모든 BarkingAnimal은 먹기 전에 한 번 짖으며 기존 기능을 변경하여 COR과 유사합니다. 그러나 그 의도는 COR과 같지 않습니다. 즉, 음식을 먹을 많은 동물을 찾는 것입니다. 여기서 의도는 동작을 수정하는 것입니다.
동물을 산책시킬 사람을 찾기 위해 COR이 적용되는 것을 상상할 수 있습니다. 이것은 chained위와 같은 연결 목록 이나 명시적인 목록 으로 구현 될 수 있습니다 .
이것이 합리적으로 명확하기를 바랍니다!
남자
체인
둘 이상의 객체에 요청을 처리 할 수있는 기회를 제공하여 요청 발신자와 수신자를 연결하지 마십시오. 수신 객체를 연결하고 객체가 처리 할 때까지 체인을 따라 요청을 전달합니다.
vs
데코레이터
객체에 동적으로 추가 책임을 연결합니다. 데코레이터는 기능 확장을 위해 서브 클래 싱에 대한 유연한 대안을 제공합니다.
나는 일이 일어날 순서에 대해 말할 것입니다. 체인을 연결하면 체인을 따라 호출됩니다. 데코레이터를 사용하면이 순서를 보장 할 수 없으며 추가 책임 만 붙일 수 있습니다.
책임 의 사슬 은 Decorator 의 특정한 형태 라고 말하고 싶습니다 .
데코레이터는 개체에 기능을 추가하려는 경우에 사용됩니다.
COR은 많은 액터 중 하나가 객체에 대해 조치를 취할 때 사용됩니다.
특히 실내 장식은 형식에 따라 조치를 취할라고; COR은 행위자 중 하나가 작업이 완료되었다고 결정할 때까지 정의 된 체인을 따라 객체를 전달합니다.
COR은 서로 다른 처리자에게 여러 단계의 에스컬레이션이있을 때 사용할 수 있습니다. 예를 들어, 회사에 대한 고객의 가치에 따라 통화가 특정 수준의 지원으로 이동하는지 결정하는 콜센터가 있습니다.
두 가지 상황을 생각할 수 있습니다.
- 핵심 객체가 없습니다. 즉, 모든 레이어 / 필터를 통과 한 후 요청을 어떻게 처리해야하는지 알 수 없습니다. (요청이 어디에서 끝나는 지 실제로 신경 쓰지 않는 인터셉터 체인과 같은 측면과 같은 것).
- 요청에 일부 사전 또는 사후 처리를 선택적으로 적용해야합니다. 데코레이터처럼 일반적인 향상 형식이 아닙니다. 즉, 필터는 특정 요청을 처리하거나 처리하지 않을 수 있지만 데코레이터를 추가하면 항상 일부 기능으로 객체를 향상시킵니다.
지금 더 이상 생각할 수 없습니다.이 주제에 대해 더 많이 듣고 싶습니다.
데코레이터
데코레이터 패턴을 사용하면 개별 개체에 동적으로 동작을 추가 할 수 있습니다.
기능 확장 을 위해 하위 분류에 대한 유연한 대안을 제공 합니다. 상속을 사용하더라도 LCD (Lowest Common Denominator) 인터페이스에서 상속됩니다.
데코레이터 용 UML 다이어그램
결과 :
- 장식을 사용하면 추가 된 기능을 동적으로 제거 할 수도 있습니다.
- 데코레이션은 런타임에 객체에 기능을 추가하여 디버깅 시스템 기능을 더 어렵게 만듭니다.
유용한 링크:
위키 백과의 Decorator_pattern
소스 제작의 데코레이터
책임 사슬 :
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
This pattern is more effective when:
- More than one object can handle a command
- The handler is not known in advance
- The handler should be determined automatically
- It’s wished that the request is addressed to a group of objects without explicitly specifying its receiver
- 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.
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.
- keyword 'extends' - static extension.
- Decorator pattern - dynamic extension.
- Chain Of Responsibility pattern - just processing of a command object with a set of processing objects and those objects don't know each other.
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.
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?)
'IT TIP' 카테고리의 다른 글
| splatting이 rhs에 튜플을 생성하지만 lhs에 목록을 생성하는 이유는 무엇입니까? (0) | 2020.11.04 |
|---|---|
| 가변 높이 UITableView 내에서 콘텐츠를 기반으로 UIWebView 높이를 결정하는 방법은 무엇입니까? (0) | 2020.11.04 |
| Criteria API를 사용하여 주문 (0) | 2020.11.04 |
| WCF 오류 "HTTP.SYS를 사용하여 HTTPS의 경우 서버 인증서가 제대로 구성되지 않았기 때문일 수 있습니다." (0) | 2020.11.04 |
| python 스크립트에서 tar 파일 내용을 압축 해제하지 않고 읽기 (0) | 2020.11.04 |

