본문 바로가기
프로그래밍 언어/설계 원칙 & 디자인 패턴

저는 객체 지향이 처음이라니까요?

by 조엘 2021. 2. 22.

안녕하세요! 조엘입니다!

 

"처음이라니까요" 시리즈 첫 주자 바로 객체 지향입니다. 

 

솔직히 말하면, 객체 지향이랑은 초면은 아닙니다. 

분명히 학교에서 배우긴 했어요. 클래스는 뭐다, 붕어빵 붕어빵 틀, 다형성, 캡슐화 등등...

(학교 커리큘럼이 이상해져서 정말 맛만 보고 끝났지만 😒)

 

근데 막상 객체 지향에서 중요한 건 이런 용어들이 아니더라고요. 

객체 지향에서 뭐가 중요한지 하나씩 알아봅시다 :)

 

틀린 내용이 있을 수 있습니다! 알려주세요! 댓글 환영합니다 😁

 

 

*** 정의 ***

기존 학교 과제나 알고리즘 테스트에서 작성한 코드들을 생각해보면, 

데이터필요한 절차를 거쳐 원하는 결과로 가공되도록 코드를 작성했어요. 

지금까지 제가 이러한 코딩 방식을 가지고 불편해하지 않았던 이유는 한 번 짜고 평생 볼 일이 없었기 때문이에요. 

 

하지만 딱 한번 어라? 불편하네? 했던 적이 있었는데,

모바일 컴퓨팅 과목에서 구현해야 할 기능이 늘어나자 주렁주렁 if - else 추가한 경험이었어요. 

 

더 규모가 큰 소프트웨어는 어떨까요? 

수 없이 변화하는 요구사항에 맞춰 저 처럼 주렁주렁 if - else를 통한,

나도 자고 일어나서 다시 보면 뭔 소린가 가물가물해할 코드를 짜야할까요?

 

객체 지향은 이를 해결해줄 수 있어요. 

 

자, 이제 무엇인가를 접할 때 가장 중요한 정의입니다. 

위키피디아에서 정의하는 객체지향 프로그래밍은 다음과 같아요.

 

객체 지향 프로그래밍(영어: Object-Oriented Programming, OOP)은 컴퓨터 프로그래밍 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다.

 

객체 지향 프로그래밍은 역할 별로 필요한 데이터필요한 절차객체라는 단위로 묶었어요.

 

이렇게 생성된 여래 개의 객체들은 이제 자신만의 기능을 제공하게 되고,

각 객체들은 서로 연결되어 다른 객체들이 제공하는 기능을 사용할 수 있게 되는 것이죠. 

 

근데 한 가지 문제가 있습니다.

 

객체 A에, 객체 B에 어느 데이터와 어느 절차가 필요한 지 어떤 기준으로 정하나요? 

사람마다 어느 객체에 어느 데이터가 필요한 지 판단이 다를 텐데요?

 

이를 슬기롭게 풀어내기 위해서 우리는 협력 - 책임 - 역할에 대해 공부해야 합니다. 

 

+ ) 위에 방식을 절차지향이라고 부르는데, 절차 지향과 객체지향에 대해 조금 더 인사이트를 얻고 싶다면 아래 참고에 있는 글을 읽어보세요. 

 

 

*** 협력 ***

"객체지향의 사실과 오해" 라는 책에 따르면, 

객체 지향의 중심은 바로 자율적인 객체들의 협력에 있다고 강조해요. 

각자 자율적인 책임을 가진 객체들의 조화로운 협력을 통해 객체 지향 프로그램을 만들 수 있다는 것이죠. 

 

중요한 단어 책임과 협력이 나왔는데, 여기서는 협력에 집중하여 객체 지향을 생각해 보도록 해요. 

 

결국 객체지향 프로그래밍은 동일한 목적을 달성하기 위해 협력하는 객체들의 공동체를 만드는 과정입니다. 

 

협력은 서로 힘을 합하여 돕는다는 뜻이 잖아요?

협력은 각자 맡은 책임에 충실할 때 원활히 진행될 수 있어요. 

 

따라서 좋은 객체 지향 프로그램을 설계하기 위해서는

어떤 객체가 필요한 가에 중점을 두는 것이 아닌,

학교에서 배운 붕어빵 - 붕어빵 틀에 중점을 두는 게 아닌,

어떤 변수와 함수가 필요한 가에 중점을 두는 것이 아닌,

어려운 문법 용어에 중점을 두는 게 아닌,

어떤 객체들이 어떤 책임을 가지고 동일한 목적을 위해 협력할 수 있을까에 집중하는 게 맞습니다. 

 

객체들이 어떠한 방식으로 협력하도록 설계하는 것은 또 개발자 마음일 것 같은데요, 

협력하는 방식들의 틀을 어느 정도 잡아준 게 디자인 패턴이라고 생각이 됩니다. 

디자인 패턴에 대해서는 다음에 좀 더 다뤄볼게요. 💪

 

 

*** 책임 ***

협력이란 것은 여러 객체들의 요청과 응답으로 만들어져요. 

그리고 객체 별로 처리하는 요청과 응답은 곧 객체가 갖는 책임으로 귀결됩니다.

 

"해당 요청은 온전히 너에게 맡길 테니, 다하면 나에게 응답해줘!"

가 쌓여 이 작업은 내가 책임진다!라고 말하는 객체가 탄생하는 것이죠. 

 

책임을 완수하기 위해 필요한 변수와 함수를 묶어 놓은 것을 어려운 말로 "캡슐화"라고 해요

 

책임을 공부할 때 가장 강조되는 내용은, 객체가 자율적으로 책임을 완수해야 한다는 것이에요. 

자율적이란 말이 안 와 닿을 수 있는데, 예를 들어볼게요. 

 

우리가 식당에 가서 돈까스를 주문하는 상황을 생각해봅시다.

주문을 하는 데엔 두 가지 방법이 있을 수 있어요. 

 

1. 요리사의 자율성을 인정하는 주문 

"여기요! 돈까스 하나 주세요!"

 

2. 요리사의 자율성을 해치는 주문

"여기요! 먼저 고기를 꺼내 주세요!"

"여기요! 망치로 다져주세요!"

"여기요! 튀김옷을 입혀주세요!"

"여기요! 기름에 튀겨주세요!"

"여기요! 플레이팅 해주세요!"

 

어떤가요? 두 번째 방법, 숨 막히죠?

첫 번째 방법처럼 요리사에게 돈까스를 요구하면, 

요리사가 알아서 돈까스를 요리해서 갖다주는 것이 바로 책임을 자율적으로 완수하는 방법입니다. 

 

이렇듯 자율적인 책임은 협력을 단순하게, 협력을 유연하게 만듭니다.

 

아, 물론 두 번째 방법으로도 돈까스를 먹을 수 있어요. 

하지만 요리 과정에 해당하는 요청들은 요리사가 알아서 수행하는 것이 주문하는 저나, 만드는 요리사나 편하겠죠? 

 

또한 책임이 자율적이게 되면 갖는 장점으로는 내부적인 방법을(요리사가 돈까스를 만드는 절차) 수정해도, 

외부의 요청(여기요! 돈까스 하나 주세요!)에 적절한 응답을 할 수 있다는 것이에요. 

 

이렇듯 책임의 범위를 자율적으로 보장하면서, 객체는 외부로 꺼낼 것 내부로 감출 것을 명확히 할 수 있게 돼요. 

 

외부에 정해진 행동만을 제공하고, 정해진 행동을 하기 위한 세부 절차는 감추는 것을 어려운 말로 "은닉화"라고 해요. 

 

어떤 것을 외부로 꺼내고, 내부로 감출지를 단 번에 알아차리는 것은 어렵습니다. 

구현할 기능 목록을 토대로 차근차근 어울리는 자리를 개발자가 잡아주는 연습이 필요하다고 하네요. 😊

 

 

*** 역할 ***

지금까지 각각의 책임을 갖고 있는 객체들을 협력시켜 조화를 이루는 게 객체 지향이라고 배웠는데요, 

여기서 "각각의 책임을 갖고 있는"을 다른 말로 역할이라 할 수 있어요. 

 

협력 안에서 각 객체에게 책임을 어떠한 방식으로 부과해야 하는지 알았다면, 

이번에는 객체가 지니고 있는 책임 그 자체, 역할에 대해 조금 더 공부해 보아요. 

 

객체의 역할을 결정짓는 것은 무엇일까요?

바로 객체의 행동입니다.

동일한 행동을 수행할 수 있다면, 동일한 역할을 수행할 수 있겠죠?

 

이렇게 동일한 행동을 수행할 수 있는 객체들을 어려운 말로 "타입"이 같다고 해요. 

 

요구사항과 변동사항이 많은 소프트웨어의 경우, 

경우에 따라 객체를 파워레인저 변신로봇 마냥 바꿔 끼워야 할 경우가 생깁니다. 

 

예를 들어볼게요. 

자주 가던 돈까스 집의 요리사 분이 오늘은 아프셔서 집에서 쉬고 계십니다. 

그래서 아프신 요리사 대신, 그의 수제자가 요리를 대신 도맡아 하기로 했어요. 

저는 여느 날과 다르지 않게 식당에 찾아가서 돈까스를 주문했어요. 

"여기요! 돈까스 하나 주세요!"

오? 오늘은 평소보다 돈까스가 더 맛있는데요? 

 

돈까스 요리사의 역할을 수제자가 훌륭하게 대체한 것을 볼 수 있는데요!

 

이렇게 동일한 역할을 수행하며, 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을,

어려운 말로 "다형성"이라고 해요. 

 

돈까스를 다 먹은 저는 계산하러 카운터에 갔다가 수제자를 발견하곤 돈까스가 수제자의 작품이냐고 물어봅니다. 

"하하 놀라셨군요 제가 만들었습니다" 

대체 어떻게 하셨냐고 물어보니, 수제자는 스승의 방식을 그대로 물려받아,

거기에 자신만의 특수 비법 소스를 추가했다고 하더라고요. 

다음에 저는 웃으며 수제자가 대타 뛰는 날 꼭 알려달라고 얘기하고, 계산하고 나왔습니다. 

 

수제자의 맛있는 돈까스는 요리사의 레시피에 자신만의 특별한 소스를 추가해서 만들어졌던 거군요!

 

이렇듯 수제자(자식 클래스)가 스승(부모 클래스)의 기능을 받아 사용할 수 있는 것을 어려운 말로 "상속"이라고 해요. 

상속 역시 다형성을 구현하기 위한 한 가지 방법이 될 수도 있겠네요!

 

살펴본 바와 같이, 객체 지향 프로그래밍에서는 객체를 역할로 정의하기 때문에,

새로운 기능 추가나 변경에 유연하게 대처할 수 있겠군요! 🎺 

 

 

*** 결론 ***

은근히 객체지향에 대한 여러 가지 설명을 남발했는데, 글에서 쓰인 정의들을 모두 긁어모으면 다음과 같아요. 

- 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 

- 자율적인 객체들의 협력

- 각자 자율적인 책임을 가진 객체들의 조화로운 협력

- 동일한 목적을 달성하기 위해 협력하는 객체들의 공동체

 

결국 모두 하는 말은 똑같아요.

객체 지향 프로그래밍에서 중요한 것은 협력 - 책임 - 역할이다! 

이를 머리에 두고 개발하면 프로그램을 유연하고 변경이 용이하게 만들 수 있다!

 

또한, 객체 지향 프로그래밍을 효율적으로 구현하게 해주는 캡슐화 - 상속 - 다형성이,

왜 객체 지향의 3대 요소로 꼽히는지 그 이유도 감이 약간 오는 것 같고요. 

 

자! 이제 어려운 문법을 배울 때가 된 것 같아요. 

 

객체지향에 대해 정리를 하고 보니,

Class, Interface, Generic 이런 어려운 용어들도,

결국 객체들의 협동 - 책임 - 역할을 지원하기 위해 만들어졌다는 생각이 드네요.

 

어려운 것들도 하나씩 배워나가도록 하겠습니다!

 

나 자신 화이팅🤞

 

 

참고 

- blog.naver.com/atalanta16/220249264429

- 객체지향의 사실과 오해(조영호 | 위키북스)

- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴(최범균 | 인투북스)

반응형

댓글