객체 지향 프로그래밍(Object-Oriented Programming, OOP)이란?
객체 지향 프로그래밍이라는 이름에서 알 수 있듯이
객체 지향 프로그래밍이란 객체를 지향하는 프로그래밍 방식이란 것을 알 수 있습니다.
위키백과에서는 객체 지향 프로그래밍을 아래와 같이 정의합니다.
객체 지향 프로그래밍(Object-Oriented Programming, OOP)은 컴퓨터 프로그래밍의 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 쉽게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.
길게 정의되어 있지만
결국 객체 지향 프로그래밍은 컴퓨터 프로그램을 객체들의 모임으로 보는 프로그래밍 패러다임이라는 점입니다.
그렇다면 객체란 무엇일까요? 왜 프로그램을 객체의 모임으로 보는걸까요? 어떻게 객체를 다룰까요?
이에 대한 대답을 찾아야 제 스스로 객체 지향 프로그래밍이 무엇인지를 정확하게 한마디로 무엇이라 정의할 수 있을 것 같아 이렇게 글로 정리해봤습니다.
# 객체란 무엇일까요?
앞에서 객체를 지향하는 프로그래밍이라 했는데, 이때 객체란 무엇일까요?
객체를 알기 위해선 클래스라는 개념과 추상화에 대해 알아야 합니다. 아래의 예를 통해서 설명해 보겠습니다.
개발자가 과일의 특징을 다루는 프로그램을 만들고 싶다고 가정을 해봅시다.
현실 세계에서 실제 과일은 과일마다 가지고 있는 특징은 매우 많습니다. 과일의 종류가 무엇인지, 어느 환경에서 자라는지, 어떤 영양소를 가지고 있는지 등등 과일마다 가지고 있는 특징은 매우 많습니다.
하지만 이 모든 특징들을 모두 다루는 것은 프로그램에서 의미가 없습니다.
프로그램에서 다루고자하는 과일들의 공통적인 특성들만 의미가 있습니다. 예시에서는 과일의 무게와 색상, 그리고 맛이 프로그램에서 다루고자하는 과일들의 공통적인 특성들입니다.
이렇듯 실제 현실 세계에 존재하는 대상에서 내(개발자)가 다루고자하는 공통적이고 핵심적인 특성들만 뽑는 과정을 추상화라고 합니다.
이렇게 추상화를 통해서 뽑아진 특징들을 하나로 묶어 만든 추상적인 틀을 클래스(Class)라고 합니다.
예시에서 볼 수 있듯이 클래스는 과일의 무게와 색상, 그리고 맛이라는 틀만 가지고 있을 뿐이지 내용물이 담겨있지 않습니다.
즉, 클래스는 개념적으로만 존재하는 것입니다.
이렇게 개념적으로 틀만 존재하는 클래스에 실제 내용물을 담아 실체화 한것을 바로 객체(Object)라고 합니다. 객체는 클래스와 다르게 내용물이 담겨있는 실체입니다. 예시에서 볼 수 있듯이 클래스에서부터 300g의 무게와 빨간 색상, 그리고 단맛이라는 특성을 담아 실체화한 사과가 그 예입니다.
간혹 객체로서의 사과와 현실 세계에 실재하는 사과의 개념이 헷갈릴 수 있습니다.
개체로서의 사과는 프로그램 상에서 다루고자하는 특성만을 모은 클래스로부터 생성된 것으로 실제 사과를 완벽하게 1:1로 매칭시켜 같다고 할 수는 없다는 것입니다.
# 왜 객체를 지향하는 걸까요?
객체가 무엇인지 알아보았습니다. 그렇다면 왜 프로그램을 객체들의 모임으로 보는 걸까요? 왜 객체를 지향하는 걸까요?
위에 위키에서 설명된 객체 지향 프로그래밍의 내용 중 마지막 부분을 다시 보면,
"객체 지향 프로그래밍은 프로그램을 유연하고 변경이 쉽게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다."
객체 지향 프로그래밍은 어떻게 프로그램을 유연하고 변경이 쉽게 만드는 것일까요?
왜 대규모 소프트웨어 개발에 많이 사용이 될까요?
여기서는 객체 지향의 특성 중 하나인 다형성(polymorphism)이라는 개념이 나옵니다.
객체 지향 프로그래밍 개념에서 다형성이란 여러가지 형태를 가질 수 있는 능력을 의미합니다. 프로그래밍에선 객체를 설계할 때 역할인 인터페이스를 먼저 설계하고, 그 역할을 수행하는 구현 객체를 만든다거나 오버라이딩을 통해 다형성을 구현할 수 있습니다. 하지만, 지금은 객체 지향 프로그래밍을 사용하는 이유에 대해 알아보기 위함으로 실세계의 예를 통해 다형성을 알아보겠습니다. 알아보기에 앞서 실세계와 객체 지향을 1:1로 완벽하게 매칭할 수 없다는 점을 알아두시고 폭 넓게 예시를 이해하는 것이 좋습니다.
그림을 통해 실세계의 예를 알아보겠습니다.
다형성은 세상을 "역할"과 "구현"으로 구분하는 것입니다. 이 예시는 다형성을 나타내는 가장 유명한 예로 자동차를 "역할"과 "구현"으로 구분하였습니다.
여기서의 자동차 역할이란 악셀을 밟으면 앞으로 나가고 브레이크를 밟으면 멈추는 것과 같은 어느 자동차나 가지고 있는 기능을 뜻합니다. 자동차 구현이란 말 그대로 자동차의 역할(=자동차 기능)이 포함된 실제 차로 구현해내는 것을 말합니다. 다양한 자동차로 구현이 되어도 자동차의 역할은 변하지 않습니다.
이렇게 자동차를 역할과 구현으로 구분하면 운전자 입장에서는 세상 어떠한 자동차를 타든 악셀을 밟으면 앞으로 나가고 브레이크를 밟으면 멈춘다는 것을 알 수 있습니다. 자동차가 실제로 어떤 방식으로 작동하는지, 어떤 부품이 들어있는지, 내부 구조가 어떻게 되어있는지는 운전자가 신경쓸 필요가 없습니다.
또한 운전자가 아닌 자동차를 구현하는 사람의 입장에서 자동차를 역할과 구현으로 구분하면 운전자와는 상관없이 무한히 자동차를 구현할 수 있습니다. 어떤 운전자가 차를 몰든 자동차를 구현하는 입장에서는 자동차의 역할만 자동차를 구현할 때 포함시키면 되는 것입니다. 다시 말해 자동차를 구현할 때 자동차의 역할을 포함만 시키면 그 외의 부분은 어떤 형태로든 어떤 기능을 추가하든 구현할 수 있는 경우는 무한히 확장될 수 있습니다.
즉, 세상을 역할과 구현으로 나누는 다형성은 결국 서로에게 영향을 끼치지 않는다는 것입니다. 이와 같은 특징은 세상을 유연하고 변화하기 쉽게 만들어 줍니다.
이렇듯 프로그램에서 객체를 지향한다는 것은 객체의 역할과 구현을 나눠 다루겠다는 뜻입니다. 객체의 역할과 구현을 나눈다면 위의 예시와 같은 이유로 클라이언트에 영향을 주지 않고 서버의 구현 기능을 유연하고 다양하게 변경할 수 있습니다.
이런 유연하고 변경이 용이하다는 특징은 인터페이스를 잘 설계하여 조직내에 이해도를 높인다면 많은 인원이 투입되어다른 곳에 영향을 끼치지 않고 각자의 구현체를 개발할 수 있기에 완성도 높은 프로그램을 제작할 수 있기에 대규모 프로젝트에서 많이 쓰이는 것입니다.
# 객체 지향 프로그래밍 장단점은 무엇일까요?
그렇다면 객체 지향 프로그래밍이 가지는 장점과 단점은 무엇일까요?
우선 객체 지향 프로그래밍의 장점입니다.
- 코드 재사용이 용이합니다
: 이미 작성된 클래스 등을 가져와 사용할 수 있으며 상속을 통해 확장시켜 사용할 수 있습니다. - 신뢰성, 보안성이 높습니다.
: 실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있습니다. 클래스는 오로지 관련 데이터만을 정의하고 제어자와 메서드를 이용해 데이터를 보호하므로 데이터의 바른 값을 유지할 수 있습니다. (객체 지향 특성 중 캡슐화에 해당) - 유지보수가 쉽습니다.
: 기능을 수정할 경우에는 주변에 미치는 영향을 최소화하며, 기능을 추가할 때에는 상속을 통해 기존 기능을 활용할 수 있습니다. 업그레이드 뿐만 아니라 디버깅 역시 기능 단위로 진행하므로 쉽습니다. - 직관적인 프로그래밍이 가능합니다.
: 객체들의 상호 작용을 기준으로 모델링을 진행하므로 직관적인 프로그래밍이 가능합니다. - 대규모 프로젝트에 적합합니다.
: 클래스 단위로 모듈화시켜 개발할 수 있으므로 업무 분담이나 업무 진행에 있어서 대형 프로젝트에 적합합니다.
다음으로는 객체 지향 프로그래밍의 단점입니다.
- 실행 속도가 느리고 성능이 저하됩니다.
: 캡슐화와 격리 구조 설계로 인해 성능 하락이 있습니다. 객체로 묶여 있기에 일반적으로 함수 호출 및 포인터 연산 등이 필요해지며, 객체가 서로를 건드릴 수 없고 getter, setter 통해서만 데이터에 접근할 수 있으므로 getter, setter의 사용이 많아지는 것 역시 속도 및 성능 저하의 이유입니다. - 코드가 복잡해지고 이해하기 어려워질 가능성이 있습니다.
: 상속이 가능하기 때문에 다중 상속 또는 상속이 복잡하게 얽혀 있는 경우엔 소스 분석이 어려워질 수 있습니다. - 설계에 많은 시간과 노력이 소요됩니다.
: 인터페이스 설계에는 추상화라는 비용이 발생하며 각 객체들의 상호작용을 중심으로 프로그램을 서술하므로 다른 프로그래밍 방식보다 설계할 때에 추가적인 시간과 노력(비용)이 들어갑니다.
# 정리
객체 지향 프로그래밍이란 프로그램을 "객체"라는 기본 단위로 나눠 각 객체들의 상호작용을 중심으로 프로그램을 서술하는 방식입니다. "객체"는 클래스라는 추상적인 틀에 내용이 담겨 실체화되어 하나의 역할을 수행하며 그 변화가 무한하며 유연하다는 특징을 지닙니다.