설계 개선하기
Robert C. Martin 이 언급한 변경하기 쉬우면서, 이해하기 쉬운 코드는 어떻게 해결할 수 있을까요?
변경과 코드의 이해는 서로 연관되어 있습니다.
Theater 클래스를 이해하기 어려운 이유는 Audience 클래스와 TicketSeller 클래스에 직접 접근하기 때문입니다.
우리의 예상과 달리 관람객과 판매원이 각자가 해야하는 일을 스스로 처리하지 못해서 입니다.
해결 방법은 간단합니다. Audience 과 TicketSeller 가 하는 일의 세부 사항을 Theater 가 알지 못하도록 차단하면 됩니다.
관람객이 가방을 가지고 있는 것은 극장에서 신경쓰지 않아도 됩니다. 또 판매원이 매표소에서 티켓을 파는 행위는 극장이 몰라도 됩니다. 극장은 단지 관람객이 공연에 입장하도록 하기만 하면 됩니다.
어떻게 관람객과 판매원 클래스의 자율성을 높일 수 있을까요?
enter() 메서드에서 Audience 과 TicketSeller 의 세부 로직을 감춥니다.
TicketSeller 는 getTicketOffice() 로 매표소에 접근하는 메서드를 외부에 공개하지 않도록 합니다.
TicketSeller 는 직접 매표소에 접근해 일을 처리합니다.
이렇게 객체가 행하는 세부적인 사항을 숨기는 것을 캡슐화(Encapsulation) 라고 합니다.
캡슐화의 목적은 변경하기 쉬운 객체로 만드는 것입니다.
Theater 는 더 이상 Audience 나 TicketSeller 의 세부 사항을 몰라도 되고, 변경에 영향을 받지 않게 되었습니다.
Theater 는 TicketSeller 라는 인터페이스에만 의존합니다. TicketOffice 는 TicketSeller 인터페이스의 구현체입니다.
Theater 는 TicketOffice 와 소통을 TicketSeller 와 하게 되었습니다.
객체를 인터페이스와 구현으로 분리하고, 인터페이스로 소통하는 방식은 객체 간 결합도를 낮추고 변경하기 쉬운 코드로 만듭니다.
동일한 방법으로 Audience 는 구현체 Bag 을 캡슐화 할 수 있습니다.
TicketSeller 는 Audience 의 Bag 을 직접 접근하지 않습니다.
단지 Audience 인터페이스로 현금을 받기만하면 됩니다.
Audience 는 가방에서 초대장을 찾거나 현금, 티켓을 직접 관리합니다.
TicketSeller 는 Audience 라는 인터페이스에만 의존하고, 가방이라는 존재는 몰라도 된다.
핵심은 객체 내부의 상태를 캡슐화해서 세부 내용을 숨기고, 메시지로 소통하는 것이다.
Theater 는 TicketSeller 구현을 몰라도 된다. 단지 sellTo 라는 메시지로 Audience 에게 티켓을 잘 판매했다는 것만 알 뿐이다.
또 TicketSeller 는 Audience 에 대해서 알지 못한다. 단지 buy 라는 메세지로 현금을 반환받아서 매표소에 직접 현금을 보관할 뿐이다.
TicketSeller 는 TicketOffice 라는 구현에 대한 작업만 수행한다.
Audience 내부의 구현은 Audience 에 맡긴다.
이렇게 신경쓰지않아도 되는 일을 위임하면 객체의 응집도(Cohesion) 이 높아진다. 객체 내 객체에 관련있는 일만 있다는 것이다.
응집도를 높이려면, 객체는 스스로의 일을 해야한다. 자신이 소유한 데이터에 대한 작업을 스스로 처리한다.
스스로 처리함으로 자율성을 높인다. 오직 인터페이스의 메세지를 통해서만 협력한다.
조금 더 개선시켜 볼 수 있다.
Audience 는 분명 자율적인 존재가 되었다. 스스로 티켓을 구매하고, 가방의 내용물들을 직접 관리한다.
하지만 Bag 은 어떤가? Audience 에 수동적인 객체가 된다.
Bag 은 자율적인 존재가 되었다. 스스로 내용물들을 관리한다.
Audience 는 Bag 의 구현에 신경쓰지 않는다. 단지 티켓을 건네준다.
TicketOffice 도 마찬가지로 자율적인 객체로 변경할 수 있다.
TicketSeller 는 TicketOffice 의 세부사항에 알지 못한다.
티켓을 가지는 매표소에게 일을 위임한다.
TicketSeller 는 처음에는 알지 못하던 Audience 라는 의존성을 추가로 가지게 되었다.
Audience 의 결합도 증가와 TicketOffice 자율성 사이에서 고민이 생긴다.
정답은 없다. 설계에서는 여러 설계 방법이 도출될 수 있고, 적절한 트레이드 오프를 따져서 더 나은 방식을 채택해야한다.
TicketOffice 와 Bag 의 자율성을 높이는 작업이 이해가 쉽지 않다.
어떻게 매표소, 가방이 스스로 자기가 소유한 데이터를 관리한다는 것인지?
이렇게 현실에서는 수동적인 존재라고 하더라도 객체 지향의 세계에서는 능동적이고, 자율적인 존재로 설계하는 원칙을 가진다.
Rebecca Wirfs-Brock 은 능동적이고 자율적인 존재로 객체를 설계하는 원칙을 의인화(anthropomorphism) 이라고 했다.
Last updated