[Design Pattern] 행동 패턴 6. 책임 연쇄 (Chain of responsibility)
Table of Contents
책임 연쇄 (Chain of responsibility) #
- 주어진 요청을 처리하기 위해서 객체 사슬을 생성하고, 이 요청은 사슬을 따라 전달되면서 적절한 핸들러에 의해 처리되게 한다.
개념적인 예시 #
// 핸들러는 핸들러들의 체인을 만든다.
// 요청을 처리할 동작도 정의되어 있다.
public interface IHandler
{
IHandler SetNext(IHandler handler);
object Handle(object request);
}
abstract class AbstractHandler : IHandler
{
private IHandler _nextHandler;
// 기본 메서드를 베이스 클래스에서 구현할 수 있다.
public IHandler SetNext(IHandler handler)
{
this._nextHandler = handler;
// 핸들러를 리턴한다.
// 이렇게 함으로써 아래 코드처럼 핸들러들을 연결시킬 수 있다.
// monkey.SetNext(squirrel).SetNext(dog);
return handler;
}
public virtual object Handle(object request)
{
if (this._nextHandler != null)
{
return this._nextHandler.Handle(request);
}
else
{
return null;
}
}
}
class MonkeyHandler : AbstractHandler
{
public override object Handle(object request)
{
if ((request as string) == "Banana")
{
return $"Monkey: I'll eat the {request.ToString()}.\n";
}
else
{
return base.Handle(request);
}
}
}
class SquirrelHandler : AbstractHandler
{
public override object Handle(object request)
{
if (request.ToString() == "Nut")
{
return $"Squirrel: I'll eat the {request.ToString()}.\n";
}
else
{
return base.Handle(request);
}
}
}
class DogHandler : AbstractHandler
{
public override object Handle(object request)
{
if (request.ToString() == "MeatBall")
{
return $"Dog: I'll eat the {request.ToString()}.\n";
}
else
{
return base.Handle(request);
}
}
}
class Client
{
// 클라이언트는 한 개의 핸들러만 사용한다. 체인이 연결된지도 모른다.
public static void ClientCode(AbstractHandler handler)
{
var list = new List<string> { "Nut", "Banana", "Cup of coffee" };
foreach (var food in list)
{
Console.WriteLine($"Client: Who wants a {food}?");
var result = handler.Handle(food);
if (result != null)
{
Console.Write($" {result}");
}
else
{
Console.WriteLine($" {food} was left untouched.");
}
}
}
}
class Program
{
static void Main(string[] args)
{
var monkey = new MonkeyHandler();
var squirrel = new SquirrelHandler();
var dog = new DogHandler();
// 체인 만들기
monkey.SetNext(squirrel).SetNext(dog);
// Monkey -> Squirrel -> Dog
Client.ClientCode(monkey);
// Squirrel -> Dog
Client.ClientCode(squirrel);
}
}