✏️ 스터디 모음집/디자인 패턴 스터디

디자인 패턴 스터디 기록 (3) - 객체 간의 강한 결합 VS 느슨한 결합

cocoroocoo 2022. 10. 27. 02:49

강한 결합 VS 느슨한 결합

이것을 이해하기 전에 먼저 객체간의 강한 결합에 속하는 상속(= is-a 관계) 을 보자!

public class Lotto {
    protected List<Integer> lottoNumbers;

    public Lotto(List<Integer> lottoNumbers) {
        this.lottoNumbers = new ArrayList<>(lottoNumbers);
    }

    public  boolean contains(Integer integer) {
        return this.lottoNumbers.contains(integer);
    }
    ...
}

public class WinningLotto extends Lotto {
    private final BonusBall bonusBall;

    public WinningLotto(List<Integer> lottoNumbers, BonusBall bonusBall) {
        super(lottoNumbers);
        this.bonusBall = bonusBall;
    }

    public long compare(Lotto lotto) {
        return lottoNumbers.stream()
            .filter(lotto::contains)
            .count();
    }
    ...
}

Lotto 클래스는 로또 번호를 List<Integer> 로 가지고있다. 그리고 WinningLotto 클래스는 당첨 로또번호를 가지고 있는 클래스이다.

WinningLotto 클래스는 부모로부터 상속받은 로또 번호 List<Integer>를 조작한다.

여기까지는 문제가 없다. 그런데 만약 부모가 수정되어 로또 번호를 연결리스트가 아닌 배열 형태로 담는것으로 수정된다면 어떻게 될까?

public class Lotto {
    protected int[] lottoNumbers; // List<Integer> -> int[] 로 수정

    public Lotto(int[] lottoNumbers) {
        this.lottoNumbers = lottoNumbers;  // 여기도 당연히 같이 수정
    }

    public boolean contains(Integer integer) {
        return Arrays.stream(lottoNumbers) // 여기도 당연히 같이 수정
            .anyMatch(lottoNumber -> Objects.equals(lottoNumber, integer));
    }
    ...
}

부모에게 물려받은 값이 바뀌면 그 값을 다루던 함수들도 다 바꿔야한다. (강한 의존)

public class WinningLotto extends Lotto {
    private final BonusBall bonusBall;

    // 오류가 발생한다. -> 그래서 다른 클래스인데 여기도 수정해줘야 함.
    public WinningLotto(List<Integer> lottoNumbers, BonusBall bonusBall) {
        super(lottoNumbers);
        this.bonusBall = bonusBall;
    }
 
    // 오류가 발생한다. -> 그래서 다른 클래스인데 여기도 수정해줘야 함.
    public long compare(Lotto lotto) {
        return lottoNumbers.stream()
            .filter(lotto::contains)
            .count();
    }
}

만약 조합(Composition = has-a 관계)을 사용하면?

public class WinningLotto {
    private Lotto lotto;
    private BonusBall bonusBall;

    public long compare() {
			return this.lotto.conpare();        
    }
}

 

이처럼 WinningLotto객체 에서 멤버 변수로 Lotto 객체를 가지는 것이 조합(Composition)이다.

WinningLotto 객체에서는 Lotto 객체가 제공하는 함수를 호출만 하면 되므로, Lotto 객체가 어떤 값을 가지고 있고, 그 값이 List<Integer> -> int[] 로 수정 된것에 대해 변경을 할 필요가 없다.