본문 바로가기
기타

객체 지향이란 대체 뭘까?

by 유세지 2023. 1. 25.

 

 

객체 지향은 현대 프로그래밍의 역사에서 빼놓을 수 없는 중요한 패러다임입니다. 몇 십 년 전부터 많은 개발자들은 객체 지향이라는 개념을 기반으로 프로그래밍을 해왔고, 그 흐름이 지금까지 이어져서 하나의 성숙한 패러다임으로 자리를 잡은지 오래입니다. 실제로 적지않은 대학교의 컴퓨터공학 커리큘럼에서도 객체 지향론, 또는 객체 지향 프로그래밍등의 과목은 어렵지 않게 찾아볼 수 있습니다.

 

 

제가 다니는 학교에도 2학년 1학기 과목으로 "객체지향 프로그래밍언어" 가 있습니다.

 

 

이렇게나 역사도 깊고 유명한 개념이지만, 막상 "객체 지향이 무엇인가요?"라는 질문을 받으면, 쉽게 대답하기 어려운 주제이기도 합니다. 돌이켜보면 우리가 처음 객체 지향다운 코드를 작성한다고 했을 때, 객체 지향의 개념을 먼저 공부하고 실제 문제에 적용해서 만들어내는 것은 나중 일이었습니다. 그보다는 숱하게 참고해왔던, 객체 지향의 개념이 이미 녹아 들어있는 선배 개발자분들의 코드를 사용한 경우가 더 먼저였을 것입니다. 그렇기 때문에 몸이나 코드로는 대충 이런 게 아닐까? 하는 느낌은 알아도, 깔끔하게 말로 정리해서 말하기는 생각보다 쉽지 않은 일이었습니다.

 

오늘 포스트에서는 객체 지향이라는게 무엇인지, 한 문장으로 깔끔하게 정리할 수 있도록 공부해보는 것을 목표로 합니다.

 

 

 

객체, 지향

객체 지향 (Object-Orientation)이라는 말의 의미를 살펴보면 객체를 지향하는 것이라는 걸 알 수 있습니다. 그렇다면 무엇보다도 객체가 무엇인지 알아야 이 말의 참뜻을 설명할 수 있습니다.

 

"객체"라는 말은 분야에 따라 미묘하게 다른 의미를 갖고 있는데, 우리가 살펴 볼 객체 지향에서의 객체는 클래스의 인스턴스를 의미합니다. 그래서인지, 객체를 설명할때 흔히 붕어빵틀과 붕어빵에 빗대어 클래스에 대한 이야기를 같이 하는 경우가 굉장히 많습니다. 여기에 기인하여 객체 지향이란 "클래스를 사용하는 프로그래밍이다." 라고 하는 답변도 간간히 들었던 기억이 있네요.

 

이런 설명은 아주 틀린 말은 아니지만, 개인적으로 객체 지향이라는 개념을 담기에는 다소 부족하다고 생각합니다. 단순히 클래스와 인스턴스만을 사용한다고 해서 객체 지향을 근본적으로 묘사했다고 하기에는 아직 필요한 것들이 더 남아있습니다.

 

 

협력을 잘 할 수 있도록 하는 것이 중요합니다

 

 

객체란 언제든 다른 객체와 협력하여 역할과 책임을 수행할 준비가 되어있는, 하나의 추상화 된 개체를 의미합니다. 클래스는 이러한 객체를 만들때 사용하는 도구이며, 그 결과물로 만들어진 객체가 인스턴스라는 이름으로 불립니다. 여기서 중요하게 바라봐야 할 것은 클래스나 인스턴스라는 이름보다, 객체의 본질적 의미인 "협력하여 역할과 책임을 수행한다" 입니다.

 

이러한 객체를 지향한다는 것은, 객체끼리 협력하여 역할과 책임을 잘 수행할 수 있도록 하는 방향으로 프로그래밍 하는 것을 의미합니다.

 

 

왜 객체 지향일까?

그렇다면 왜 객체를 지향해야할까요? 협력을 잘 할 수 있게 하면 무엇이 좋을까요?

마찬가지로 객체 지향을 설명할때 많이 사용되는 카페에서의 상호 작용을 예시로 들어보겠습니다.

 

 

 

 

카페에서는 세 가지 유형의 사람들이 있습니다. 카페에 들어와 커피를 주문하는 손님, 손님의 주문을 받는 캐셔, 주문대로 음료를 제조하는 바리스타입니다. 여기서 한 번의 주문이 일어나고 손님에게 음료가 전해지기까지의 과정을 쭉 나열해 보겠습니다. 

 

손님, 캐셔, 바리스타

손님이 주문한다.
캐셔는 주문을 받는다.

주문 받은 음료가 커피라면
바리스타는 커피를 만든다.

음료가 만들어지면 캐셔는 손님에게 전달한다.
손님은 음료를 마신다.

 

이 과정에서는 손님, 캐셔, 바리스타 세 인물이 등장하고, 셋 모두 어느정도 역할이 정해져있습니다. 요컨대 바리스타가 손님에게 음료 주문을 하거나, 손님이 음료를 만드는 일 등은 거의 일어나지 않는다는 의미입니다.

 

이렇게만 보면 사뭇 간단해보입니다. 하지만 실제 카페에는 음료가 커피만 있는 것도 아니고, 손님도 한 명만 오지는 않습니다. 여기서 우리가 해야 할 일은 추가되는 요구사항 속에서 점점 복잡해지는 상황에 대비해 빠르게 변경사항을 반영할 수 있도록 프로그램을 짜는 것입니다. 이러한 구조를 변경에 유연한 설계라고 부릅니다.

 

결국 이러한 설계를 위해서는 우리가 생각해야 할 부분들을 최대한 줄여 전체적인 복잡도를 낮추어야만 합니다. 실제로 전체 복잡도가 변하지는 않으니 정확히는 복잡도를 잘 관리해야 한다라고 할 수 있겠습니다.

 

복잡도를 관리하는 가장 쉬운 방법은 분할입니다. 주어진 문제 상황을 쪼개고, 수정해야 할 코드의 범위와 양을 줄여내면 새로운 변경에 비교적 적은 노력으로 대응할 수 있게 됩니다.

 

그렇다면 어떤 기준으로 시스템을 분할할 수 있을까요? 또한, 우리는 어떤 부분에 집중해야 할까요?

 

 

객체간의 협력

위의 상호작용에서 손님, 캐셔, 바리스타는 모두 객체라고 볼 수 있습니다. 그리고 주문 하기, 주문 받기, 음료 만들기 등의 동작들은 객체가 할 수 있는 행위입니다. 보통 행위는 객체에 종속적이기 때문에, 그 행위의 주체가 적절한 객체가 될 수 있도록 배분해주는 것이 중요합니다.

 

이렇게 각 객체들이 행위를 갖게 되면, 객체들에게 기대하는 역할이 생겼다고 할 수 있습니다. 손님은 주문을 하는 역할, 캐셔는 주문을 받는 역할... 이러한 역할들을 객체가 갖게되면 이제 서로간의 협력을 통해 동작을 수행하게 됩니다.

 

협력이라는 단어에서 알 수 있듯 객체들은 목표 달성을 위해 서로 도와가며 작업을 수행합니다. 어떠한 간섭도 없이, 객체는 다른 객체에게 그저 요청할 뿐입니다. 여기서 말하는 간섭이란 아래와 같은 경우입니다.

 

 

손님 "바리스타씨, 커피를 내릴땐 원두를 좀 더 눌러 담아서 해야죠."
바리스타 "제가 알아서 하겠습니다."

 

 

보통 커피를 내리는 방법에 대해서는 손님보다 바리스타가 전문가일 확률이 높습니다. 손님이 바리스타에게 요청할 수 있는건 메뉴나 개인의 선호 (샷 추가, 연하게) 정도이지 어떻게 커피를 내려야 할지 세세하게 지시하진 않습니다. 그나마도 캐셔를 통해서 요청해야 합니다. 이는 보장된 품질과 좋은 서비스를 위한 암묵적인 약속인 셈이니까요.

 

이처럼 서로에게 간섭하지 않고 객체의 독립성을 보장할때 객체들은 효율적으로 협력할 수 있게 됩니다. 때문에 객체들은 직접적인 간섭 대신, 이러한 요청과 응답을 주고 받을 소통 창구가 필요합니다. 이것을 객체 지향에서는 인터페이스라고 부릅니다.

 

다시 말해서 요청과 응답을 객체 간의 메시지라고 했을때, 인터페이스는 객체가 메시지를 주고 받을 수 있는 규약이라고도 할 수 있습니다.

 

메시지와 인터페이스에 대한 설명을 첨가하니 위에서 클래스만으로 객체 지향을 설명했을때 느꼈던 부족한 점이 어느정도 채워지는 느낌입니다. 다시 한 번 객체 지향을 정리해보면, 독립적인 객체들이 메시지를 통해 협력하도록 시스템을 분할하여 만드는 방법이라고 할 수 있을 것 같습니다.

 

 

서로가 협력하는 시스템을 만드는 객체 지향

 

 

 

마무리

이번 포스트에선 객체 지향이 목표로 하는 것이 무엇인지, 한 문장으로 설명하라고 한다면 어떻게 정리할 수 있을지 알아보았습니다. 위에서 다룬 내용 이외에도 객체 지향에는 좋은 객체를 만드려면 어떻게 해야하는지나 복잡성을 어떻게 더 잘 관리할 수 있을지에 대해서도 많은 논의가 이어져왔습니다. 다음에는 그러한 부분들도 다루어 볼 기회가 있었으면 좋겠네요.

 

이 포스트는 스터디원들과 <객체지향의 사실과 오해> 책을 함께 읽고, 어느정도 내용 정리가 된 시점에 작성하였습니다. 어렴풋하게만 느껴졌던 개념이었는데, 한 번 정리를 하고 나니 이전보다는 명료하게 눈에 들어오는 느낌이네요. 다음 북 스터디에는 리팩토링 2판을 다시 읽습니다. 이번이 2회독인데, 이전보다 많은 부분을 볼 수 있었으면 하는 작은 바람이 있네요.

 

읽어주셔서 감사합니다.

 

 

참고 문서

객체지향의 사실과 오해 - 조영호 님

객체 - 위키백과

 

반응형

댓글