Java

Public Interface의 품질에 영향을 미치는 요소...

체리필터 2021. 7. 1. 10:43
728x90
반응형

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791158391409&orderClick=LET&Kc= 

 

오브젝트 - 교보문고

코드로 이해하는 객체지향 설계 | 객체지향으로 향하는 첫걸음은 클래스가 아니라 객체를 바라보는 것에서부터 시작한다. 객체지향으로 향하는 두번째 걸음은 객체를 독립적인 존재가 아니라

www.kyobobook.co.kr

 

위 책 6장에 나오는 내용을 정리해 둔다.

182면에 Public Interface의 품질에 영향을 미치는 기법에 대해 나온다.

1. 디미터 법칙

디미터 법칙(Law of Demeter)은 객체의 내부 구조에 강하게 결합되지 않도록 협력 경로를 제한하라는 것.

"낯선 자에게 말하지 말라(Don't talk to strangers)"

"오직 인접한 이웃하고만 말하라(Only talk to your immediate neighbors)"

이를 위해서는 부끄럼 타는 코드(Shy code)를 작성해야 한다.

책에 나오는 예제 중 다음과 같은 코드는 디미터 법칙을 위반하는 전형적인 코드이다.

screening.getMovie().getDiscountConditions();

상영이 영화를 가져와서 그 안의 할인 조건 목록을 가져오는 것인데, 상영이 영화 내부를 너무나도 잘 알고 있기 때문에 디미터 법칙을 위반하는 것이다.

이와 같은 코드를 기차 충돌(train wreck) 이라고 부른다. 따라서 상영이 영화의 내부구현을 모르도록 바꾸길 원한다면 다음과 같은 코드로 바뀌는게 맞다.

screening.calculateFee(audienceCount);

이렇게 함으로 메시지 수신자의 내부 구조에 대해 묻지 않게 되고 원하는 것만 요청하는 모습을 가지게 된다.

2. 묻지 말고 시켜라

메시지 전송자는 메시지 수신자의 상태를 기반으로 결정을 내린 후 메시지 수신자의 상태를 바꿔서는 안된다.

즉 메시지 수신자의 상태에 따라 어떻게 할지 정하고 메시지를 전송하는 것이 아니라, 데이터와 행동을 같이 가지고 있는 높은 응집도를 가진 클래스(객체)에게 어떠한 액션을 시키는 것이다.

메시지 수신자의 내부 상태를 뭍는 인터페이스가 존재한다면, 해당 객체가 책임져야 하는 어떤 행동이 외부로 누수된 것이다.

인터페이스는 객체가 어떻게 하는지가 아니라 무엇을 하는지를 서술해야 한다.

반응형

3. 의도를 드러내는 인터페이스

예제로 든 영화 예매 프로그램 중 할인 조건을 찾는 예제가 나와 있다. 기간으로 조건을 찾을 때는 isSatisfiedByPeriod 라는 메소드를 호출하였고, 상영회차에 대한 조건일 경우 isSatisfiedBySequence 라는 메소드를 사용하였다.

이는 할인 조건을 사용하는 클라이언트로 하여금 할인 조건의 내부 구현을 파악하도록 강요하게 된다.

또한 내부 구현의 방법이 변경 되어 메소드 명을 변경하게 되면, 이를 호출하는 클라이언트까지 수정하게 되어 안 좋은 코드가 된다.

따라서 메소드 명은 '어떻게'가 아니라 '무엇'을 드러내도록 명명해야 한다.

위의 메소드를 예로 든다면 DiscountCondition이라는 인터페이스에 isSatisfiedBy 라는 메소드를 선언하고, 이를 기간과 회차 클래스에서 각각 구현하면 된다.

이로 인해서 내부 구현이 바뀌던가, 아니면 할인 조건이 추가 되어도 클라이언트 입장에서는 수정할 필요가 없게 된다.

이런 식으로 이름을 짓는 것을 의도를 드러내는 선택자(Intention Revealing Selector)라고 한다.

4. 명령-쿼리 분리 원칙

명령(Command)과 쿼리(Query)는 다음과 같이 정의 내릴 수 있다.

명령(Command) - 객체의 상태를 수정하는 오퍼레이션

쿼리(Query) - 객체와 관련된 정보를 반환하는 오퍼레이션

따라서 '명령-쿼리 분리 원칙'이란 오퍼레이션은 부수 효과를 발생시키는 명령이거나, 부수 효과를 발생시키지 않는 쿼리 중 하나여야 한다는 의미이다.

즉 명령인 동시에 쿼리인 오퍼레이션이어서는 안된다는 의미이다.

명령과 쿼리를 섞으면 실행 결과를 예측하기 어렵게 되며, 메소드를 이해하기 어렵게 되며, 잘못 사용할 수 있고, 버그를 양산하게 된다.

실제로 새로 입사하게 되는 회사의 레거시 코드를 분석하다 보면 이런 경우를 많이 볼 수 있게 된다.

 

728x90
반응형

'Java' 카테고리의 다른 글

Collection Test, Fail Fast, Fail Safe...  (0) 2021.07.02
Reflection 사용2  (0) 2021.06.29
Reflection 사용1  (0) 2021.06.25
Reflection  (0) 2021.06.25
Java Random 함수의 동작 원리  (0) 2021.05.14