[ALERT]
공부한 것을 정리한 글입니다.
부정확한 내용이 있을 수 있는 점 양해부탁드립니다!
피드백 주시면 감사히 받겠습니다 :)
1. 협력
객체지향 시스템은 자율적인 객체들의 공동체이다. 즉, 각자 능동적으로 역할을 수행한다. 이때 각 객체 사이의 협력을 위해 사용할 수 있는 유일한 통신 수단이 바로 메시지 전송이다.
협력이란 어떤 객체가 다른 객체에게 무엇인가를 요청하는 것이다.
A객체가 B객체와 협력하기 위해 메시지를 전송하게되면 B 객체는 그 메시지를 수신하고 이에 맞는 메서드를 실행해 요청에 응답한다.
영화 예매 시스템에 방금 예를 대입해보자. Screening 객체가 Movie 객체에게 요금을 계산해달라는 calculateMovieFee라는 메시지를 전송한다. 그러면 Movie는 이에 응답하기 위해 적절한 메서드를 선택해 요금을 계산한 후 요청에 응답하게 된다.
이렇게 함으로써 Screening객체가 Movie 객체의 내부 메서드, 변수에 대해 알지 않고도 원하는 바를 얻을 수 있다. 이로써 캡슐화가 이루어지고 결합도를 느슨하게 유지할 수 있다.
또한 설계 측면에서 협력은 각 객체가 가질 수 있는 상태와 행동을 결정 짓는 단서를 제공한다.
객체의 행동을 결정하는 것이 협력이고, 객체의 상태를 결정짓는 것이 행동이다. Movie가 영화요금을 계산하는 행동을 하기 위해서는 할인정책과 같은 상태를 가지고 있어야만 한다. 따라서 협력을 잘 알고 적용하게되면 이러한 일들을 보다 수월하고, 정확하게 정의할 수 있다.
2. 책임
이 책에서는 책임을 크게 2가지로 나눈다.
- 하는 것
- 객체를 생성하거나 계산을 수행하는 등의 스스로 하는 것
- 다른 객체의 행동을 시작시키는 것
- 다른 객체의 활동을 제어하고 조절하는 것
- 아는 것
- 사적인 정보에 관해 아는 것
- 관련된 객체에 관해 아는 것
- 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것
Screening은 영화 예매를 하는 책임, 상영할 영화를 아는 책임이 있다.
Movie는 요금을 계산하는 책임, 영화의 가격, 할인 정책에 대해 아는 책임이 있다.
또한, Screening은 영화요금을 계산할 수 없기 때문에 영화요금을 계산할 수 있는 Movie 객체에 대해 알고 있어야 하는 책임이 있다.
객체지향 설계에서 가장 중요한 것은 책임이다.
적절한 객체에게 적절한 책임을 할당해야 단순하고 유연한 설계를 할 수 있다.
INFORMATION EXPERT Pattern(정보 전문가 패턴)
책임을 수행하는 데 필요한 정보를 가장 잘 알고 있는 전문가에게 그 책임을 할당하는 방식의 패턴
[영화 예매 시스템에서의 예]
- 예매하라는 메시지가 있을 때, 이를 처리하기에 가장 적절한 객체는 Screening이다. 예매를 하기 위해서는 영화 정보, 상영 시간, 가격 등을 알아야 하기 때문이다.
- 예매를 위해 예매 가격을 계산해야한다. 하지만 Screening은 요금에 관련된 것은 아는 것이 없다. 따라서 요금에 관련된 전문가인 Movie객체가 예매 가격 계산에 대한 메시지를 처리하게 된다.
→ 이러한 방식으로 설계하는 것을 책임 주도 설계(RDD)라고 부른다.
메시지가 객체를 결정한다.
책임 주도 설계처럼 메시지가 객체를 결정하게 되면 객체가 최소한의 퍼블릭 인터페이스를 가질 수 있게되고, 객체가 충분히 추상적인 인터페이스를 가질 수 있게 된다.
- 메시지를 중심으로 설계하기 때문에 객체의 불필요한 퍼블릭 인터페이스를 만드는 것을 방지한다.
- 인터페이스는 무엇을 하는지는 표현하되, 어떻게 이를 수행하는지는 노출해서는 안된다. 따라서 메시지를 식별하는 데에만 힘을 1차적으로 쏟고 그 후에 어떻게 수행할지를 고민할 수 있게 된다. 그 결과 추상적인 레벨의 인터페이스를 얻을 수 있다.
데이터-주도 설계(DDD)와 같이 객체에 필요한 상태가 무엇인지를 결정하고, 그 후에 상태에 필요한 행동을 결정하게 되면 원하지 않아도 퍼블릭 인터페이스에 구현이 노출되게 된다. 이로 인해 캡슐화가 이뤄지지 않고, 결합도 또한 높아지게 된다.
→ 프로젝트를 진행하면서 이를 피하기 위해 항상 내가 RDD로 진행하고 있는지 고민하며 설계하지만 그 결과로 나온 구조가 정말 RDD인지, 아니면 RDD의 탈을 쓴 DDD인지를 명확히 구분짓지 못하고 있다. 이를 개인 차원에서 검증할 수 있는 방법에는 무엇이 있을까?
3. 역할
책임에 대해 충분히 이해한 것 같다. 역할은 객체가 어떠한 협력 안에서 수행하는 책임의 집합을 의미한다. 즉, 객체가 책임을 할당받는 것이 아니라 ‘역할’이 책임을 할당 받고 그 역할을 맡은 ‘객체’가 책임을 수행하는 것이다.
뒤에도 다시 나오겠지만 역할을 연극의 배역이라고 하고, 객체를 그 배역을 맡은 배우라고 하자. 여기서 배우와 배우간의 협력을 통해 연극이 진행된다고 생각하지만 사실은 배역과 배역사이의 협력을 통해 연극이 진행한다.
로미오와 줄리엣이라는 배역이 있을 때, 로미오 역을 맡은 배우가 A든지, B든지 누가 와도 로미오라는 역할은 변하지 않는다. 즉, 연극은 로미오와 줄리엣의 협력을 통해 진행되는 것이지, 배우 A와 줄리엣을 맡은 배우 C 간의 협력이 아닌 것이다. 로미오 역을 배우 B가 맡더라도 연극은 차이 없이 진행되기 때문이다.
이러한 사고방식을 바탕으로 설계를 진행하게되면 보다 유연한 설계가 가능할 것이다.
객체에 관해 생각할 때 ‘이 객체가 무슨 역할을 수행해야 하는가?’ 라고 자문하는 것이 도움이 된다.
너무 애매하면...?
실제로 많은 경우에 객체와 역할을 명확하게 구분하기 어려울 수 있다. 여기서 저자는 설계 초반에는 적절한 책임과 협력의 큰 그림을 탐색하는 것이 가장 중요하지, 초기부터 객체와 역할을 구분 짓는 것이 우선이 되지 않는다고 말한다. 따라서 애매하면 일단 객체로 시작하고 반복적인 리팩토링을 통해 필요한 순간 객체로부터 역할을 분리해내는 것이 가장 좋은 방법이라고 조언하고 있다.
역할과 추상화
영화 예매 시스템에서 역할과 추상화를 살펴보자. 할인 조건이 가장 대표적이라고 할 수 있다.
DiscountCondition은 인터페이스로 정의되었고 이를 상속받은 AmountDiscountCondition과 PercentDiscountCondition으로 나뉜다. 즉, 할인 조건이라는 역할을 Amount할인조건 객체가 수행할 수도 있고, Percent할인조건 객체가 수행할 수도 있다는 뜻이다.
여기서 DiscountPolicy를 살펴봐야 한다. DiscountPolicy는 총 할인 금액을 알기 위해 DiscountCondition에 메시지를 보내다. 이때 DiscountCondition은 총 할인 금액을 알려줘야할 책임이 있고, 이 책임을 수행할 메서드는 외부에서 알 필요도, 알아서도 안된다. 즉, DiscountPolicy는 단순 금액이 차감되는 할인조건인지, 일정 퍼센트만큼 할인해주는 할인조건인지 등 구체적인 사항에 대해 알 필요가 없다는 뜻이다.
이렇듯 구체적인 정보에 대해 알 필요가 없게 되는 추상화를 통해 협력을 유연하게 만든 것을 알 수 있다.
'개발 > 객체지향' 카테고리의 다른 글
VO, DTO, DAO, Entity의 차이 (0) | 2024.11.11 |
---|