본문 바로가기

[Java] 절차 지향 프로그래밍(PP) VS 객체 지향 프로그래밍(OOP)

@xuv22024. 9. 8. 12:10

절차 지향 프로그래밍 (Procedural Programming) VS 객체 지향 프로그래밍(Object Oriented Programming) 에 대해 포스팅 해보겠다

사실 지난번에 객체 지향의 특성에 대해 올렸는데, 이번에는 이 둘의 차이점을 코드를 통해 쉽게 포스팅 해보고자 한다.

사실 현대 트렌드는 거의 대부분 객체 지향 프로그래밍을 추구하는 추세이지만, 몇몇은 사실 두개의 개념을 아예 갈라치기 해놓고 생각하는 사람이 꽤 있는 것 같다.

결론부터 말하자면, 이 두가지는 정반대로 대치되는 개념이 아니다

아무리 객체 지향을 추구한다고 하더라도, 프로그램의 작동 순서는 반드시 중요한 개념이기 때문이다.


간단하게 예를 들어, 우리가 ATM이라는 객체를 만들어 사용하기로 하고, 사용자의 입력을 기다리고 있는 상태다.

사용자가 아무런 메뉴도 누르지 않았는데, 무작정 돈부터 뽑아주고 메뉴를 고르라고 할 수는 없는 것과 마찬가지이다.


절차 지향과 객체 지향 두가지 개념은 어디에 포커스를 두는지에 대한 차이점이 존재한다.

절차 지향 프로그래밍 (Procedural Programming)

  • 절차 지향 프로그래밍은 이름 그대로 절차를 지향한다 → 즉 순서를 중요하게 생각하는 방식
  • 프로그램의 흐름을 순차적으로 따르며 처리하는 방식이며, “어떻게” 를 중심으로 프로그래밍
//음악 플레이어를 절차적으로 작성
public class ProceduralProgramming {

    public static void main(String[] args) {

        int volume = 0;
        boolean isOn = false;

        isOn = true;

        System.out.println("음악 플레이어를 시작합니다.");

        //증가 2번, 감소 1번, 플레이어 상태 표시, 플레이어 끄기

        volume++;
        System.out.println("음악 플레이어 볼륨: " + volume);
        volume++;
        System.out.println("음악 플레이어 볼륨: " + volume);

        volume--;
        System.out.println("음악 플레이어 볼륨: " + volume);

        System.out.println("음악 플레이어 상태 확인");

        if(isOn == true){
            System.out.println("음악 플레이어 ON , 볼륨: " + volume);
        }
        else {
            System.out.println("음악 플레이어 OFF ");
        }

        isOn = false;
        System.out.println("음악 플레이어를 종료합니다.");
    }

위 코드는 사용자가 직접 상태 변화를 계속 체크해주고, 변동이 있으면 모든 코드를 변경해야 한다는 번거로움이 있다.

하지만 위에서 말한 것 처럼, 음악 플레이어를 키는 것부터 시작해서 각 기능을 사용하고, 사용을 종료하는 것 까지의 절차는 음악 플레이어를 사용하는데 있어 당연하고 중요한 절차이다.


다음은 객체 지향의 특성이다.

객체 지향 프로그래밍(Object Oriented Programming)

  • 말 그대로 객체를 지향한다 → 객체를 중요시 하는 방식
  • 실제 세계의 사물이나 사건을 객체로 보고 이러한 객체들 간의 상호작용을 중심으로 프로그래밍하는 방식 → 즉 “무엇을” 중심으로 프로그래밍
  • 가장 중요한건 상태(멤버 변수)와 기능(메서드)를 하나로 묶어놓고 유기적으로 상호작용할 수 있게끔 설계하는 것이 주된 목표

자 이제, 위 절차 지향 코드를 클래스, 메서드, 객체 지향을 듬뿍 첨가하여 코드를 리펙토링 해보자

//음악 플레이어의 상태와 기능을 하나로 묶은 클래스를 생성
public class MusicPlayer {
    int volume;
    boolean isOn;

    void on(){
        isOn = true;
        System.out.println("음악 플레이어를 시작합니다.");
    }

    void off(){
        isOn = false;
        System.out.println("음악 플레이어를 종료합니다.");
    }

    void volumeUp(){
        volume++;
        System.out.println("음악 플레이어 볼륨 : " + volume);
    }

    void volumeDown(){
        volume--;
        System.out.println("음악 플레이어 볼륨 : " + volume);
    }

    void status(){
        System.out.println("음악 플레이어 상태 확인");
        if(isOn){
            System.out.println("음악 플레이어 ON, 볼륨 : " + volume);
        }
        else{
            System.out.println("음악 플레이어 OFF, 볼륨 : " + volume);
        }
    }
}

위 코드를 통해, 현재 음악 플레이어의 상태를 클래스의 멤버 변수로 작성해놓고, 그 밑에는 멤버 변수를 활용하여 상태를 업데이트 하는 메서드들을 정의 해놓은 MusicPlayer 클래스이다.

이 클래스를 호출함으로써, 우리는 객체를 생성하고, 그 객체를 위한 메서드를 호출하여 사용하기만 하면 된다.

그렇다면 위 클래스를 토대로 main 메서드 코드는 얼마나 간추려졌는지고, 리펙토링 되었는지 확인하자.

//클래스에서 메서드를 바로 가져와 간결하고 가독성 좋은 코드 완성
public class ObjectOrientedProgramming {

    public static void main(String[] args) {

        MusicPlayer player = new MusicPlayer();

        player.on();

        player.volumeUp();
        player.volumeUp();

        player.volumeDown();

        player.status();

        player.off();

    }

}

한눈에 봐도 명확하게 어떤 객체가 어떤 작업을 수행하는지 확연하게 보이지 않는가?

이것이 객체 지향 프로그래밍의 주된 목표이다. -> 즉 상태와 메서드를 하나로 묶어 하나의 실제 객체로 생성하는 것을 목표로 하는 것이다.

이로써 우리는 메인 메서드에 정해 놓은 순서를 포함하여 아무 코드를 건드리지 않아도, 클래스 내부에서만 필요한 부분을 변경하여 사용할 수 있는 코드 유지 보수성과 재사용성이 훨씬 증가한 것을 확인할 수 있다.

 

둘의 중요한 차이점

  • 절차 지향은 데이터와 해당 데이터에 대한 처리 방식이 분리 되어 있지만 (상태는 클래스에서 관리, 기능는 Main에서 관리)
  •  객체 지향에서는 데이터와 그 데이터에 대한 행동이 하나의 객체 안에 포함되어 있다. (상태와 기능을 하나의 클래스안에 묶어서 관리)
xuv2
@xuv2 :: xuvlog

폭싹 늙었수다

목차