객체지향의 사실과 오해

코지클래식·2021년 12월 15일
0

들어가면서

객체지향의 사실과 오해

책을 읽고 내용을 정리해서 적어봅니다.
"객체지향의 사실과 오해"는 코드에 대해 모르는 부분이 많아도 비교적 쉽게 읽을 수 있는 책입니다.

코드로 설명되어 있는 부분이 없습니다. 입문자에게 추천드립니다.




주제: 함수를 기준으로 삼아라.

이 책에서는 처음부터 끝까지 끊임없이 하나의 주제를 이야기 하고 있습니다.
그것은 바로 함수를 기준으로 프로그램을 설계 하라는 것 입니다.

객체지향 프로그래밍의 3요소

객체를 갖는 프로그래밍은 3가지의 요소를 갖습니다. 1)책임 2)협력 3)역할입니다.

카페에서 고객이 커피를 주문하고 받는 과정을 3가지 요소에 맞추어 설명 해보겠습니다.
이는 달리 말하면 프로그램에서 객체가, 요청을 하고 응답을 받는 과정입니다.

  • 책임 : 주문을 받은 카페 직원은 커피를 고객에게 전달할 책임을 갖는다.

  • 역할 : 고객은 커피를 주문해야 한다. 직원은 커피를 전달해야 한다.

  • 협력 : 커피를 전달하기 위해, 주문을 받은 카페 직원은 다른 직원에게 요청하거나, 기계를 사용하거나, 이미 만들어둔 커피를 꺼내는 등의 다양한 협력을 할 수 있다.

1. 책임과 자율성

객체지향에서 책임이란 "자율적이어야 하며 스스로의 행동을 책임지는 것" 입니다.

주문을 받은 카페 직원의 책임은 '커피를 고객에게 주는 것'입니다.
주문을 한 고객은 '커피를 받기 위해 어떤 물을 쓰고, 어떤 기계를 쓰고, 어떤 직원이 작업을 하는지' 신경쓰지 않습니다. 그저 '커피를 받는것'에만 관심이 있습니다.

따라서 카페직원은 커피를 주는 책임을 해결하기 위해서
자율적으로 여러가지 기계를 사용하거나 다른 직원에게 요청을 할 수 있습니다.

이 설명을 프로그래밍으로 바꾸어 보면
요청이란 객체 외부에서 오는 요청/request를 말하며,
책임이란 request를 응답할 책임을 뜻합니다.

객체에서 책임은 내부 필드 또는 메소드로 외부에 응답 가능합니다.

2. 역할

역할에는 2가지 의미가 있습니다.

  1. 대체가능성
    카페 직원은 주문하는 고객이 바뀌어도 신경쓰지 않습니다.
    고객은 주문받는 직원이 바뀌어도 신경쓰지 않습니다.

  2. 다양성
    한 사람/객체는 여러 역할을 수행할 수 있습니다.
    카페직원은 주문을 받을수도, 커피를 만들수도, 설거지를 할 수 도있습니다.

프로그래밍으로 대입해 본다면
이는 동일한 클래스 또는 타입에 대해서
다른 메소드/함수들이 호환가능한 것을 뜻합니다.

3. 협력

협력이란 서로 다른 사람/객체들 사이에 요청과 응답을 주고받는 것을 뜻합니다.

모든 객체는 협력적이어야 합니다.

협력은 다수/연쇄적인 요청/응답으로 구성됩니다.

혼자 모든 것을 해결하려는 "god class"는
"언젠가 발생할 수 밖에 없는 에러"를 해결하기에 매우 난감합니다.

4. 결론

결국 객체는 책임(행동/메소드/함수)으로 정의될 수 있습니다.

객체의 책임이 없다면 협력은 일어날 수 없고

역할은 결국 동일한 책임을 갖는다면, 다른 데이터 타입을 사용하는 객체라도 대체 가능하기 때문입니다.

객체와 클래스

클래스란 무엇인가? (feat.데이터 타입)

객체/클래스는 흔히 "공통된 무언가를 갖는 것"이라고 표현됩니다.
그러나 이에 대해 조금만 더 생각해보면 "공통된 무언가"를 갖는 한가지가 있습니다.
바로 데이터 타입(type)입니다.

그렇다면 데이터타입은 어째서 같은 타입으로 분류될까요?
이 책에서는 다음과 같이 소개하고 있습니다.

"같은 값을 갖고 있기 때문"에 같은 타입이 되는 것이 아니다.
숫자끼리는 연산을 할 수 있는 것처럼,
알파벳끼리는 대/소문자를 변경할 수 있는 것처럼,
"같은 행동을 할 수 있기 때문"에 같은 타입이 되는 것이다.

데이터 타입이야말로 우리가 가장 편하고, 흔하게 사용하는 클래스 중의 하나일 것입니다.
숫자/문자의 기초 데이터 타입도 공통된 값(-2^16~ 2^16)을 기준으로 분류하지 않습니다.

이를 생각해보면 "동일한 행동"을 기준으로 하는 것이
프로그램을 설계할 대 "같은 데이터"를 기준으로 하는 것보다
더 근본적인 방법에 가깝다는 것에 대해 하나의 설득력을 가질 수 있습니다.

객체의 성질

  1. 객체는 어떤 상태에 있더라도 유일하게 식별 가능합니다.

  2. 객체의 행동은 객체의 상태에 영향을 받습니다.

  3. 객체의 행동은 2가지 효과가 있습니다.

    1. 자신의 상태를 변경한다.
    2. 요청을 받고 메시지를 전송한다.

객체를 만드는 법

책의 주제를 다시 한번 상기시켜보겠습니다.
객체를 만들 때에는 함수(행동)를 기준으로 삼아야 합니다.

  1. 행동이 상태를 결정한다
    값or상태를 기준으로 클래스를 만들지 말고, 행동을 기준으로 만들어야 합니다.
    객체가 내부적으로 관리하는 데이터를 고려하기 이전에 외부에 제공할 책임을 먼저 결정해야 합니다. 객체 내부의 데이터는 책임을 수행하기 위해 필요한 과정에서

추상화

1. 오해 1 - 클래스와 객체의 차이

책의 저자는 객체지향과 클래스지향의 차이를 구분해야 한다고 소개하고 있습니다.
책의 문구를 적어보겠습니다.

클래스가 객체지향 프로그래밍 언어의 관점에서 매우 중요한 구성요소(construct)임에는 분명하다.
그러나 객체지향의 핵심을 이루는 중심개념이라고 하기에는 무리가 있다.
지나치게 클래스를 강조하는 프로그래밍언어적인 관점은 객체의 캡슐화를 저해하고 클래스를 서로 강하게 결합시킨다.

흔히 하는 표현으로 객체는 "현실에서 우리가 프로그래밍적으로 표현하고 싶은 무언가를 추상적으로 표현하는 것"이라는 말이 있습니다.

여기에서 말하는 추상화를 생각할 때 흔히하는 생각은

  • 현실 세계의 무언가(사람)에 대해 "특정 부분(키, 몸무게, 이름)만 표현하는 것" 이 추상화다. 라고 생각한다는 것 입니다. 그러나 이는 오해입니다.

1. 객체가 뭔가 더 많을 수도 있다.

"사람"객체와 "물"객체가 있을 때, 사람이 "물"을 마신다고 표현하면,
현실세계의 "물"은 스스로 줄어들 수 없고 사람이 마시는 것에 의해서만 감소할 수 있습니다.
하지만 우리가 표현하는 "물"객체는 스스로 가지고 있는 메소드에 의해 감소합니다.

결론적으로, 우리의 생각과는 달리 객체는 현실세계에서 특정 부분을 제외한 무언가가 아니라, 스스로 자율적으로 움직일 수 있는 새로운 무언가인 것입니다.

2. 잘라내기

사람에 대해 표현할 때, 우리는 굉장히 다양한 것을 속성으로 정의할 수 있습니다.
키,몸무게,나이 뿐만이 아니라, 지문,혈액형,DNA,얼굴,눈,코,입, 등등..

자동차에 대해서도 흔히들 표현하는
색깔, 위치, 속도 뿐만이 아닌, 무게,회사,엔진종류, 옵션, 연도, 차번호 등등.. 다양한 속성이 있습니다.

그러나 우리는 프로그래밍을 할 때 이 모든것을 다 표현하지 않습니다.
우리에게 필요한 부분만 표현합니다.
사람이 갖고 있는 많은 속성 중에서도, 학생으로서의 성적만 표현한다던지 하는 것입니다.

진정한 의미의 추상화란 객체의 속성을 얼마나 잘 표현하는지 가 아닙니다.
현실에서 출발하되, 불필요한 부분을 도려내는 것입니다.

3. 일반화/단순화

위에 살펴본바와 같이 우리는 현실의 무언가를 프로그램으로 만들기 위해
불필요한 부분을 추려내고 단순화할 필요가 있습니다.
그리고 이렇게 단순화를 하다보면 사물들 간의 공통점을 조금 더 쉽게 찾을 수 있게 됩니다.

그렇다면 일반화 또는 단순화는 어떤 식으로 할 수 있을까요?

적어도 이 책의 설명 내에서는 일반화/특수화 관계를 결정하는 것은 데이터가 아닌 행동이라고 합니다.

물과 기름은 서로 다릅니다.
그러나 상온에서 흐르고, 끓는 등의 행동을 할 수 있습니다.
이를 일반화 시키면 액체라고 라고도 할 수 있습니다.

액체가 할 수 있는 행동을, 물과 기름은 모두 할 수 있지만
끓는 점이나 미끄러움 등이 다르다고 할 수 있는 것이빈다.

정리

1. 협력

책의 내용 일부를 따왔습니다.

객체지향에 갓 입문한 사람들의 가장 흔한 실수는
협력이라는 상황/문맥을 고려하지 않는 것이다.
각 객체가 가져야 할 상태와 행동부터 고민하는 것이다.
중요한 것은 개별 객체가 아닌 객체들 사이에 이루어지는 협력이다.
객체지향 설계의 전체적인 품질을 결정하는 것은
개별 객체의 품질이 아닌 여러 객체들이 모여 이뤄내는 협력의 품질이다.

2. 책임

책임의 구성

  1. 객체가 아는 것(Knowing)
  • 개인적인 정보에 대해 아는 것
  • 관련된 객체에 대해 아는 것
  • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것
  1. 하는 것(Doing)
  • 객체를 생성하거나 계산하는 등 스스로 하는 것
  • 다른 객체의 행동을 시작 시키는 것
  • 다른 객체의 활동을 조절/제어 하는 것
  1. 책임과 메시지
    객체는 다른 객체로부터 요청을 받았을 때에만 책임을 수행한다.
    따라서 좋은 코드를 만들기 위해서는, 메시지(arg)에도, 행동/요청(method)에도 의미가 부여되어야 한다.

3. 역할

동일한 책임을 지는 개체들은 동일한 역할을 수행한다.
따라서, 각 객체는 대체 가능하다. (동일한 책임을 지지 못하는 객체는 아님)

채김은 Input/Output, 즉 메소드/함수에서 비롯된다.
따라서, 동일한 데이터가 아닌 메소드가 기준이 되어야 한다.

  • 객체가 가져야 하는상태/행위에 대해 고민하기 전에 객체가 참여할 문맥인 협력을 정의해야 한다.
  • 자율적 + 협력적을 동시에 챙기는 가장 쉬운 방법은 객체를 협력적으로 만든 이후, 그 내에서 객체를 자율적으로 만드는 것이다.
profile
코지베어

0개의 댓글