Dandy Now!
  • [SW공학] 학교 예제로 보는 절차지향과 객체지향, 뭐가 다를까?
    2025년 04월 13일 22시 00분 04초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    학교 예제로 보는 절차지향과 객체지향, 뭐가 다를까?

    소프트웨어 개발 세계에는 크게 두 가지 중요한 프로그래밍 방식이 있다. 바로 절차지향 프로그래밍(Procedural Programming, PP)객체지향 프로그래밍(Object-Oriented Programming, OOP)이다. 이 둘은 마치 세상을 바라보는 다른 두 개의 렌즈처럼, 프로그램을 만들고 문제를 해결하는 방식에서 근본적인 차이를 보인다.

    절차지향은 '어떤 순서로 일을 처리할까?'에 집중하는 반면, 객체지향은 현실 세계처럼 데이터와 관련 기능을 하나로 묶은 '객체'들이 서로 소통하며 프로그램을 만들어나간다.

    이 글에서는 이 두 가지 프로그래밍 방식의 핵심 개념을 알아보고, 우리에게 친숙한 '학교 운영'을 예시로 들어 그 차이점을 쉽고 명확하게 비교해보려 한다. 학교라는 비유를 통해 데이터 처리, 기능 구현, 코드 재사용, 확장성 등 다양한 관점에서 두 방식이 어떻게 다른지 살펴보면서, 절차지향과 객체지향의 본질적인 차이를 좀 더 직관적으로 이해하는 데 도움을 주고자 한다.

     

     

    절차지향 프로그래밍 (PP): 순서대로 착착!

    절차지향이란 무엇인가?

    • 정의: 프로그램을 일련의 순차적인 단계 또는 '절차(Procedure)'의 집합으로 간주하는 프로그래밍 패러다임이다.
    • 핵심: '무엇을 어떤 절차로 수행할 것인가?'에 중점을 둔다.
    • 절차의 의미: 단순 순서가 아닌, 특정 작업을 수행하는 코드 묶음(함수/프로시저)을 의미한다.
    • 구조: 여러 함수(프로시저) 호출로 구성되며, 정의된 순서에 따라 실행된다. 명령형 프로그래밍의 한 갈래로 볼 수 있다.

    주요 특징은?

    1. 순차적 실행: 코드는 기본적으로 위에서 아래로, 작성된 순서대로 실행된다. 마치 '일어나기 -> 씻기 -> 밥 먹기 -> 학교 가기'처럼 일련의 과정을 순서대로 코드로 표현하는 것과 같다.
    2. 함수 중심: 프로그램의 핵심 구성 요소는 함수이다. 큰 문제를 작은 기능(함수) 단위로 나누어 해결하며, 각 함수는 특정 작업을 수행한다. 함수를 통해 코드 재사용성을 일부 확보하고 프로그램 구조를 만들 수 있지만, 데이터와 그 데이터를 처리하는 함수는 분리되어 관리되는 경향이 있다.

    장점과 단점

    • 장점:
      • 컴퓨터의 실제 처리 방식과 비슷해 실행 속도가 빠를 수 있다.
      • 비교적 단순하거나 순차적인 작업을 구현하기에 직관적이다.
    • 단점:
      • 유지보수 어려움: 프로그램 전체가 긴밀하게 연결되어 있어, 코드 일부를 수정하면 예상치 못한 곳에 영향을 줄 수 있어 유지보수가 어렵다.
      • 데이터 구조 변경 문제: 데이터와 함수가 분리되어 있어 데이터 구조가 바뀌면 관련 함수들을 모두 수정해야 할 수 있다. 이는 시스템을 취약하게 만든다.
      • 전역 변수 남용 위험: 전역 변수를 많이 사용하면 코드 추적이 어렵고 부작용이 발생할 수 있다.
      • 확장성/재사용성 한계: 프로젝트 규모가 커지면 복잡성이 증가하고 코드 중복이 발생하기 쉬워 확장성과 재사용성에 한계가 있다.
      • 현실 모델링 어려움: 현실 세계의 다양한 개체와 관계를 모델링하기 어렵다.

    객체지향 프로그래밍 (OOP): 세상을 객체로!

    객체지향이란 무엇인가?

    • 정의: 프로그램을 서로 상호작용하는 '객체(Object)'들의 집합으로 보는 방식이다.
    • 핵심: 현실 세계의 사물이나 개념을 '객체'로 만들고, 이 객체들이 서로 메시지를 주고받으며 프로그램을 설계하고 구현한다.
    • 객체의 구성: 각 객체는 자신만의 상태(데이터)와 행동(기능, 메서드)을 가진다.

    주요 특징은?

    1. 객체 (Object): OOP의 기본 단위이다. 클래스라는 설계도를 바탕으로 만들어진 실제 존재(인스턴스)이며, 고유한 상태(데이터 값)와 행동(메서드)을 가진다. '홍길동' 학생이나 '소나타' 자동차처럼 구체적인 실체이다.
    2. 클래스 (Class): 객체를 만들기 위한 '틀' 또는 '설계도'이다. 특정 종류의 객체가 가져야 할 속성(데이터)과 메서드(행동)를 정의한다.
    3. 캡슐화 (Encapsulation) & 정보 은닉 (Information Hiding): 관련된 데이터(속성)와 이를 처리하는 함수(메서드)를 하나의 객체 안에 묶는 것이다. 또한, 객체 내부 데이터를 외부에서 함부로 접근하지 못하게 숨기고(정보 은닉), 정해진 방법(메서드)을 통해서만 데이터에 접근하도록 제어한다. 캡슐화는 객체의 독립성을 높여준다.
    4. 상속 (Inheritance): 새로운 클래스가 기존 클래스의 속성과 메서드를 물려받는 기능이다. 코드 재사용성을 높이고 클래스 간의 계층 구조를 만들어 프로그램을 체계적으로 관리하는 데 도움을 준다.
    5. 다형성 (Polymorphism): '여러 형태를 가질 수 있는 능력'이다. 서로 다른 클래스의 객체들이 같은 요청(메서드 호출)에 대해 각자의 방식으로 다르게 반응할 수 있는 특성이다. 주로 메서드 오버라이딩(상위 클래스 메서드를 하위 클래스에서 재정의)을 통해 구현되며, 때로는 메서드 오버로딩(같은 이름의 메서드를 매개변수만 다르게 여러 개 정의)도 포함된다. 다형성은 프로그램의 유연성과 확장성을 높여준다.
    6. 추상화 (Abstraction): 복잡한 현실 요소를 프로그램으로 표현할 때, 불필요한 세부 사항은 감추고 핵심 특징(속성, 행동)만 뽑아내 표현하는 과정이다. 클래스 자체가 현실을 추상화한 결과물이며, 복잡성을 관리하는 데 중요한 역할을 한다.

    장점과 단점

    • 장점:
      • 코드 재사용성 향상: 상속 등을 통해 기존 코드를 효과적으로 재활용할 수 있다.
      • 유지보수 용이: 캡슐화 덕분에 특정 객체 수정이 다른 곳에 미치는 영향을 줄일 수 있다.
      • 현실 세계 모델링: 복잡한 시스템을 객체 단위로 모델링하기에 적합하다.
      • 대규모 프로젝트 유리: 모듈성이 높아 팀 협업에 유리하다.
    • 단점:
      • 실행 속도: 절차지향보다 느릴 수 있다.
      • 설계 복잡성: 초기 설계에 더 많은 시간과 노력이 필요할 수 있다.
      • 복잡한 상속 구조: 상속 구조가 너무 복잡해지면 오히려 이해와 수정이 어려워질 수 있다.
      • 메모리 사용량: 객체가 많아지면 메모리 사용량이 늘어날 수 있다.
      • 만능은 아님: 단순하고 순차적인 작업에는 절차지향이 더 나을 수 있다.
    • 캡슐화의 힘: 캡슐화는 OOP의 유지보수성을 높이는 핵심 원리이다. 객체 내부를 숨기고 정해진 방법(메서드)으로만 소통하게 함으로써, 객체는 '블랙박스'처럼 작동한다. 내부 구현이 바뀌어도 외부 인터페이스만 같다면 다른 부분에 영향을 주지 않는다. 이는 절차지향에서 데이터 구조 변경 시 관련 함수를 모두 수정해야 했던 문제를 해결한다. OOP는 데이터와 관련 기능을 객체 안에 묶어 변경의 영향을 최소화한다.
    • 상속과 다형성의 양면성: 상속과 다형성은 코드 재사용과 확장에 강력한 도구이지만, 설계 복잡성을 높이고 잘못 사용하면 문제를 일으킬 수도 있다. 상속은 코드 공유를 가능하게 하고, 다형성은 다양한 하위 클래스 객체를 동일한 방식으로 처리하게 해준다. 이를 통해 기존 코드를 수정하지 않고 새로운 기능을 추가(확장)할 수 있다(개방-폐쇄 원칙). 하지만 부모-자식 클래스 간의 강한 연결은 변경을 어렵게 만들 수도 있다.
    • 현실 세계 모델링: OOP는 현실 세계의 개체를 모델링하는 데 강점을 가진다. 사람들은 세상을 속성과 행동을 가진 객체들의 관점에서 인식하는 경향이 있는데, OOP는 이러한 현실 세계를 코드 구조로 직접 매핑할 수 있게 해준다. 이는 절차지향이 프로세스 중심으로 접근하는 것과 대조된다.

    학교 비유: 절차지향 방식으로 학교 운영하기

    학교 운영을 절차지향 방식으로 구현한다면 어떨까? 이 방식은 학교 운영에 필요한 업무 절차기능을 중심으로 시스템을 설계한다.

    절차/함수 중심 설계

    • 핵심: 기능별 함수(프로시저) 생성.
      • 학생_등록(학생_데이터): 중앙 명단에 학생 정보 추가 함수.
      • 수강_신청(학생_ID, 과목_ID): 학생-과목 연결 기록 갱신 함수.
      • 수업_진행(과목_ID, 교사_ID, 강의실_ID): 수업 시간 작업 처리 함수.
      • 성적_기록(학생_ID, 과목_ID, 점수): 중앙 성적 저장소 기록 함수.
      • 성적표_생성(학생_ID): 여러 데이터 저장소에서 정보 취합, 성적표 생성 함수.

    데이터 처리 방식

    • 데이터 분리: 학생 명단, 과목 목록 등 데이터는 함수와 별개 데이터 구조(배열, 파일 등)에 저장된다.
    • 직접 접근: 함수가 데이터 구조 직접 읽기/수정.
    • 전역 변수: 학교 전체 정보(학년도 등)는 전역 변수 관리 가능.

    프로그램 흐름

    • 순차 호출: 함수들을 순차적으로 호출하여 시스템 운영. (예: 학기 초 학생_등록, 수강_신청 -> 학기 중 수업_진행 -> 학기 말 성적_기록, 성적표_생성)

    시사점 (비유)

    이 방식은 학교 행정 업무 흐름과 비슷하게 느껴질 수 있다. 하지만 만약 학생 데이터 구조가 바뀌면(예: '생년월일' 추가), 이 데이터를 사용하는 여러 함수(학생_등록, 성적표_생성 등)를 모두 찾아 수정해야 한다. 이는 절차지향의 유지보수 어려움을 보여준다.

    또한, 새로운 유형의 구성원(예: '조교')을 추가하고 다른 절차가 필요하다면, 기존 함수를 복잡하게 수정하거나 비슷한 새 함수를 많이 만들어야 할 수 있다. 이는 절차지향이 새로운 개체 유형 추가 및 시스템 확장에 한계가 있음을 보여준다.

    학교 비유: 객체지향 방식으로 학교 운영하기

    이번에는 학교 운영을 객체지향 방식으로 모델링해 보자. 이 방식은 학교를 구성하는 개체(Entity) 들에 초점을 맞춘다.

    객체 중심 설계

    • 핵심: 주요 요소(학생, 교사, 과목 등)를 클래스로 정의, 실제 객체(인스턴스) 생성 사용.
      • 학생 클래스:
        • 속성: 학번, 이름, 수강 과목 목록, 성적 정보 등
        • 행동(메서드): 수강신청하다(과목), 성적조회하다()
        • 객체 예시: johnDoe = new 학생(...)
      • 교사 클래스:
        • 속성: 교번, 이름, 담당 과목 등
        • 행동: 과제채점하다(과제), 성적부여하다(학생, 과목, 점수)
        • 객체 예시: msSmith = new 교사(...)
      • 과목 클래스:
        • 속성: 과목 코드, 과목명, 담당 교사, 수강 학생 목록 등
        • 행동: 학생추가하다(학생), 과제추가하다(과제)
        • 객체 예시: math101 = new 과목(...)

    데이터 처리 방식 (캡슐화)

    • 자체 관리: 각 객체가 자신의 데이터 관리 (예: 학생 객체가 자기 성적 정보 보유).
    • 메서드 통한 접근: 데이터 접근은 보통 해당 객체 제공 메서드 통해 이루어짐 (예: johnDoe.성적조회하다()).
    • 정보 은닉: 내부 데이터 저장/관리 방식 외부에서 알 필요 없음.

    객체 간 상호작용

    • 메시지 교환: 객체 간 상호작용 통해 운영.
      • 예: 학생 수강 신청 -> johnDoe 학생 객체가 수강신청하다 메서드 호출 -> 내부에서 math101 과목 객체의 학생추가하다 메서드 호출.
      • 예: 교사 성적 부여 -> msSmith 교사 객체가 성적부여하다 메서드 호출 -> 관련 학생, 과목 객체 데이터 갱신.

    OOP 특징 활용 예시

    • 상속: 학생 클래스를 상속받아 학부생대학원생 클래스를 만들 수 있다. 공통 속성/메서드를 공유하면서 대학원생논문작성하다() 메서드를 가질 수 있다.
    • 다형성: 교장 객체가 평가하다(교직원) 메서드를 가질 때, 이 메서드는 교사 객체와 행정직원 객체(둘 다 교직원 상속 가정) 모두 처리할 수 있다. 각 객체는 자신에게 맞게 재정의된 방식으로 평가를 수행하게 된다.

    시사점 (비유)

    이 객체 모델은 실제 학교가 다양한 구성원들이 상호작용하며 운영되는 방식과 매우 유사하다. 따라서 복잡한 시스템을 설계할 때 더 직관적일 수 있다.

    만약 성적 평가 정책이 변경된다면, 관련 로직은 교사과목 클래스의 성적 관련 메서드 내부에 캡슐화되어 있을 가능성이 높다. 해당 부분만 수정하면 되므로 다른 시스템에 영향을 주지 않는다. 이는 캡슐화를 통한 유지보수성 향상을 보여준다.

    또한, '조교' 같은 새로운 구성원을 추가하는 것도 상속을 이용하면 비교적 간단하다. 교직원 클래스를 상속받는 조교 클래스를 만들면, 기존 교직원 객체와 상호작용하던 코드가 다형성 덕분에 큰 변경 없이 조교 객체와도 작동할 수 있다. 이는 OOP의 확장성 측면에서의 장점을 보여준다.

    학교 비유로 본 절차지향 vs 객체지향 비교 분석

    학교 비유를 통해 두 방식의 주요 차이점을 더 자세히 비교해 보자.

    데이터와 기능 처리 방식 비교

    • 절차지향 (PP):
      • 데이터(학생 명단 등)와 기능(등록 함수 등) 분리됨.
      • 함수가 외부 데이터 전달받거나 전역 데이터 참조하여 작업 수행.
      • 비유: 행정실 별도 캐비닛 파일(데이터) + 각 절차 직원(함수) 접근/수정. 파일 양식 변경 시 모든 관련 절차 수정 필요.
    • 객체지향 (OOP):
      • 데이터(속성)와 기능(메서드)이 객체 안에 함께 묶임 (캡슐화).
      • 비유: 각 학생(객체)이 자기 정보(속성) 갖고 스스로 행동(메서드)하는 자율적 존재. 외부와는 정해진 방식 소통.
    • 분석: OOP 캡슐화가 PP의 데이터-기능 분리 문제(데이터 무결성, 유지보수 어려움) 해결. 응집도↑, 결합도↓. PP는 데이터 구조 의존성 광범위 유발 가능, OOP는 데이터/연산 지역화 및 접근 제어로 변경 범위 축소, 무결성 향상.

    코드 재사용성 및 확장성 비교

    • 절차지향 (PP):
      • 주로 기존 함수 호출로 코드 재사용.
      • 기능 확장 시 새 함수 작성 또는 기존 함수 수정/복붙 (코드 중복, 위험 부담).
      • 비유: '동아리 등록' 새 절차 생성. 기존 '학생 등록'과 유사 시 코드 복붙 가능성(중복). '교직원 등록' 등 새 유형 필요 시 기존 함수 복잡 수정 필요 가능.
    • 객체지향 (OOP):
      • 상속(일반->특수 클래스)과 합성(객체가 다른 객체 사용) 통해 재사용성 향상.
      • 새 클래스(하위) 추가하여 기존 인터페이스 따르도록 함으로써 기존 코드 수정 없이 기능 확장 용이 (다형성, 개방-폐쇄 원칙).
      • 비유: 사람 클래스 상속 -> 학생, 교사 클래스 (공통 속성 재사용). 시간제학생 클래스를 학생에서 상속 -> 기존 학생 다루던 코드, 다형성 덕에 시간제학생도 대부분 그대로 처리 가능.
    • 분석: OOP가 PP보다 더 정교한 메커니즘(상속, 다형성) 제공하여 재사용/확장 용이. 대규모 복잡 시스템 개발에 더 적합 이유 중 하나. PP 재사용은 함수 단위 국한, 변형 대응 위해 코드 중복/복잡 수정 필요 가능. OOP 상속은 구조적 공유/특성화 가능, 다형성은 유연한 확장 지원.

    현실 세계 모델링 관점 비교

    • 절차지향 (PP):
      • 프로세스/알고리즘 중점. 현실 개체 모델링 간접적 (데이터 구조 통해).
      • 비유: 학교 시뮬레이션 = '입학 처리 -> 반 배정 -> 수업 진행' 등 절차 초점. '학생'/'교사'는 절차에 의해 처리되는 데이터 레코드.
    • 객체지향 (OOP):
      • 상태/행동 가진 객체로서 현실 개체 직접 모델링. 객체 간 관계/상호작용이 현실 반영.
      • 비유: 시뮬레이션 = 학생, 교사, 과목 객체 생성 시작. 객체 간 상호작용 ('교사'가 '과목' 가르침, '학생'이 '과목' 수강 신청)으로 진행. 더 자연스럽고 직관적일 수 있음.
    • 분석: OOP는 명확한 개체 구성 문제에 대해 PP보다 더 직관적/직접적 매핑 제공 경우 많음. 문제 영역과 솔루션 간 '의미론적 간격' 축소 -> 설계 이해/소통/발전 용이. PP는 프로세스 중심 관점 강요, 개체 중심 문제와 부합하지 않을 수 있음. OOP 핵심 구성 요소(클래스, 객체)는 개체/특성 직접 표현.

    핵심 차이점 요약: 한눈에 보기

    절차지향과 객체지향은 프로그램 구조화에 대한 근본적으로 다른 접근 방식 제공함.

    핵심 철학

    • 절차지향 (PP):
      • 작업을 어떻게 완료할지에 초점 (프로시저/함수 중심).
      • 하향식(Top-down) 설계 방식 경향.
      • 데이터와 연산(함수) 분리.
    • 객체지향 (OOP):
      • 어떤 개체(객체)가 존재하고 상호작용하는지에 초점.
      • 상향식(Bottom-up) 설계 방식(객체 먼저 만들고 조합) 경향.
      • 데이터와 관련 연산(메서드) 객체 내 함께 묶음 (캡슐화).

    주요 차이점 정리

    • 기본 단위: PP는 함수(프로시저), OOP는 객체/클래스.
    • 데이터/기능 처리: PP는 분리, OOP는 캡슐화 통해 통합.
    • 재사용/확장 메커니즘: PP는 함수 호출, OOP는 상속, 합성, 다형성 활용.
    • 모델링 접근: PP는 프로세스 중심, OOP는 개체 중심으로 현실 모델링.

    학교 비유 요약

    • 절차지향: 학교의 업무 절차(등록 절차, 성적 처리 절차 등) 집중.
    • 객체지향: 학교 구성 개체(학생 객체, 교사 객체 등)와 그들의 상호작용 집중.

    상호 배타적이지 않은 관계

    • 중요: 두 패러다임은 완전히 상호 배타적 개념 아님.
    • OOP 메서드 내부 로직은 종종 절차적 방식으로 작성됨.
    • OOP는 PP 개념 포함/확장한 것으로 볼 수도 있음.
    • 문제 성격, 프로젝트 요구사항 따라 적합 패러다임 선택 중요.

    비교 요약표

    특징 절차지향 프로그래밍 (PP) 객체지향 프로그래밍 (OOP)
    주요 초점 프로세스, 절차, 함수, 행동 순서 객체, 개체, 상호작용, 상태와 행동
    기본 단위 프로시저 / 함수 객체 / 클래스
    데이터 & 기능 처리 분리됨; 데이터는 함수에 전달되거나 전역적임 객체 내부에 함께 묶임 (캡슐화)
    핵심 개념 프로시저, 순차 실행, 하향식 설계 객체, 클래스, 캡슐화, 상속, 다형성, 추상화
    코드 재사용성 주로 함수 호출을 통해 상속, 합성, 다형성을 통해
    확장성 함수 추가/수정; 복잡해질 수 있음 새로운 클래스 추가(주로 상속); 일반적으로 더 용이함
    유지보수성 대규모 시스템에서 어려울 수 있음; 높은 결합도 위험 캡슐화/모듈성 덕분에 대규모 시스템에서 일반적으로 더 용이함
    현실 세계 모델링 간접적; 프로세스 중심 개체 기반 문제에 더 직접적이고 직관적임
    학교 비유 예시 학생_등록() 함수가 학생 데이터 파일을 처리함. 학생 객체가 수강신청하다() 메서드를 통해 과목 객체와 상호작용함.

    마무리하며

    절차지향과 객체지향 프로그래밍은 소프트웨어 설계/구조화에 각기 다른 철학과 접근 방식 제공함.

    • 절차지향:
      • 순차 작업 흐름 명확 표현, 특정 상황 높은 실행 성능 가능.
      • 단점: 시스템 규모/복잡성 증가 시 유지보수/확장 어려움.
    • 객체지향:
      • 캡슐화, 상속, 다형성 통해 코드 재사용성↑, 유지보수성/확장성 개선.
      • 복잡 현실 문제 직관적 모델링 지원.
      • 단점: 초기 설계 복잡성↑, 실행 속도 불리 가능.

    학교 운영 비유 통해 보았듯, 각 패러다임은 문제 해결에 대한 다른 관점 제시. (PP: '어떻게' 작업 수행 / OOP: '무엇' 존재, 상호작용)

    궁극적 패러다임 선택은 다음 요소 고려 필요:

    • 문제 특성
    • 프로젝트 규모/복잡성
    • 개발팀 경험
    • 장기적 유지보수/확장 계획

    현대 언어 다수 패러다임 지원 추세지만, 각 패러다임 근본 원리/장단점 이해는 효과적/효율적 소프트웨어 개발에 여전히 필수적임.

    728x90
    반응형
    댓글