2022-10-09 작성

절차지향과 객체지향에 관한 고찰

누군가 내게 "자바의 특징이 무엇인가?" 라고 묻는다면 반사적으로 객체지향 언어라고 말할 것이다. 그만큼 '자바는 객체지향 언어'라는 인식이 강하게 박혔기 때문이다. 그러나 남에게 핵심을 간추려 설명할 만큼 제대로 알고 있지는 못했다. 스파게티코드님이 절차지향과 객체지향을 비교하여 깔끔하게 설명한 글을 토대로 포스팅 하였다. 설명이 꽤 길지만 읽을 만한 가치가 있는 글이라고 생각한다.

절차지향

이 말에 한 번쯤 의구심을 품어본 적이 없는가?

위 사진은 절차지향과 객체지향의 차이점을 설명하는 단순화된 사례이다. 이를 바탕으로 실제로 자판기 프로그램을 구현한다고 생각해보자.​

먼저 절차지향 방식을 보면, 차근차근 순서대로 따라가는 전형적인 절차식 프로그램임에 틀림이 없다. 그렇다면 객체지향 방식을 살펴보자. 뭔가 이상하지 않나? 개별적으로 참조되고 호출되는 변수들과 함수들을 '객체'라는 틀로 묶어서 사용했다는 건 그렇다 치고, 순서대로 차근차근 진행되는 실행방식에 있어서는 도대체 무슨 차이점이 있을까?

객체지향을 설명할 때는 항상 짝꿍처럼 "절차지향" 방식이 따라붙는다. 그러다보니 마치 객체지향 프로그래밍은 실행절차에 영향을 받지 않는 것 같은 착각에 빠지게 된다. 그러나 위의 알고리즘을 보듯이, 객체지향 방식으로 개발한 프로그램도 분명히 일련의 절차에 따라 실행된다. 어찌 이런 알쏭달쏭한 일이 발생했을까?

정답은 결국 "절차지향"이라는 용어 선택이 이 모든 혼돈을 초래한 주범이라는 것이다.

사실 객체지향의 개념과 특징을 설명하는 데 있어서​ 굳이 절차지향 방식을 들먹이면서 서로 비교할 필요는 없다. 객체란 기존의 방식인 변수 따로, 함수 따로의 분산적이고 통일성 없는 추상화 과정을 통합하여 표현대상(문제해결대상)을 좀 더 모듈화하기 쉽게 도와주는 도구에 불과하며(모듈화 강화의 부산물인 정보은닉화, 상속 및 다형성을 통한 확장성과 재사용성, 이를 기반한 생산성과 유지보수의 용이성이 OOP의 진정한 특징이자 정체성일지도 모른다), 

객체지향 프로그래밍은 객체의 디자인을 한 뒤에 이들의 데이터플로우를 짜고 진행시나리오를 설계해나가는 방식의 개발방법론일 뿐이다. 플로우차트 먼저 짜느냐, 데이터모델링을 먼저 하느냐의 차이일 뿐이지 그 이후로는 절차지향 프로그램이나 객체지향 프로그램이나 다들 정해진 알고리즘을 따라 순서대로 실행되는건 마찬가지이다.

한 번에 프로그램 한 문장씩만을 읽어 들여와서 실행시키는 폰노이만 컴퓨터구조를 사용하는 한, 객체지향 프로그래밍이라고 절차성을 무시하는 프로그램을 짤 수는 없다. 이렇듯, "객체지향"과 "절차식"의 개념은 애초에 비교대상이 아니며 카테고리 자체가 다른 것이다.

"절차지향"이라는 이름을 써야 한다면 "절차지향 프로그래밍은 프로그램의 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식이고, 객체지향 프로그래밍은 반대로 자료구조와 이를 중심으로 한 모듈들을 먼저 설계한 다음에 이들의 실행순서와 흐름을 짜는 방식이다" 정도의 설명을 추가하는 것만으로도 그렇게까지 헷갈릴 일은 없을 것이다. 그게 아니면, 절차지향이라는 이름 대신 차라리 "비객체지향 방식"이라고 쓰는 게 나을지도 모른다.

앞서 살펴본 자판기 프로그램 예시에서도 볼 수 있듯이, 절차지향과 객체지향을 비교할 때 대부분이 절차지향은 "순서도"로, 객체지향은 "클래스 다이어그램"으로 도표를 그려서 비교해놔서 혼란을 가중시킨다. 애당초 순서도와 클래스 다이어그램은 서로 용도부터 다른 도구이다. 알다시피 순서도는 알고리즘을 표현하기 위한 도구이고, 클래스 다이어그램은 자료구조간의 상호관계를 기술하기 위한 도구이다.

객체지향 방식으로 설계하더라도 그 알고리즘을 표현할 때 당연히 순서도를 활용할 수 있으며, 절차식 방식으로 설계하더라도 클래스 다이어그램을 이용하여 데이터들과 모듈간의 관계를 설명할 수 있다. 물론 확실히 절차식 프로그래밍에서는 거의 순서도 위주로, 반대로 객체지향 프로그래밍에서는 UML 위주로 설계가 이루어지는 것은 엄연한 사실이다.

객체지향은 기존의 방식에 비해 프로그램의 수행절차를 간소화해주긴 한다. 깔끔한 모듈화를 통해서, 단 몇 줄의 메서드 호출만으로 구성된 메인함수를 작성할 수도 있도록 도와주는건 분명하니깐. 하지만 간소화되어 코드가 대폭 줄었다고 할지라도 코드 각 부분의 실행순서는 엄연히 존재하며, 근본적으로 모듈화라는 것은 그 함수가 호출될 때 참조되어 실행되어야할 다량의 본체코드가 존재하고 단지 이를 별도의 장소로 분리해서 정리해놓는 기술이라는 사실을 잊어서는 안 된다.

절차를 줄여주고 읽기에 깔끔한 프로그램으로 보이는 것은 순전히 사용자(개발자)입장에서나 추상화를 통해 그렇게 느끼는 것이지, 시스템 내부적인 관점에서는 실제로 실행되는 코드의 양은 절차식이나 객체지향이나 큰 차이가 없으며 둘 다 한 번에 한 줄씩 '순서대로' 실행시키는 것에는 다름이 없다는 것을 명확히 이해해야할 것이다.

객체지향의 결론

  • 객체지향은 절차를 간소화하는 것이지, 결코 절차를 무시하는 게 아니다.
  • 절차지향은 변수 따로 함수 따로의 분산적이고 통일성이 없지만, 객체지향은 좀 더 모듈화되어 체계적이다.
  • 절차지향은 과도한 전역변수의 사용, 스파게티 소스, 변경과 확장이 어렵지만, 객체지향은 코드의 재사용성이 높다.
  • 절차지향은 프로그램의 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식이고, 객체지향은 반대로 자료구조와 이를 중심으로 한 모듈들을 먼저 설계한 다음에 이들의 실행순서와 흐름을 짜는 방식이다.

객체지향 특징

아래의 표는 객체지향의 대표적인 4대 특징이다. 기사 시험을 볼 때 객체지향은 '캡상추다'로 암기하곤 했다.

 슐화  외부에서는 생성한 객체가 어떤 메서드와 필드로 일을 수행하는지 몰라도 된다.  예) getter/setter
   자식클래스는 부모클래스를 물려받으며 확장 가능하다. (재사용)  예) extends 키워드
 상화  공통된 속성/기능을 묶어 이름을 붙인다. (단순화 및 객체모델링)  예) 클래스, 객체
 형성  부모클래스와 자식클래스가 동일한 요청을 다르게 처리할 수 있다. (사용 편의성)  예) 오버라이딩, 오버로딩

다양한 요구사항을 수용할 수 있는 '유연성'은 객체지향의 근본이자 핵심이다. 객체지향 프로그래밍은 유연성을 가지기에 가치가 높은 것이다. 그리고 유연성은 캡슐화, 추상화, 다형성을 이용해서 달성할 수 있다.

  1. 추상화 : 요구사항들의 공통점을 찾되, 목적과 관계 없는 불필요한 공통점들은 제거한다.
  2. 캡슐화 : 공통점을 묶어 대상화 한다.
  3. 상속 : 개별적인 차이점들을 구현한다. 이 때 이미 뽑아 놓은 공통점은 모든 차이점들에게도 상속을 이용해서 포함시켜야 한다.
  4. 다형성 : 차이점 대신 공통점을 통해 대상을 다루어야 한다. 공통점을 통해 대상을 다루려면 각각의 요구사항들이 공통점을 통해 다뤄 질 수 있어야 하는데, 다형성을 통해 지원한다.

객체지향 개념들간의 관계 UML

간략히 설명하자면 다음과 같다.

  • OOP는 유연성(Flexibility)을 가진다.
  • 유연성은 캡슐화와 추상화, 다형성을 이용해서 달성된다.
  • 상속은 캡슐화를 활용하고, 다형성은 상속을 이용해서 만들어진다.
  • 캡슐화를 통해서 가시성(Visibility) 개념이 만들어지고, 클래스 개념이 만들어진다.
  • 클래스는 타입과 필드, 그리고 메서드를 가지고 있다.
  • 클래스 개념은 인터페이스(Interface), 추상 클래스(Abstract Class), 구체 클래스(Concrete Class) 개념을 파생시킨다.
  • 객체(Object)는 구체 클래스(ConcreteClass)가 가진 개념을 포함한다.
  • 객체는 Identity를 가진다.(구체클래스를 통해 클래스가 가진 개념도 가지게 되므로 Method, Field, Type도 가지게 된다.)
  • 메서드는 프로토타입을 가지며, 추상 메서드는 메서드의 일종이다.
  • 필드는 Reference와 Primitive로 나뉜다.
  • 클래스, 메서드, 필드는 가시성을 가진다.
  • 클래스는 상속 가능(Inheritable)하다.
  • 메서드는 재정의 가능(Overridable)하고, 오버로딩 가능(Overloadable)하다.

References