요즘 부서 이동때문에 출퇴근이 4시간이 넘게 걸리네요.. ㅎㅎ 부랴부랴 회사옆에 집은 구했는데 아직 입주까지 2주가 남은 상황이라 조금 더 힘을 내야할듯 합니다. 😅 출퇴근 시간에 읽은 조영호 저자님의 객체지향의 사실과 오해
에 대해 후기를 남기려고 합니다. 책 내용 정리보다는 제가 이해한 내용을 바탕으로 글을 쓰려고 합니다.
객체지향 프로그래밍은 우리가 실생활에서 인지하고 있는 객체를 소프트웨어에 투영시킴으로써 기억하기 쉽고 이해하기 쉬운 소프트웨어를 만드는데 초점이 맞춰져있습니다. 하지만 실생활의 객체를 그대로 옮긴 것은 아닙니다. 소프트웨어 세상은 현실에 없는 객체도 존재하고 현실세계에서 대부분의 객체는 자율적인 의지가 없어 스스로 행동할 수 없지만 소프트웨어 세상에서 객체는 의지를 갖고 행동할 수 있습니다. 이를 저자는 객체의 의인화
가 가능하며 소프트웨어 세상은 실세계를 그대로 옮겨놓은 것이 아닌 은유
한 세계라고 설명합니다.
역할, 책임 그리고 협력
Java
진영 라이브러리들에서 변수, 메서드의 이름이나 설명을 보면 역할, 책임, 협력에 관한 이야기가 많이 나옵니다. 이 3가지 용어가 정확히 무엇을 의미하는지 이 책의 저자가 알려줍니다.
책임이란 객체가 메시지를 받았을 때 무엇을 해야 하는지를 나타냅니다. 여기서 어떻게
가 아닌 무엇을
결장한다는 것이 중요합니다. 이는 인터페이스와 구현을 분리해 자유로운 객체를 만들 수 있게 해줍니다. 그렇게 되면 클라이언트 코드는 객체의 변경사항에서 자유롭겠죠? 역할은 객체에 책임들이 모여 그 객체가 다른 객체들 사이에서 나타나는 의미를 말합니다. 이런 역할은 일반화/특수화 관계로 추상화 시키면 다른 객체도 그 역할을 대신할 수 있게되면서 객체지향 설계의 수준을 높입니다. 마지막으로 협력은 이런 객체들의 역할이 서로 어우러지면서 사용자가 기대하는 결과나 행동을 수행하는 것을 말합니다. 우리의 최종 목표인거죠. 뒤에 말하겠지만 설계를 할 때는 협력 -> 책임 -> 역할 순으로 고려를 하게됩니다.
타입과 클래스
타입은 객체의 추상화 방법중 하나로 여러 객체의 구체적인 부분을 하나의 개념으로 표현한 것입니다. 이런 타입을 프로그래밍으로 구현하는 방법 중 하나가 클래스이고 프로토타이핑 언어에서는 프로토타입으로 이를 구현할 수 있다고 합니다. 그리고 설계를 할 때는 하나의 객체가 여러 타입일 수 있고 다른 타입으로 이동하는 경우도 생기지만 대부분의 프로그래밍 언어에서는 단일 분류, 정적 분류만 지원하므로 프로그래밍을 할 때 자연스럽게 다른 객체로 변하게 해야 합니다.
도메인 모델과 설계
도메인 모델이란 도메인을 표현하는 개념적인 모델이라는 뜻으로 위키피디아에 써있습니다. 이것만 봐서는 무슨 뜻인지 와닿지 않지만 저자가 말해주는 특징을 들어보면 어떤 용도로 쓰이는지 대략 알 수 있습니다. 도메인 모델은 사용자가 시스템에 바라는 목표를 수행할 수 있는 시스템안에 작은 시스템들을 개념적으로 나타낸 것입니다. 예를 들어 커피 주문 도메인에서는 주문, 바리스타, 주문 메뉴, 손님, 커피 등이 있고 손님은 주문을 알고있고 바리스타는 메뉴와 커피를 알고 있겠죠. 이렇게 대략적인 개념 용어와 개념간의 관계에 대해 표현하는 것이 도메인 모델입니다. 이 도메인 모델은 비지니스 로직이 크게 바뀌지 않는 이상 바뀌지 않아야 합니다. 프로그래밍을 하면서 도메인을 수정하는 일은 많이 일어납니다. 하지만 기본적으로 개념과 개념간의 관계는 바뀌는 경우가 없어야 합니다. 그래서 클린 아케텍처나 이를 일반화한 헥사고날 아키텍쳐에서는 도메인 모델을 가장 아래 두어 다른 로직으로 부터 보호하는 아키텍처를 사용합니다. 도메인 모델은 거의 안바뀐다는 가정을 하고 있는 거죠.
이런 도메인 모델을 설계하고 난 뒤에는 3가지 방법으로 설계를 합니다. 책임-주도 설계
, 디자인 패턴
, 테스트-주도 개발
입니다. 먼저 책임-주도 설계는 객체에 주어진 책임에 따라 객채의 상태와 행동이 결정되야 한다는 것입니다. 객체의 상태와 행동은 가장 나중에 결정이 되어야 교체되어도 다른 곳에 영향을 덜 끼칩니다. 그러면 책임은 어디서 부터 나오는 걸까요? 객체가 받은 메시지로 부터 나옵니다. 그리고 메시지는 시스템 책임으로 부터 나오죠. 먼저 시스템 책임을 사용자 유즈케이스에서 추출한 다음 이 시스템 안에 도메인 모델에 있는 개념을 객체로 보고 책임을 수행할 수 있는 객체에게 줄 메시지를 설계하고 책임을 할당합니다. 이 객체가 책임을 수행할 수 없는 객체라고 생각이 되면 수행할 수 있는 객체에게 메시지를 전달해 책임을 전가합니다. 이게 What/Who 사이클이며 끝나면 협력이 완성되는 거죠. 즉, 아래 순서로 시스템의 전반적인 책임,협력 그리고 역할이 설계되는 것입니다.
1
시스템 책임(사용자가 기대하는 것) => 메시지, 책임(메시지를 먼저 생각하고 이를 수행할 수 있는 객체에게 할당, What/Who 사이클) => 객체의 상태와 행동을 결정함
디자인 패턴은 위 설계 과정을 패턴화 시킨 것입니다. 다른 개발자들이 설계를 해놓은 디자인 패턴을 가져다 쓰면 시간도 절약하고 규모의 경제로 잘 설계되어 있을테니 안정성도 높겠죠. 개발에 적극 활용합니다. 자바 디자인 패턴 레포지토리 테스트-주도 개발은 설계과정이 끝나고 개발을 할 때 객체의 책임을 완벽히 수행하면서 필요없는 로직이 생기지 않게 실패하는 테스트를 짜고 이를 성공시키는 코드를 짠뒤 리펙토링 과정을 거치면서 작동가능한 깔끔한 코드를 만드는 방법입니다. 저자는 핵심은 책임을 객체에 할당하는 설계과정이지 테스트-주도 개발은 이를 도와주는 장치라고 말합니다.