커피를 통해 배우는 OOP - 1

suky·2021년 8월 16일
0
post-thumbnail

안녕하세요. suky입니다~
부스트캠프 챌린지가 끝나고 챌린지 기간을 돌아보며 제 코드가 많이 부족하다! 라는 생각이 들어 코드에 대한 공부를 하고 있습니다. (챌린지 열심히 하다가 쉬려고 하니깐 쉽지 않네요 😂)
그 중 OOP(Object Oriented Programming)가 무엇인가?에 대해 생각을 많이 하고 있습니다 (오오피!)

챌린지 기간 중 '객체지향의 사실과 오해'라는 책을 소개받아 이 책을 읽고 저만의 방식으로 정리해보려고 이 포스트를 작성하게 되었습니다 :)

객체지향 프로그래밍

객체지향 프로그래밍(OOP)이란?

객체지향 프로그래밍이란 무엇일까요!? 제가 책을 읽기 전 다음과 같은 생각을 많이 했었습니다. (여러분도 그러신가요 ㅎㅎ??)

  • 클래스를 이용하여 상속받아 작성하는 프로그래밍 패러다임
  • 현실 세계를 모방하여 프로그래밍 하는 것

뭔가 많은 분들이 하실만한 생각이라고 생각해요! (저만 그런가요 ㅎㅎ? 🤣)
그럼 우리들의 백과사전 위키백과에는 어떻게 나와 있을까요?

위키에는 프로그램을 메시지를 주고 받고, 데이터를 처리하는 객체의 모임으로 파악하는 것이라 나와있네요!

그렇다면 '객체'가 무엇인지 알아야 객체를 지향하는 프로그래밍을 할 수 있을 것 같단 생각이 드네요.

객체

객체는 무엇일까요?

자바스크립트에서는 {}의 자료형이 Object라고 하는데 이것이 OOP에서 의미하는 객체의 전부일까요??
위키백과에는 다음과 같이 나와있습니다.

호오! 위키백과에서는 객체를 다음과 같이 묘사하네요.

  • 객체는 클래스의 인스턴스
  • 객체가 메시지를 받고 자료를 처리함

근데 이 객체는 위에서 typeof {}로 묘사된 구체적인(?) 객체인 것 같습니다.
과연 그렇다면 이것이 OOP에서 말하는 객체의 모든 설명일까요???

책에서는 객체를 정말 추상적으로 묘사합니다.

  • 하나의 개별적인 실체로 식별 가능한 물리적인 또는 개념적인 사물은 어떤 것이라도 객체가 될 수 있다.
  • 인간의 인지 능력 안에서 개수를 셀 수 있고, 다른 사물과 구분할 수 있으며, 생성 시점을 알 수 있고, 독립적인 하나의 단위로 인식할 수 있는 모든 사물은 객체다.
  • 객체의 다양한 특성을 효과적으로 설명하기 위해서는 객체를 상태(state), 행동(behavior), 식별자(identity)를 지닌 실체로 보는 것이 가장 효과적이다. (Grady Booch - Object Oriented Design)

이를 책에서는 다음과 같이 정의했습니다.

객체란 식별 가능한 개체 또는 사물이다. 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다. 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다. 소프트웨어 안에서 객체는 저장된 상태와 실행 가능한 코드를 통해 구현된다.

호오! 많이 추상적이죠? 그리고 앞서 typeof {}로 설명된 객체는 소프트웨어 안에서의 객체라고 볼 수 있겠네요.

저는 이제 위의 개념을 이용해서 객체를 설명할 것입니다 :)

객체의 3가지 특성

Grady Booch가 Object Oriented Design에서 언급했듯 객체를 3가지의 특성(상태, 행동, 식별자)을 가지고 바라보았습니다. 각각 어느 느낌인지만 간단하게 집고 넘어가겠습니다.

상태 (State)


상태는 객체가 지금 어떤 상태인지를 나타내는 나타내는 것입니다. (GNU is not UNIX)
예를 들어 배고픈 사람이라고 하면 '배고픈'이 상태를 대변할 수 있을 것 같네요!
물론 상태는 더 다양합니다~

행동 (Behavior)


행동은 객체가 할 수 있는 행위입니다. 행동은 상태에 의해서 바뀔 수 있고, 행동을 하면 상태가 바뀔 수 있습니다. 다음과 같은 예시가 있겠네요!

  • '배고픈' 사람 => 음식을 먹을 행동을 할 수 있음
  • '배부른' 사람 => 음식을 먹을 행동을 할 수 없음

배고픈 상태면 음식을 먹을 수 있습니다.
음식을 먹다보면 언젠간 포만감이 차게 되어 상태가 배고픈 => 적당한 => 배부른 상태로 바뀌게 될 것이고, 배부르다면 음식을 먹을 수 없습니다.

이것이 행동과 상태의 상관관계입니다.
설명이 이렇지만 행동과 상태의 상관관계에 대해서 느낌이 오셨으면 좋겠습니다. 😄...

식별자 (Identity)

식별자는 객체가 이 객체다! 라고 식별할 수 있는 것을 의미합니다.
객체는 자율적인 친구라서 시간에 따라서 바뀝니다. 사람도 마찬가지죠?
근데 이 사람이 이 사람이다!라고 다들 판단을 합니다. 어떻게 할까요? 다음 예시를 통해 식별자의 느낌을 알아봅시다!

  • 10년전 suky는 키가 a였고, 몸무게가 b입니다. 근데 현재의 suky는 키가 a'이고, 몸무게는 b'입니다.
  • 현재 suky는 키가 a이고, 몸무게가 b입니다. 홍길동 군은 키가 a이고, 몸무게가 b입니다.

객체는 시간에 따라 상태가 달라집니다. 마치 첫 번째 예시처럼요!
10년전 suky는 키가 a이고 몸무게가 b인데 현재는 a', b'라고 한다면 같은 suky가 아닌건가요?
똑같은 suky입니다!

다음 두 번째 예시를 보겠습니다. suky의 상태와 홍길동 군의 상태가 같군요!
그럼 둘은 같은 사람일까요? 둘은 다릅니다! ㅎㅎ (제가 알고있어요!! 다르다는 것을!!!)
물론 상태는 같죠!

첫 번째 예시처럼 시간에 따라 상태가 바뀌어도 동일하다고 판단할 수 있는 성질을 동일성(Identical)이라고 하고, 두 번째 예시처럼 값을 가지고만 상태를 비교할 수 있는 성질을 동등성(Equality)라고 합니다.

객체 지향의 세 가지 관점 (역할, 책임, 협력)

자! 이제 돌고 돌아서 객체 지향 프로그래밍에서 중점적으로 보아야 할 세 가지 관점으로 왔군요!
객체 지향 프로그래밍에서 중요한 핵심은 클래스를 상속받는 단순한 것이 아닌 문제를 세부 문제로 분할하고 객체들의 협력을 통해 해결하는 것입니다!
이를 위해서는 객체마다 역할이 있고, 그 역할에 따른 책임을 수행하고, 협력하여 해결하는 방식으로 수행되어야 하죠!
그럼 책에서 가장 중요하게 언급되었던 역할, 책임, 협력에 대하여 알아볼까요?

역할

역할은 책임의 집합입니다!
라고 설명해서는 어떤 의미인지 와닿지 않을거라 생각합니다 ㅎㅎ (저도 그렇거든요!😋)

학창시절을 떠올려봅시다. 반에는 선생님과 학생이 있죠? 추상적이지만 저는 두 가지의 개념으로 역할을 나누어보았습니다.
선생님과 학생을 떠올리면 어떤 것이 떠오르시나요? 저는 다음과 같네요.

  • 선생님 - 학생들을 가르친다. 수업을 준비한다. 발표를 시킨다. 등등
  • 학생 - 수업을 듣는다. 발표를 지목당하면 발표를 한다. 떠든다. 등등

선생님과 학생을 생각하면 떠오르는 그런 생각들이 역할이라고 생각하시면 됩니다.

역할에는 중요한 특성이 있습니다. 바로 대체가 가능하다는 뜻이죠.
객체들끼리는 다른 객체에게 메세지를 전했을 때 원하는 결과만 도출이 된다면 누구에게 메세지를 보내든지 상관하지 않아요! 예를 들어볼까요?

A 수학 선생님이 처리해야할 바쁜 일이 생기셔서 B 수학 선생님이 대신 오셨습니다.
엇! 선생님이 다르네요!! 수업이 될까요??
당연하죠! 수학 선생님이라는 역할이 똑같으므로 대신 수업을 진행하셨습니다.

대체가 가능한 것이 어떤 느낌이 아시겠죠? 수업 스타일이 다르셨지만 결국 수업을 수행하셨네요. (책임을 수행하는 방식이 다르겠지만 책임을 이행함)
책임을 수행하지만 방식이 다양한 것을 객체지향 프로그래밍에서는 다형성(polymorphism)이라고 합니다!
암시적이지만 추상적인 이 역할이 잘 정의되어야지만 대체가 가능하고 재사용성이 높은 코드를 생산할 수 있다고 합니다.

책임

역할은 책임의 집합이라고 했습니다. 역할의 의미를 보았을 때 책임은 어떤것일까요?

  • 선생님 - 학생들을 가르친다. 수업을 준비한다. 발표를 시킨다. 등등
  • 학생 - 수업을 듣는다. 발표를 지목당하면 발표를 한다. 떠든다. 등등

바로 어떤 것을 행동하는 것입니다.
제가 행동이라고 했나요!? 그렇습니다. 책임은 객체의 3가지 특성 중 행동과 아주 밀접한 관련이 있어요.
다시 말해서 어떤 객체가 어떤 요청에 대하여 대답해줄수 있거나 행동을 할 수 있는 경우 책임이 있다라고 표현합니다.

위에서 표현을 했듯이 선생님은 학생을 가르치고, 수업을 준비할 책임이 있습니다.
또한 학생은 수업을 듣고, 지목당할 시 발표를 하는 등의 책임이 있습니다.

이렇듯 역할에 대한 의무를 책임이라고 합니다.
크레이그 라만은 하는 것(Doing)과 아는 것(Knowing) 2가지로 책임을 분류했습니다.

  • 하는 것 (Doing)
    - 객체를 생성하거나 계산을 하는 등 스스로 하는 것
    - 다른 객체의 행동을 시작시키는 것
    - 다른 객체의 활동을 제어하고 조절하는 것
  • 아는 것 (Knowing)
    - 개인적인 정보에 관해 아는 것
    - 관련된 객체에 관해 아는 것
    - 자신이 유도하거나 계산할 수 있는 것에 아는 것

선생님이 학생에게 발표를 시킬려면 특정 학생에게 발표를 시켜야겠죠.
즉 알고있는 객체(Knowing)에게 메시지를 전달하는 행위(Doing)라고 표현할 수 있겠네요!
한 가지 예시를 들었지만 책임의 종류는 어마어마하게 많아질 수 있답니다.

책임-주도 설계(Responsibility-Driven Design)라는 것이 있을 정도로 OOP에서는 책임이 매우 매우 중요합니다.

협력

협력은 객체가 객체에게 메시지를 전달할 때 시작돼요.

선생님이 학생에게 발표를 시키면 학생이 발표를 하는 등 메시지를 받으면 책임을 수행합니다. 만약 학생이 모르겠다면 짝꿍에게도 물어볼수도 있죠.

이렇듯 결과적으로 협력은 다수의 요청과 응답으로 구성되며, 전체적으로 협력은 다수의 연쇄적인 요청과 응답의 흐름으로 구성됩니다.

협력을 위해서는 메시지의 전달과 수신이 이뤄지는데 이를 통해 객체지향 프로그래밍에서는 문제를 해결합니다.
객체지향 프로그래밍에서는 문제를 분할하고 이를 각 역할에 맞게 할당하고 협력하는 방식으로 해결하기 때문에 올바른 객체를 설계하기 위해서는 좋은 협력을 설계해야 한답니다!!

마무리

이번 포스트에서는 다음 포스트에서 다룰 용어들에 대하여 간략히 소개했습니다.
포스트 내용중에 커피가 나오지 않았다고요!? 다음 포스트에서 중점적으로 다루도록 하겠습니다~
OOP를 공부하면서 틀린 내용이 있을 수 있으니 피드백 환영합니다!!
그럼 다음에 커피가 어떻게 나오는지 보면서 OOP를 이해해봅시다~ 그럼 Bye Bye~ 😁

profile
도전하고 성장하는 개발자입니다 :)

0개의 댓글