[Book리뷰] 객체지향의 사실과 오해

devdo·2022년 1월 5일
0

Book리뷰

목록 보기
1/8
post-thumbnail

감히 이책을 읽지 않고서 객체지향에 대해서 제대로 이해했다고 얘기할 수 없을 것 같다. 다 읽고 나서 든 생각이다. 이 책을 읽고나서 내가 객체에 대해서 제대로 오해한 부분이 드러나게 되었다.

오해1. 객체는 실세계를 모방하는 것이다.
오해2. 객체는 독립적인 것이다.
오해3. 객체는 행동보다 상태로 결정된다.

이 세 가지 오해에 대해서 제대로 짚어볼 수 있게 되었다.

오해1. 객체는 실세계를 모방하는 것이다.

아니다. 객체는 객체간 메시지를 전달하며 협력을 하는 존재들이다.

객체란 실세계를 모방하는 것이 아니다. 예를 들어 내가 처음에 클래스를 만들 때, 자동차 클래스를 만들고 그안에 모델명,색상,바퀴,기어 등을 넣고 전진, 후진 등의 기능으 가진 객체를 만들어 객체의 상태와 기능을 심어주었다.

앞서 자동차의 경우, 객체세계에선 자동차는 스스로 시동걸기와 주행의 기능을 가진다. 그리고 '사람'이 '자동차'에게 요청(메시지)를 보낼 뿐이다. 객체 세계에서는 자동차는 마치 하나의 생명체 같이 자율적으로 메시지를 받으며 처리한다.


오해2. 객체는 독립적인 것이다.

객체는 독립적인게 아니라 자율적이다.

무슨 말이가 하면, 객체의 핵심은 서로 협력적이라는 것이다.

혼자 모든걸 해결하려 하지 않는다는 게 중요하다. 객체가 자율적이라는 것은 데이터(상태)와 프로세서(행위)를 분리하지 않고, 둘다 스스로 전문가로서 그 분야의 데이터들을 가짐으로써 자율적인 존재라 생각하고 그 분야의 데이터를 원하면 그 분의의 전문가인 객체에게 물어보라는 것이다.

이 책에서는 객체 지향에 대해서 이렇게 정의한다.

  • 객체지향이란 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법
  • 자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.
  • 객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.
  • 객체는 다른 객체와 협력하기 위해 메세지를 전송하고, 메세지를 수신한 객체를 메세지를 처리하는데 적합한 메서드를 자율적으로 선택한다.

객체 라는 단어는 역할, 책임, 협력, 메시지라는 단어와 뗄레야 뗄 수 없는 것이다. 하지만 독립이라는 단어는 알맞지 않다!

추가적으로 행동은 메시지를 수신하였을 때 메시지 처리 방법이고, 이 처리 방법(method)을 메서드라고 부른다.


오해3. 객체는 행동보다 상태로 결정된다.

객체의 상태보다 행동으로 결정하는 것이다

이 책에서는 객체를 또 이렇게 표현한다.

"객체란 식별 가능한 개체 또는 사물이다. 구체적인 사물또는 추상적인 개념일 수 있다."

식별이라 함은 말 그래도 객체는 식별이 가능하다는 뜻이다. 이런 이유로 객체가 독립적이라는 오해가 살만하다. (핑계같지만...)

그렇다. 객체의 행동이 상태를 결정하는 것이다

앞서 자동차 클래스를 만들때 보통 모델명,색상,바퀴,기어 등 상태부터 결정해서 만들려고 한다고 했다. 이와 같은 접근은 잘못된 것이다. 객체세계 말하는 객체는 어떤 메시지를 주고 받으면서 협력을 한다고 했다. 즉 행동을 생각한 후, 행동을 할 객체를 선택, 필요한 속성이 결정되어야 한다.

이런 객체의 행동은 객체가 해야할 책임이라고 표현하기도 한다. 객체지향 설계라 함은 어떤 행동 즉 책임이 필요한가를 결정하는 과정이 전체 설계를 주도해야 한다는 뜻을 내포한다. 이에 따라 객체가 선택되고 속성이 정의되는 것이다.

이 같은 방법을 따르면 응집도도 높아지고 재사용이 가능한 객체를 만들 수 있게 해준다.


그래서 객체지향이란? 협력, 행동, 책임, 역할 그리고 추상화

이 책에서는 객체지향에서 이 단어들을 계속 강조한다. 그리고 추상화로 이어지는 다음과 같은 결론을 도출한다.

객체는 협력 속에서 책임에 따른 역할(추상화)이 존재한다.

예를 들어 사람이 자동차에 시동을 건다고 해보자.
자동차는 승용차, 세단, 트럭 어떤 객체가 될지 모르지만 '자동차'라는 역할은 들어있는 것이다. 즉 이 역할이라 함은 객체가 뭐가 될진 모르겠지만 꼭 하게 되는 일반화된 것을 말한다. 이걸 객체 추상화라고 하는 것이다.

추상화는 세부적인 사항을 제거하고 메시지의 의도를 표현하려는 목적으로 사용한 기법

협력 또한 추상화할 수 있다고 말한다. 사람이라는 역할이 자동차라는 역할에게 시동을 걸라는 메세지를 요청한다. 이때 자동차라는 역할은 스스로 시동을 걸고 어떠한 행동이나 응답을 해야 하는 책임이 생긴다.

그런데 시동을 거는 방식이 자동차마다 다르다. 이 시동을 거는 방식이 추상화할 수 있는 것이다. 이 추상화는 나중에 자세하게 말하겠지만 인터페이스로 구성한다!


객체지향 설계 기법

이런 것도 잘 정리되어 있었다

책임-주도 설계

객체세계에서 협력을 통해 책임 식별후, 적합한 객체에 책임을 할당하는 방식
여태 강조한 협력속에서 어떤 책임이 필요하고, 어떤 객체가 필요한지 결정하는 과정이 전체 설계 자체를 주도하는 방식
그전 방식인 데이터-주도 설계에서 객체지향을 위해 바꾼 방식이다.

전문가 주도 설계

객체세계에서 협력을 통해 책임을 가지는 각 객체들은 전문가들이다.
그 전문가들에게는 모든 것을 요청하지 않는다. 단지 말할 뿐이다. (Don't ask, Just Tell)

디자인 패턴

정해진 협력, 책임, 역할의 템플릿으로, 책임-주도 설계의 절차를 따르지 않고도, 빠르게 협력, 책임, 역할을 선택 가능

테스트 주도 개발

책임을 수행할 객체 또는 클라이언트가 기대하는 객체의 역할이 메세지를 수신할 때 어떤 결과를 반환하고, 그 과정에서 어떤 객체와 협력할 것인지에 대한 기대를 코드의 형태로 작성하는 방식
이 과정에서, 테스트 코드는 덤이고, 리팩토링을 하는데 더 부담이 적어진다는 이점들이 존재


역할과 구현의 분리, 인터페이스의 다형성

아까 협력 또한 추상화할 수 있다고 말했다. 이것은 어떤 객체가 협력을 위한 똑같은 메시지를 다른 객체들에게 보내게 하여 수신한 객체들이 다르게 협력할 수 있다는 말이다. 이같은 것이 다형성이다.

이와 함께 요청한 객체, 송신자는 수신한 객체가 누구인지 상관없다. 그래서 수신자의 외부와 내부처리를 분리하는 캡슐화도 가능하다.

객체의 외부 내부 구성

객체의 외부 : 공용 인터페이스
객체의 내부 : 구현(Implementation)

다형성이란

  • 송신자는 수신자가 누구인지 상관없이 메세지만 수행하면 된다.
  • 메세지만 변경이 없다면, 수신자를 변경하거나 수정해도 송신자에겐 영향이 없다.
  • 협력에 영향 없이 다양한 적절한 객체들이 수신자로 대체할 수 있다.

인터페이스는 캡슐화 기능을 가지고 구현을 숨겨놓는다.


왜 인터페이스가 중요할까?

소프트웨어는 항상 변경되기 때문이라고 한다.

수많은 객체들이 협력하며 작동하는 객체지향 세계에서 어떤 객체를 수정했을 때 다른 어떤 객체가 영향을 받을지 판단하는 것은 거의 불가능하다고 한다.

"객체의 모든 것이 외부에 공개되어 있으면 아무리 작은 부분을 수정하였어도 변경에 의한 파급효과가 객체 공동체의 구석구석까지 파고들 것이다."

그래서 미래에 변경이 가능한 부분은 객체의 내부에 감춰놓아야 하는 것이다.

송신자와 수신자가 구체적인 구현 부분이 아니라 느슨한 인터페이스에 대해서만 결합되도록 만드는 것이다.


도메인 주도 설계 - 커피주문

이 책에서 지금까지 배운 걸 바탕으로 커피주문을 하는 프로그램 예제를 보여준다. 이 블로그에서 잘 정리되었다.
https://mindock.github.io/book/the-essence-of-object-orientation-7/


✅ 객체 지향 설계 생각 순서

1) 도메인을 구성하는 객체에는 어떤 것들이 있는지 고민
2) 객체들 간의 관계를 고민
3) 동적인 객체를 정적인 타입으로 추상화해서 도메인 모델링 하기
4) 협력을 설계
5) 객체들을 포괄하는 타입(클라이언트와 소통하는 퍼블릭 인터페이스)에 적절한 책임을 할당
6) 구현하기

참고) 객체지향 세계에서는 모든 객체가 능동적(자율적)인 존재


정리

  1. 실제는 객체와 현실은 전혀 다른 세계이기 때문에 그 차이를 인지하고 객체지향적으로 접근하는 것
  2. 객체의 타입이든, 속성이든 정의를 하기 위해선 객체와 객체 사이 어떤 메세지가 주고 받을지 즉 행동을 최우선으로 생각하고, 그에 따른 객체의 타입과 속성을 결정해야 한다.
  3. 협력을 설계하고, 협력에서의 책임을 기준으로 전체적인 설계가 주도되어야 한다.쉽게 말해 메세지를 먼저 정하고, 해당 책임들을 역할(객체)에개 적절하게 할당하는 방식으로 설계가 주도되어야 한다.
  4. 메세지를 기반으로 책임을 자율적으로 만들어야 한다.
  5. 요구사항을 식별, 도메인 모델을 생성한 후, 코드를 작성, 요구사항을 충족시키기 위해 객체들간의 메세지 전송을 정의해야 한다.


참고

https://woozzang.tistory.com/152
https://lee1535.tistory.com/125

profile
배운 것을 기록합니다.

0개의 댓글