본문 바로가기

C++

객체지향 프로그래밍(OOP)이 필요한 이유

객체지향 프로그래밍(Object Oriented Programming, OOP)은 과거 프로그래밍 세계를 지배하던 패러다임에서 발견된 한계를 극복하고자 만들어졌다. 그렇기 때문에 OOP를 제대로 이해하기 위해서는 과거 프로그래밍 패러다임에 어떤 한계가 있는지 알아야 한다.


절차적 언어(Procedural Languages)


C, Pascal, FORTRAN 등과 같은 것들이 절차적 언어이다. 절차적 언어는 실행문(statements)을 통해 컴퓨터에게 어떤 작업을 수행하라고 말한다. 절차적 언어로 만든 프로그램은 이러한 실행문의 집합이다.


아주 작은 프로그램의 경우는 실행문 만으로도 만들 수 있다.


하지만 프로그램이 커질수록 실행문 만으로 프로그램을 만들고, 관리하기가 힘들어진다. 수백, 수천 줄의 실행문으로 만든 프로그램을 이해하기는 쉽지 않다. 그렇기 때문에 '함수(function)'가 도입되었다. 함수는 복잡해진 프로그램을 작게 쪼개어 프로그래머가 이해할 수 있도록 만들어졌다.


프로그램을 함수와 모듈(여러개의 함수를 그룹화시켜 놓은 것)으로 나누는 것은 구조적 프로그래밍(structured programming)의 기반이 되었다.


하지만 프로그램이 커지고 복잡해주면 구조적 프로그래밍조차 어려움을 겪는다.


함수와 모듈을 도입해서 큰 프로그램을 작게 쪼갤 수 있는데도 문제가 발생한 이유를 찾아보니 그 이유는 절차지향 패러다임 그 자체에 있었다. 프로그램의 구조를 잘 설계했는가와는 상관없이 큰 프로그램은 지나칠 정도로 복잡해졌다.


그렇다면 절차지향 패러다임과 그 패러다임을 대표하는 언어들은 왜 문제가 생길까?


첫째로, 함수가 전역 변수(global data)에 접근하는데 아무 제약이 없기 때문이다.


C로 프로그램을 짤 때 데이터는 크게 두가지로 나뉜다.


지역 변수(Local data)는 함수 안에 들어가 있는 것이다. 지역 변수는 그것을 포함하고 있는 함수에서만 사용 가능하므로 다른 함수에 의해서 값이 변경되지 않는다.


하지만 두가지 이상의 함수가 이용해야 할 변수는 지역 변수로 선언하면 안되기 때문에 전역 변수(Global data)로 선언해야 한다. 규모가 큰 프로그램에서는 전역 변수와 함수가 서로 복잡하게 얽혀있다. 그렇게 되면 프로그래머가 자신이 만든 프로그램의 구조를 한눈에 파악하기 힘들다. 또한 전역 변수 하나가 수정한다면 그와 연관된 모든 함수 또한 수정이 필요할 수 있다.


둘째로, 프로그래밍을 하기 위해서는 실제 세계와 대응되는 모델이 있어야 하는데 절차지향 패러다임의 기본인 함수와 데이터 만으로는 이러한 모델을 만들기가 어렵다. 모델을 쉽게 만들기 위해서는 데이터(attributes)과 함수(behavior)가 함께 있어야 한다.


자동차를 모델로 만든다고 가정한다면, 자동차의 모델명, 색깔, 연식 등이 데이터고, 자동차가 전진한다, 후진한다 등이 함수이다.


객체지향적인 접근법


객체지향의 기본 아이디어는 하나의 유닛(unit)에 데이터와 함수를 모두 넣는 것이다. 그러한 유닛을 객체(Object)라고 부르며, 데이터와 함수를 하나의 단일한 유닛으로 합치는 것을 캡슐화(Data encapsulation)라고 한다.


객체의 함수(C++에서는 member functions라고 부름)는 객체의 데이터에 접근할 수 있는 유일한 수단이다. 데이터를 수정하거나 확인하고 싶다면 member function을 사용하면 된다. 그렇지 않은 방법으로는 접근할 수 없다.


데이터는 다른 함수로부터 숨겨져 있으므로, 예상치 못한 변화가 일어날 가능성이 적어진다. 이러한 특성을 은닉화(Data hiding)라고 한다.


캡슐화와 은닉화는 객체지향을 설명하는 핵심 용어이다.


객체가 필요한 이유를 쉽게 이해하기 위해서 회사의 구조에 비유를 해보자. 객체는 회사의 개발, 영업, 인사 등을 담당하는 부서라고 할 수 있다. 회사를 부서로 나누는 것은, 프로그램을 객체로 나누는 것처럼, 회사가 하는 일을 이해하기 쉽게 만들어주며 정보를 온전하게 보관해준다. 그렇기 때문에 아주 작은 회사를 제외하고는 대부분의 회사는 각 부서가 하는 일이 확실하게 나누어져 있고, 한 직원이 인사 업무를 보면서 개발까지 하지는 않는다.


각 부서는 소속된 직원들이 있고, 정해진 업무가 있다. 또한 부서는 부서마다 데이터를 가지고 있다. 영업부는 영업 데이터가 있고, 인사부는 인사 데이터가 있다. 부서에 소속된 직원만이 그 부서의 데이터를 관리할 수 있다.


개발 부서 직원이 직원들이 받은 연봉의 합계를 알아보기 위해 회계 부서에 간다고 하자. 회계 부서에 찾아가서 멋대로 자료를 찾아보면 안된다. 그 자료는 회계 부서에서 엄격하게 관리하는 자료이고, 내가 멋대로 찾는 도중에 문제가 생길 수 있기 때문이다. 자료를 얻기 위해서는 회계 부서의 담당자에게 부탁을 하고 담당자가 정보를 찾고, 나에게 정보를 줘야 한다. 그렇게 해야 아무것도 모르는 외부자가 부서의 중요한 정보를 망칠 가능성을 줄일 수 있다.


이처럼 회사를 부서로 나누면 부서마다 고유한 업무와 데이터를 부여함으로써 회사가 어떻게 기능하는지 파악하기 쉽게 만들며(Data encapsulation), 회사의 데이터를 부서별로 나눠서 다른 부서에서는 접근하지 못하게 한다(Data hiding).