Shine
짝 프로그래밍 중에서 다음과 같이 접근하려는 일이 있었습니다.
class WinningNumbers {
private LottoTicket winningTicket;
(...)
public LottoTicket getWinningTicket() {
return winningTicket;
}
class LottoTicket {
// 일급 객체
private ArrayList<LottoNumber> lottoNumbers;
(...)
private checkWinningNumber(WinningNumbers winningNumber) {
for (int i=0; i < winningNumber.size(); i++ {
myLottoNumber.isSameNumber(winningNumber.getWinningTicket().lottoNumbers.get(i);
}
}
myLottoNumber
와 winningNumber
를 비교하기 위해 조회하는 부분에서, shine
이 이렇게 구현하면 디미터 법칙을 위배한다고 하셔서 찾아보았습니다.
디미터 법칙은 디미터라는 이름의 프로젝트를 진행하던 도중 다른 객체들과의 협력을 통해 프로그램을 완성해나가는 객체지향 프로그래밍에서 객체들의 협력 경로를 제한하면 결합도를 효과적으로 낮출 수 있다는 사실을 발견해서 만들어졌다고 한다.
현재 디미터 법칙은 객체 간 관계를 설정할 때 객체 간의 결합도를 효과적으로 낮출 수 있는 유용한 지침 중 하나로 꼽히며 객체 지향 생활 체조 원칙 중 한 줄에 점을 하나만 찍는다.로 요약되기도 한다.
Don’t Talk to Strangers
디미터 법칙을 한마디로 요약한 문장이다. 디미터 법칙의 핵심은 객체 구조의 경로를 따라 멀리 떨어져 있는 낯선 객체에 메시지를 보내는 설계를 피하라는 것이다. 바꿔 말해, 객체는 내부적으로 보유하고 있거나 메시지를 통해 확보한 정보만 가지고 의사 결정을 내려야 하고 다른 객체를 탐색해 뭔가를 일어나게 해서는 안 된다.
다른 객체를 탐색했다는 뜻은 그 객체와도 결합된다는 뜻이다. 그럼 메시지를 주고받는 객체 뿐만 아니라 그 낯선 객체의 변화에도 설계가 무너지게 된다. 아래 링크에 예제 코드와 자세히 나와있어 큰 도움이 되어 있다.
호눅스의 수업 시간 중에 Composition과 Inheritance에 대해서 배웠다. 보통 객체지향의 특징 하면 코드의 재사용을 위한 상속을 떠올리는데, 오히려 상속보다 합성이 코드 재사용에 유리하다는 말을 들었다.
사실 합성이 정확히 무슨 개념인지조차 몰랐어서 조금 놀랐다. 그래서 찾아보기로 했다.
보통 상속 관계를 is-a
관계로 표현한다. [자식 클래스는 부모 클래스이다] 라고 말할 수 있는 관계인 것이다. 사람
클래스가 존재한다면, 개발자
, 학생
등이 사람 클래스를 상속받는다. 그럼 [개발자는 사람이다], [학생은 사람이다]가 성립된다.
반면, 합성은 has-a
관계로 표현한다. 한 객체가 자신이 필요한 객체를 멤버 필드로 가지고 있는 것이다.
특정 클래스에 필요한 기능을 재사용하기 위해서, 상속을 받는 것이 아니라 멤버로서 주입받아 사용하는 것이다. 이렇게 하면 상속보다 매우 느슨하게 결합할 수 있다. 메서드를 호출하는 방식으로 동작하기 때문에 캡슐화도 깨지지 않는다. 변화에 의한 영향 역시 줄어든다.
상속을 사용해야 하는 경우는 두 가지 조건을 만족하는 경우가 좋다고 한다.
1. 부모 클래스와 자식 클래스가 확실한 is-a
관계일 때
2. 행동 호환성이 만족하는 경우
아래 링크 등을 참고해보며 꾸준히 공부해야할 내용일 것 같다.
무분별하게 상속해서 코드를 재사용하는 것이 객체지향적이다! 라고 생각했었는데, 오늘 생각이 많이 바뀌었다.
상속보다는 조합을 사용하자
Composition이란
[OOP] 코드의 재사용, 상속보다 합성을 사용해야 하는 이유
shine
과 성공적으로 미션을 수행한 것 같다..!! 감사하다!
디미터 법칙에 대해 새롭게 알게되었네요 👍
3단계까지 벌써하셨다니 부럽습니다 ㅠㅠ
지금 본문에 썸네일이 2개 있는 것 같은데 본문작성시에는 썸네일을 넣지말고 작성완료 누르고
썸네일업로드하는 부분에만 업로드하면 본문에 1개만 나옵니다 ㅋㅋㅋ