DESIGN PATTERN

[디자인패턴] 책임 연쇄 패턴 (Chai- of-responsibility Pattern) - 개발자 배찌

개발자 배찌 2022. 4. 11. 15:14
728x90

😀책임 연쇄 패턴이란?

- 클라이언트에게 어떤 요청이 들어왔을 때, 요청받은 객체가 해당요청을 해결할 수 없을 경우
연결된 다음 객체들에게 전달하여 해당 요청을 해결할 수 있는 객체가 처리하는 방식

즉, 요청을 처리할 수 있는 객체가 여러개이고, 처리객체가 특정적이지 않을 경우 권장되는 패턴

😀장점

- 요청의 발신자와 수신자를 분리시킬 수 있다.
- 결합도를 낮춰준다.
- 클라이언트는 처리객체의 집합 내부 구조를 알 필요가 없다는것을 충족함.

😀단점

- 충분한 디버깅을 거치지 않을 경우, 집합 내부에서 사이클이 발생할 수 있음.

😀코드로 알아봅시다!!

요청 : 거스름돈을 남겨주는 로직. 100원, 10원, 1원단위로만 남겨줄 수 있음.

DispenseChain.java

package study.chainOfResponsibilityPattern.code1;

public interface DispenseChain {
    void setNextChain(DispenseChain nextChain);
    void dispense(Currency cur);
}


Currency.java

package study.chainOfResponsibilityPattern.code1;

public class Currency {
    private int amount;

    public Currency(int amt){
        this.amount = amt;
    }

    public int getAmount(){
       return this.amount;
    }
}


Won100Dispenser.java

package study.chainOfResponsibilityPattern.code1;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Won100Dispenser implements DispenseChain{

    private DispenseChain nextChain;

    @Override
    public void setNextChain(DispenseChain nextChain) {
        this.nextChain = nextChain;
    }

    @Override
    public void dispense(Currency cur) {
        if(cur.getAmount() >= 100){
            int num = cur.getAmount() / 100;
            int remainder = cur.getAmount() % 100;

            log.info("Dispensing = " + num + " * 100won");
            if (remainder != 0) {
                this.nextChain.dispense(new Currency(remainder));
            }
        } else {
            this.nextChain.dispense(cur);
        }
    }
}


Won10Dispenser.java

package study.chainOfResponsibilityPattern.code1;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Won10Dispenser implements DispenseChain{

    private DispenseChain nextChain;

    @Override
    public void setNextChain(DispenseChain nextChain) {
        this.nextChain = nextChain;
    }

    @Override
    public void dispense(Currency cur) {
        if(cur.getAmount() >= 10) {
            int num = cur.getAmount() / 10;
            int remainder = cur.getAmount() % 10;

            log.info("Dispensing = " + num + " * 10won");
            if (remainder != 0) {
                this.nextChain.dispense(new Currency(remainder));
            }
        } else {
            this.nextChain.dispense(cur);
        }
    }
}


Won1Dispenser.java

package study.chainOfResponsibilityPattern.code1;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Won1Dispenser implements DispenseChain{

    private DispenseChain nextChain;

    @Override
    public void setNextChain(DispenseChain nextChain) {
        this.nextChain = nextChain;
    }

    @Override
    public void dispense(Currency cur) {
        int num = cur.getAmount()/1;
        log.info("Dispensing = " + num + " * 1won");
    }
}


ChainOfResponsibilityPatternTest.java

package study.chainOfResponsibilityPattern;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import study.chainOfResponsibilityPattern.code1.*;

@Slf4j
public class ChainOfResponsibilityPatternTest {


    @Test
    void code1test(){
        DispenseChain chain1 = new Won100Dispenser();
        DispenseChain chain2 = new Won10Dispenser();
        DispenseChain chain3 = new Won1Dispenser();

        chain1.setNextChain(chain2);
        chain2.setNextChain(chain3);

        chain1.dispense(new Currency(397));

    }
}


결과화면

Dispensing = 3 * 100won
Dispensing = 9 * 10won
Dispensing = 7 * 1won