객체지향의 역할, 책임, 그리고 협력 쉽게 이해하기

sinjuk1·2025년 5월 11일
4
post-thumbnail

개요

객체지향적인 코드를 작성하면서 역할, 책임, 협력이라는 세 가지 핵심 개념을 자주 접했다. '역할과 책임이 불분명하다', '책임이 너무 과하다', '객체 간에 협력을 매우 잘하고 있다' 같은 이야기를 들으면서 역할과 책임 그리고 협력이 정확히 무엇을 의미하는지 궁금해졌다. 찾아보는 과정에서 김영한 님의 "객체지향의 사실과 오해"를 읽어보며 이 말들이 무슨 의미인지 비로소 알게 되었다. 이 글은 그 과정에서 알게 된 내용과 내 생각을 정리한 것으로, 역할, 책임, 협력에 대해 이해하는 것에 도움이 되길 바란다.

1. 객체지향적 사고, 왜 필요할까?

객체지향의 핵심 목표는 마치 현실 세계의 사람들이 서로 협력하며 살아가는 것처럼, 소프트웨어 안에서도 객체들이 협력하여 공동의 목표를 달성하는 공동체를 만드는 것이다. 즉, 객체들로 이루어진 자율적인 공동체가 유기적으로 상호작용하며 하나의 시스템을 구축하는 사고방식이다.

이러한 객체지향적 사고를 이해하기 위해, 우리 주변에서 쉽게 볼 수 있는 '커피 주문' 상황을 예시로 들어보자.

커피 주문하기 협력 시나리오:

카페에 손님이 들어와 커피를 주문하는 상황을 상상해 보자. 이 하나의 목표를 달성하기 위해 '손님', '캐시어', '바리스타'라는 세 가지 존재가 서로 협력한다.

  • 손님: 캐시어에게 원하는 커피를 주문한다.
  • 캐시어: 손님으로부터 주문을 받고, 결제를 처리한 후 주문 내용을 바리스타에게 전달한다.
  • 바리스타: 전달받은 주문 내용에 따라 커피를 만들고, 완성된 커피를 캐시어에게 건넨다.
  • 캐시어: 바리스타로부터 받은 커피를 손님에게 전달한다.

이처럼 '커피 주문'이라는 목표를 달성하기 위해 각자 맡은 바를 수행하며 서로 돕는 과정이 바로 협력이다. 그리고 이 협력 속에서 자연스럽게 역할과 그에 따른 책임이 발생한다.

2. 협력이란 무엇일까?

협력이란 객체들이 시스템의 공동 목표를 달성하기 위해 서로 메시지를 주고받으며 상호작용하는 과정을 의미한다. 객체지향 시스템은 독립적인 객체들의 단순한 나열이 아니라, 이 객체들이 유기적으로 연결되어 협력함으로써 하나의 기능을 완성한다.

왜 협력이 중요할까?

  • 문제 해결: 복잡한 문제를 하나의 객체가 모두 해결하는 것은 어렵다. 여러 객체가 책임을 나눠 협력하면 효율적으로 문제를 해결할 수 있다.
  • 유연성: 협력의 구조를 잘 설계하면, 특정 객체의 내부 구현이 바뀌더라도 다른 객체에 미치는 영향을 최소화할 수 있다.
  • 재사용성: 잘 정의된 협력 관계는 다른 시스템에서도 재사용될 수 있는 모듈을 만들 가능성을 높인다.

커피숍 예시에서의 협력:

위 커피 주문 시나리오에서 '커피 주문하기'는 손님, 캐시어, 바리스타의 협력을 통해 이루어지는 하나의 큰 흐름이다. 각자가 자신의 역할을 수행하며 메시지(주문, 주문 전달, 커피 제조 요청, 완성된 커피)를 주고받으며 공동의 목표(손님이 커피를 받는 것)를 달성한다.

3. 역할이란 무엇일까?

역할은 특정 협력에 참여하는 객체가 수행해야 할 기대되는 임무나 책임의 집합을 의미한다. 즉, 객체가 협력 안에서 차지하는 위치나 행위의 추상적인 표현이다.

왜 역할이 중요할까?

  • 유연성과 대체 가능성: 중요한 점은 '역할'은 특정 객체에 묶이지 않는다는 것이다. 카페에 여러 명의 캐시어가 있어도, 손님은 그중 아무나 '캐시어' 역할을 수행하는 사람에게 주문할 수 있다. 이는 역할이 객체의 구체적인 타입이 아니라, 그 객체에게 기대되는 행동을 정의한다는 의미이며, 시스템에 유연성을 부여한다. 한 객체가 고장 나더라도 동일한 역할을 수행하는 다른 객체로 쉽게 대체할 수 있다.
  • 책임의 집합: "역할은 관련성 높은 책임의 집합이다"라는 말처럼, 캐시어라는 역할은 '주문 받기', '결제 처리하기', '바리스타에게 주문 전달하기'와 같은 여러 책임들을 묶어 놓은 것이다.

커피숍 예시에서의 역할:

  • 손님 역할: 커피를 주문하고, 비용을 지불하며, 커피를 받는 임무를 가진다.
  • 캐시어 역할: 손님의 주문을 받고, 결제를 처리하며, 주문을 바리스타에게 전달하고, 완성된 커피를 손님에게 전달하는 임무를 가진다.
  • 바리스타 역할: 주문 내용에 따라 커피를 제조하는 임무를 가진다.

4. 책임이란 무엇일까?

책임은 객체가 특정 역할을 수행하기 위해 '해야 하는 것' (행동) 또는 '알아야 하는 것' (정보)을 의미한다. 책임은 객체가 협력에 참여하기 위해 반드시 수행해야 할 의무이자 기능이다.

객체의 책임은 크게 두 가지 유형으로 나눌 수 있다.

  • 하는 것 (Doing): 객체가 수행하는 행동이나 계산을 의미한다. (예: 캐시어가 주문을 처리한다, 바리스타가 커피를 제조한다)
  • 아는 것 (Knowing): 객체가 가지고 있거나 다른 객체에게 알려줄 수 있는 정보를 의미한다. (예: 캐시어가 주문 내용을 안다, 바리스타가 커피 레시피를 안다)

왜 책임이 중요할까?

  • 캡슐화: 객체는 자신의 책임을 수행하는 데 필요한 내부 구현을 외부로부터 숨긴다. (예: 바리스타가 커피를 어떻게 만드는지는 손님이나 캐시어가 알 필요 없다.) 이는 객체의 독립성을 높여준다.
  • 협력의 일관성: 각 객체가 자신의 책임을 명확히 수행하면, 협력 과정이 예측 가능하고 효율적으로 진행될 수 있다.

커피숍 예시에서의 책임:

  • 손님 역할의 책임:
    • 주문할 커피의 종류를 결정하고 캐시어에게 알린다.
    • 주문한 커피에 대한 비용을 지불한다.
  • 캐시어 역할의 책임:
    • 손님으로부터 주문을 정확하게 받는다.
    • 결제를 처리한다.
    • 주문 내용을 바리스타에게 정확하게 전달한다.
    • 완성된 커피를 손님에게 전달한다.
  • 바리스타 역할의 책임:
    • 주문받은 커피를 레시피에 따라 제조한다.
    • 완성된 커피를 캐시어에게 전달한다.

만약 손님에게 커피 제조까지 맡긴다면 어떨까? 이는 '손님'이라는 역할이 감당하기에는 너무 과도한 책임이다. 적절한 객체에게 적절한 책임을 할당하는 것이 바로 객체지향 설계의 핵심이다.

5. 역할, 책임, 협력, 이 세 가지의 연결고리

우리는 흔히 객체지향을 배울 때 객체 자체에 초점을 맞춘다. 하지만 "객체지향의 사실과 오해"는 객체지향의 본질이 '객체가 아닌 협력'에 있다고 강조한다.

객체지향적 사고의 핵심 흐름:

  1. 협력 정의: 시스템이 달성해야 할 목표를 정의하고, 이를 위한 큰 틀의 협력 시나리오를 구상한다. (예: '커피 주문하기')
  2. 역할 도출: 협력 시나리오 안에서 누가 어떤 일을 할 것인지, 어떤 추상적인 역할들이 필요한지 파악한다. (예: '손님', '캐시어', '바리스타' 역할)
  3. 책임 할당: 각 역할에 필요한 구체적인 행동과 지식, 즉 책임을 할당한다. 이때 책임은 너무 과하지 않게, 명확하게 분리하는 것이 중요하다.

결론적으로, 객체지향적 설계는 달성하고자 하는 목표(협력)를 먼저 정의하고, 이 협력을 원활하게 이끌어낼 수 있는 역할들을 도출한 뒤, 각 역할에 적절한 책임을 할당하는 과정이라고 할 수 있다. 책임이 너무 과도하거나 불분명하면, 객체 간의 관심사가 명확하게 분리되지 않아 시스템이 복잡해지고 유지보수가 어려워진다.

6. 예시로 더 깊이 이해하기

6.1. '오리' 예시: 잘못된 설계가 가져오는 책임 문제

객체지향에서 흔히 이야기되는 '오리' 예시를 통해 역할과 책임, 그리고 협력의 중요성을 다시 한번 살펴보자.

생물 오리(날 수 있고, 수영할 수 있음)와 장난감 오리(날 수 없고, 수영할 수 있음)가 있다고 가정해 보자. 만약 장난감 오리가 생물 오리를 상속받아 모든 행동(날기, 수영하기)을 물려받았다면 어떻게 될까?

  • 협력 상황 1: 절벽에서 '날기'라는 역할 기대
    • 우리는 '날기'라는 역할을 생물 오리에게 기대할 수 있다. 하지만 이 역할을 장난감 오리에게 맡긴다면, 장난감 오리는 날지 못하므로 책임을 다하지 못하게 된다. 이 경우 '날기'라는 협력에 장난감 오리가 부적절하게 참여한 것이다.
  • 협력 상황 2: 물에서 '수영하기'라는 역할 기대
    • 반면, 물에서 '수영하기'라는 역할을 생물 오리나 장난감 오리 모두에게 기대할 수 있다. 이 상황에서는 두 오리 모두 책임을 성공적으로 수행한다.

이 예시는 '객체의 역할과 책임은 협력에서 나온다'는 핵심 메시지를 명확히 보여준다. 어떤 역할과 책임을 수행하느냐는 객체 그 자체의 특성뿐만 아니라, 그 객체가 참여하는 협력의 문맥에 따라 달라진다는 것이다. 장난감 오리는 '날기' 협력에는 부적합하지만, '수영하기' 협력에는 적합한 참여자가 될 수 있다. 객체지향 설계 시, 객체의 행동(책임)을 결정할 때 어떤 협력에 참여할지를 먼저 고려하는 것이 중요하다.

profile
함께 성장하는 것을 지향합니다.

0개의 댓글