본문 바로가기

책, 강의 정리/객체지향의 사실과 오해

객체지향의 사실과 오해 - 1, 2 장(협력하는 객체들의 공동체, 이상한 나라의 객체)

 

객체지향을 간과하고 Java를 쉽게 생각하고 Spring Boot 에 재미를 먼저 들여서 그런지 좋지 않은 습관이 많이 생겼다. 스터디에서 코드 리뷰를 받아보니 나는 기본적인 코드 컨벤션조차 잘 지키지 못하는 사람이었고 나름 또래 중에서 코딩을 잘하는 줄 알았던 지난 시간들을 되돌아보기도 했다.

 

 

Java 8 을 먼저 공부해야하나 객체지향을 공부해야하나 클린코드를 공부해야하나 이런 저런 고민이 들던 중 스터디에서 조영호님의 "객체지향의 사실과 오해"라는 책을 읽게 되었다.

 

 

이 책의 특징은 "엘리스" 이야기를 예로들어 설명한다는 것이다(그 분량도 짧지 않다). 스터디에서 이러한 방식의 장단점에 대한 얘기가 나왔었다. 나도 사실 딱딱 정리된 책을 선호하는 편이지만 객체지향 같은 경우는 한번에 이해할 수 없었고, 사실 몇번씩이나 그 정의를 찾아봐도 딱히 이해된 적이 없었기 때문에 결과적으로는 나를 이해시키는데 이만한 책은 없을 것이라고 생각한다.(그렇다고 완벽하게 객체지향을 알겠다는건 당연히 아니다.)

 

 

책 완독은 끝냈고, 정리했던 내용을 바탕을 재정리해보려고 한다.

 

 

본 포스팅은

    1. 협력하는 객체들의 공동체

    2. 이상한 나라의 객체

를 함께 정리한다.

 


 

요약

 

"소프트웨어의 세계와 실세계 사이의 거리는 멀다. 오히려 소프트웨어 세계의 객체가 실세계의 사물보다 더 많은 능력을 가지고 있다. 굳이 둘 사이의 관계를 얘기하자면 일치보다는 은유에 가깝다"

 

 

객체지향을 검색해보면 가장 많이 나오는 말이 "현실을 객체화하는 것"이다. 따라서 이러한 설명은 굉장히 신선했지만, 바로 이해할 수 있었다.

 

예를들어, 계산기라는 객체는 덧셈, 뺄셈, 곱셈, 나눗셈 네가지의 기능을 가질 수 있다고 가정하자.

계산기 클래스에서 생성된 인스턴스는 스스로 사칙연산을 수행하지만, 현실의 계산기는 스스로 수행하는 것이 아닌 사람이 누르는대로 수행한다.

 

위에서 말한 것처럼 "실제 사물보다 더 많은 능력을 가지는 것"이다.

 

 

객체지향의 주요 개념

 

역할(Role)과 책임(responsibility)

  1. 여러 객체가 동일한 역할을 수행할 수 있다.

    - 커피는 바리스타도 만들 수 있고, 사장님도 만들 수 있고, ..

  2. 역할은 대체가능성을 뜻한다.

    - 그 말은 바리스타를 사장님이 대체할 수도 있단는 것이다.

  3. 책임은 다양한 방법으로 수행될 수 있다.(다형성의 개념이 여기에서 나올 수 있음)

  - 커피를 만든다는 책임은 커피를 만드는 것이지 "어떻게"만드는 가는 상관 없다.

  - 커피머신으로 커피를 만들든, 드립커피를 만들든 상관 없다. 커피를 만들어내기만 하면 책임을 수행하는 것이다.

  - 역할은 관련성 높은 책임들의 집합이다. 즉, 역할이 있다는 것은 책임이 있다는 것. "바리스타"역할을 가졌다면 "커피  를 만들 책임"이 있는 것이다.

 

 

협력

  1. 각 객체들은 고립된 것이 아닌 서로 간의 협력을 통해 시스템을 구성한다.

  2. 연쇄적인 요청과 응답을 통해 협력을 이루어낸다.

  3. 손님 객체가 카운터 아르바이트생에게, 아르바이트생 객체가 바리스타 객체에게 요청함으로써 "커피주문"이라는 협력이 이루어진다. 

 

 

"애플리케이션은 다양한 기능을 제공하고 이 기능은 여러 역할을 가진 객체들의 책임을 통해 수행되며 그 객체들은 다른 객체들과 연쇄적인 요청과 응답의 흐름을 통해 협력한다."

 

 

객체

 

  1. 객체는 충분히 협력적이어야 한다.

  2. 요청에 대한 응답을 하는 것은 사실이지만 그것이 수동적이라는 의미는 아니다. 응답하는 방식은 객체 자신이 자율적으로 결정한다.

  3. 즉, 객체는 충분히 자율적이어야 한다.

  4. 객체는 다른 객체가 무엇을 수행하는지는 알 수 있지만 어떻게 수행하는지는 알 수 없다.

  5. 이는 캡슐화와 연결된다. 

  6. 아르바이트 객체는 바리스타 객체가 "커피를 만든다"는 책임을 수행하는 것은 알지만, 어떻게 만드는지는 모른다. 몰라도 된다. 바리스타 객체는 "커피를 만든다"는 책임만 수행한다면 어떻게 만들든 상관없다. 충분히 "자율적"으로 결정할 수 있다. 

 

 

상태

  1. 객체가 과거에 행동한 이력을 설명하지 않고도 지금 하는 행동의 결과를 알 수 있도록 한다.

  2. 자동차 객체가 전진하고 나서의 위치를 알려면 그간의 이력 전부를 보는 방법도 있지만, 바로 이전의 상태를 안다다면 "얼마나 전진했는지"만 알면 현재 위치를 알 수 있다.

  3. 상태는 값이 될수도 있고 다른 객체가 될 수도 있다.

 

 

행동

  1. 행동은 상태에 영향 받고 상태에 영향을 준다.

  2. 전진하는 행동은 위치라는 상태에 영향을주고, 위치라는 상태는 전진하는 행동에 영향을 준다.(더이상 전진할 수 없을 수도)

  3. 외부에 가시적이다. -> 객체의 행동은 공용 인터페이스로 외부에 노출될 수 있다. 그래야 다른 객체에게 요청을 할 수 있으니까.

 

 

중요한 점은, 

 

"객체 설계는 행동에 초점을 맞추어야 한다." 는 것이다.

 

상태를 결정하고 행동을 결정한다먄, 상태를 노출시킴으로써 캡슐화를 저해할 수 있다. 또, 협력에 초점을 맞추기도 어려울 것이다. 행동에 초점을 맞춘 설계를 한다면 협력을 행동(요청)의 연속으로 이루어낼 수 있고 명확한 설계가 될 수 있다.