개발/디자인패턴

[Java][디자인 패턴] 17. 체인 패턴 (Chain Pattern)

nova_dev 2022. 3. 21. 00:00
반응형

디자인패턴
[Java][디자인 패턴] 17. 체인 패턴 (Chain Pattern)

체인 패턴은 객체 메시지의 송신과 수신을 분리해서 처리한다.

 

 체인 패턴이란?

  • 체인 패턴은 처리 로직을 요청하는 송신부와 처리하는 수신부를 분리하는 효과가 있다.
  • 체인 패턴은 여러 객체에 요청된 이벤트를 처리할 수 있도록 균등한 기회를 제공한다.
  • 체인 패턴은 자신이 요청한 이벤트의 상태를 어떤 객체가 처리할지 모른다.
  • 하나의 요청을 세부적으로 분리하거나 복수의 동작을 처리할 때 유용하다
  • 체인 패턴은 사슬로 묶인 객체를 순차적으로 탐색하면서 요청된 객체를 수행한다.
  • 순차적으로 모든 객체를 처리하기 때문에 다소 지연 시간이 발생한다. 이는 체인 패턴의 단점이다.
  • 체인 패턴의 특징은 하나의 객체를 처리할 때 클래스 객체 한 개의 메서드에서 책임을 지는 것이 아니라 여러 객체의 메서드에서 동시에 책임을 처리한다.

 

 

 

 

 

 체인 패턴 구조

처음에 패턴을 공부할 때 당연히 메서드 체이닝 얘기하는 것이겠거니 하고 읽었는데 내가 생각하던 메서드 체인이 아니었다.
당황해서 예시를 찾아 보며 공부하던 중 발견한 아래 사이트의 예시가 직관적이고 괜찮았다. 이 예시보다 더 잘 예시를 짤 짱구가 돌아가지 않아 예시 코드를 거의 그대로 참고했다. 원본 코드는 아래 사이트를 참고하자!
https://www.geeksforgeeks.org/chain-responsibility-design-pattern/

 체인 패턴 코드

1. Number 클래스

public class Number {
    private final int number;

    public Number(int number) {
        this.number = number;
    }

    public int getNumber() {
        return number;
    }
}

2. Processor 추상 클래스

public abstract class Processor {
    private Processor next;
    protected String name;

    protected Processor(String name) {
        this.name = name;
    }

    public void process(Number request) {
        if (next != null) {
            next.process(request);
        }
    }

    public void setNext(Processor next) {
        this.next = next;
    }
}

3. Processor 클래스를 상속하고 있는 PositiveProcessor, ZeroProcessor, NegativeProcessor

public class PositiveProcessor extends Processor {
    public PositiveProcessor(String name) {
        super(name);
    }

    @Override
    public void process(Number request) {
        if (request.getNumber() > 0) {
            System.out.println(name + ": " + request.getNumber());
        } else {
            super.process(request);
        }
    }
}

 

public class ZeroProcessor extends Processor {
    public ZeroProcessor(String name) {
        super(name);
    }

    @Override
    public void process(Number request) {
        if (request.getNumber() == 0) {
            System.out.println(name + ": " + request.getNumber());
        } else {
            super.process(request);
        }
    }
}
public class NegativeProcessor extends Processor {
    public NegativeProcessor(String name) {
        super(name);
    }

    @Override
    public void process(Number request) {
        if (request.getNumber() < 0) {
            System.out.println(name + ": " + request.getNumber());
        } else {
            super.process(request);
        }
    }
}

5. Chain 클래스

public class Chain {
    private final Processor chain;

    public Chain() {
        this.chain = buildProcessorChain();
    }

    private Processor buildProcessorChain() {
        Processor firstProcessor = new NegativeProcessor("음수 프로세서");
        Processor secondProcessor = new PositiveProcessor("양수 프로세서");
        Processor thirdProcessor = new ZeroProcessor("제로 프로세서");

        firstProcessor.setNext(secondProcessor);
        secondProcessor.setNext(thirdProcessor);
        return firstProcessor;
    }

    public void process(Number request) {
        chain.process(request);
    }
}

6. 테스트 코드

class ChainTest {

    @Test
    @DisplayName("체인 테스트")
    void chainTest() {
        Chain chain = new Chain();
        chain.process(new Number(90));
        chain.process(new Number(-50));
        chain.process(new Number(0));
        chain.process(new Number(91));
    }
}

테스트 코드 결과

양수 프로세서: 90
음수 프로세서: -50
제로 프로세서: 0
양수 프로세서: 91

 원본 코드

https://www.geeksforgeeks.org/chain-responsibility-design-pattern/

참고 자료

 

 

 

 

 

반응형