이 글은 '객체지향의 사실과 오해'라는 책을 읽고 참고하면서 작성한 글입니다.
"객체는 상태와 행동을 지닌 것이다. 또한, 객체는 고유의 역할과 책임을 지니고 있다. 객체는 다른 객체와 메시지를 주고 받으며 상호협력한다."
책의 첫 부분에서 객체를 설명하기 위해 카페에 비유한 설명이 있다. 카페에서 일을 해본 것은 아니지만 평소 커피를 좋아하기 때문에 친근한 예시였다. 카페에 들어섰을 때 나타나는 이미지를 연상하면, 고객은 주문을 받는 사람에게 주문을 한다. 주문을 받은 사람은 바리스타에게 들어온 주문을 알려준다. 아주 단순한 단계로 요약해도 서로 메시지를 주고 받고 있다. 고객은 주문을 받는 사람에게, 주문을 받는 사람은 바리스타에게 메시지를 전달한다.
"아이스 아메리카노 주문할게요."
"아이스 아메리카노 주문 들어왔어요."
그런데 주문을 받는 사람이 바리스타에게 다음과 같이 메시지를 전달한다고 생각해보자.
"우리 매장에 라마르조꼬 리네아 3그룹 머신 있는거 아시죠?ㅎㅎ EK43 그라인더 분쇄도 1.5로 맞춰서 그라인딩 하시고 원두 파우더를 포타필터에 담아서 탬핑 안 하고 디스트리뷰터만 사용한 뒤에 라마르조꼬 리네아 머신 두 번째 그룹헤드에서 추출한 에스프레소를 얼음 12개 담긴 컵에 에스프레소를 넣고 물은 280g 희석한 아이스 아메리카노 만들어 주세요.ㅎㅎ"
돌아오는 바리스타의 답변을 예상해보자.
"사사건건 일해라 절해라 하실거면 니가 하세요.ㅎㅎ"
객체는 스스로 책임과 역할을 지닌다고 했다. 그런데 지나치게 범위를 넘어선 객체가 있다면, 특정 객체는 존재의 의미가 없어진다. 정의할 필요조차 없었을지도 모른다. 주문을 받는 사람은 주어진 역할과 책임(주문을 받는 것)에만 충실해야 하며, 전달해야 하는 메시지는 주문이 들어왔다는 메시지이다. 주문을 전달했을 때 바리스타는 스스로 지닌 책임과 역할에 따라 맡은 바를 수행하되, 자율성을 갖고 스스로 행동해야 한다.그런데 왜 하나의 객체가 여러 가지 역할과 책임을 지니는 것이 좋지 않은지가 궁금할 수 있다. 만약 누군가가 에스프레소 추출이라는 행동에 접근해야 하는 상황이라고 가정해보자. 분명 바리스타가 그 역할과 책임에 따라 에스프레소 추출이라는 행동을 지니고 있을 것으로 기대된다.
그런데 주문을 받는 사람이 에스프레소 추출이라는 행동을 지니고 있었다면, 그 행동에 접근하려는 사람은 행동에 접근하려고 할 때 시간이라는 비용이 생길 것이다. 또한, 애초에 역할과 책임을 할당할 때도 누구에게 그 역할과 책임을 맡겨야 하는지에 대해 고민하는 시간이 줄어든다. 다르게 표현하면 변경과 설계에 유연하게 대처할 수 있다는 것이다. 그렇다면 자율성은 어떻게 보장받을 수 있는지 생각해볼 수도 있다. 외부로부터 구현을 감추기 위해 객체를 캡슐화 할 수 있다. Swift에서 public, private을 떠올릴 수 있다. public은 외부에서 활용할 수 있는 것으로 정의하게 되며, private은 외부로부터 접근이 제한되는 객체 고유의 무엇으로 정의할 수 있게 해준다.
책을 읽으면서 놓치지 않아야겠다는 생각이 들었던 부분이 있다. 식품 기업에서 마케팅 리서치 실무를 겪으면서 느꼈던 바와 관련이 있다. 많은 조사설계와 실사, 설문 데이터 분석을 하면서 느낀 부분인데, 특정 카테고리 제품에 대해 소비자는 '기대하는 것'이 있다. 흔히 마케터나 마케팅 리서처가 실수할 수 있는 부분은 소비자가 기대하는 기본적인 특성을 무시하고 부가적인 기능을 강조하는 마케팅 커뮤니케이션을 하려는 것이다. 일단 소비자가 기본적으로 기대하고 있는 것을 충족시킬 수 있으면서 동시에 부가적인 것을 소개할 수 있어야 한다. 그렇지 않으면 소비자가 식품 섭취를 통해 기대할 수 있는 것을 충족시킬 수 없다고 판단한다. 이런 경우 기업, 마케터, 마케팅 리서처는 소비자가 기대하는 것을 충족시키지 못하고 있는 것이다. 제품 개발 과정에서 자주 느꼈던 상황이다. 애플리케이션도 마찬가지다. 사용자는 특정 애플리케이션을 사용하면서 얻을 수 있는 고유의 효과를 기대할 것이다. 개발자는 그에 걸맞는 프로그래밍을 해야 한다. 사업 관점이자 제품 관점이기도 하다.
다시 객체지향으로 넘어오자.
"객체지향을 사용하면 사용자들이 이해하고 있는 도메인의 구조와 최대한 유사하게 코드를 구조화할 수 있다. (중략) 객체지향 패러다임은 사용자의 관점, 설계자의 관점, 코드의 모습을 유사한 형태로 유지할 수 있게 하는 유용한 사고 도구와 프로그래밍 기법을 제공한다. 결과적으로 객체지향을 이용하면 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지 모두가 유사한 모습을 유지하도록 만드는 것이 가능하다."
다음 문장도 눈에 띈다.
"요구사항들을 식별하고 도메인 모델을 생성한 후, 소프트웨어 클래스에 메서드들을 추가하고, 요구사항을 충족시키기 위해 객체들 간의 메시지 전송을 정의하라[Larman 2001]."
궁극적으로 얻을 수 있는 이점을 생각하면, 사용자의 기대하는 바가 바뀌어 기능이 변경되거나 추가된다고 해도 전체적인 구조가 안정적이다. 특정 기능의 변경에 대한 예시만 생각해봐도 구조는 유지된 채로 해당 기능을 찾아 재정의하면 그만이다.