왜 객체지향인가?

혁콩·2024년 1월 5일
0

객체지향

목록 보기
1/3
post-thumbnail

객체 지향 프로그래밍은 컴퓨터 패러다임 중 하나이다.
그렇다면 컴퓨터 프로그래밍 패러다임이란 무엇일까?

위 목록은 Wikipedia 에서 제공하는 프로그래밍 패러다임 문서 목록이다. 얼핏봐도 50개가 넘어가는 패러다임들이 있는데, 도대체 프로그래밍 패러다임이 뭐길래 이렇게 많은걸까? 시작하기에 앞서 간단히 알아보자.

프로그래밍 패러다임

Programming paradigms are a way to classify programming languages based on their features.

프로그래밍 패러다임은 기능에 따라 프로그래밍 언어를 분류하는 방법이다. 위키피디아에 나와있는 정의다.

많고 많은 프로그래밍 패러다임 중 가장 핫한 3가지를 꼽아보자면 절차 지향, 객체 지향, 그리고 함수형 을 꼽을 수 있겠다.

위에서 말하길, 기능에 따라 패러다임을 분류한다고 했는데, 각 패러다임은 어떤 기능을 가질까?

절차 지향은 재사용성이 높은 코드를 별도의 함수로 분리하고, 함수를 호출하며 진행되는 프로그래밍 방식이다.

객체 지향객체를 최소 단위로 두고, 객체 간 상호 작용을 통해 진행되는 프로그래밍 방식이다.

함수형은 모든 데이터의 처리를 수학적 함수로 취급하는 프로그래밍 방식이다.

현재의 프로그래밍 패러다임은 위 사진과 같이 나타났고, 발전했다. 참 아이러니한것이, 각 패러다임이 나타난 순서와 부흥한 순서가 완전히 반대라는 것이다.

과거 제한된 하드웨어의 성능에 의해 절차 지향을 중심으로 발전하기 시작했다.
이후 하드웨어가 발전함에 따라 성능은 조금 뒤쳐질 수 있지만 튼튼한 설계를 할 수 있는 객체 지향이 두각을 드러냈다.
하드웨어의 성능 발전이 주춤하여 코어의 개수를 늘리기 시작하며 동시성의 개념이 중요해졌으며, 외부 상태를 갖지 않아 동기화 없이 병렬 처리를 보장할 수 있는 함수형 패러다임이 무섭게 발전하고 있다.

본론으로 돌아와서, 이 많은 패러다임 중 객체 지향은 왜 사용하는 걸까?

객체 지향 프로그래밍

객체 지향 프로그래밍은 프로그래밍에서 필요한 데이터를 추상화시켜 상태행위를 가진 객체를 만들고, 객체들 간 유기적인 상호 작용을 통해 로직을 구성하는 프로그래밍 방법이다.
즉, 실세계에 존재하는 사물 혹은 개념을 소프트웨어를 통해 표현하는 것이다.
이를 통해 얻는 이점은 무엇일까? 예시를 보며 생각해보자.

냉장고 안의 음식들을 관리하고 싶어.

위와 같은 요구 사항이 들어왔다고 생각해보자. 어떻게 작성해볼 수 있을까?

import java.util.ArrayList;
import java.util.List;

public class Sample {
    static class Food {
        private String name;
        private boolean isSpoiled;
        
        public Food() {}
        public Food(String name, boolean isSpoiled) {
            this.name = name;
            this.isSpoiled = isSpoiled;
        }

        public String getName() {
            return name;
        }
    }

    static class Refrigerator {
        List<Food> foods = new ArrayList<>();

        public void add(Food food) {
            foods.add(food);
        }

        public List<Food> getFoodList() {
            return foods;
        }

        public Food pop(Food food) {
            Food toFind = new Food();
            for(Food f:foods) {
                if (f.name.equals(food.name)) {
                    toFind = f;
                    foods.remove(f);
                    break;
                }
            }
            return toFind;
        }
    }

    public static void main(String[] args) {
        Refrigerator refrigerator = new Refrigerator();

        refrigerator.add(new Food("milk", false));
        refrigerator.add(new Food("apple", false));

        refrigerator.getFoodList().forEach(f -> System.out.println(f.getName()));
    }
}

위 코드는 음식과, 음식을 갖는 냉장고 클래스가 있는 것을 바로 알아볼 수 있다. 객체 지향은 실세계와 유사하게 작성되므로, 이 객체가 어떤 상태를 가지며, 어떤 행위를 할 수 있는지를 쉽게 파악할 수 있다.

이 때, 새로운 요구사항이 들어왔다.

음료수를 구분해서 놓고 싶은데..

public class Sample {
    static class Food {
		...
    }

    static class Beverage extends Food {
        private boolean isSingle;

        public Beverage(String name, boolean isSpoiled, boolean isSingle) {
            super(name, isSpoiled);
            this.isSingle = isSingle;
        }
    }

    static class Refrigerator {
		...
    }

    public static void main(String[] args) {
        Refrigerator foodRefrigerator = new Refrigerator();
        Refrigerator beverageRefrigerator = new Refrigerator();

        beverageRefrigerator.add(new Beverage("milk", false, true));
        foodRefrigerator.add(new Food("apple", false));

        beverageRefrigerator.getFoodList().forEach(f -> System.out.println(f.getName()));
    }
}

어쩌다보니 냉장고를 2대 놓은게 되어버렷지만, 완벽하게 구분할 수 있게 됐으니 뭐 어떤가!

위와 같이 상속을 통해 요구 변화에 유연하게 프로그램을 확장하며 코드를 재사용함으로써 생산성을 높일 수 있다는 장점 또한 있다.

객체 지향에는 상속 말고도 추상화, 다형성, 캡슐화 라는 원칙이 있는데, 이 내용은 다음 포스트에서 다뤄보자.

몇가지 더 추가해서 요약하자면 객체 지향코드 재사용이 용이하고 확장성이 뛰어나며, 모듈화를 통해 업무 분담에 유리하다.

단점 또한 있다. 위에서 말했듯, 절차 지향에 비해 속도가 상대적으로 느리며, 생성한 객체가 많아질 시 리소스를 그만큼 많이 차지하게 된다. 또한 튼튼한 구조를 설계할 수 있지만, 설계를 위해 많은 시간과 노력이 필요하다. 함수형 패러다임에선 크게 고민할 필요 없는 동시성에 대한 처리 또한 필요하다.

그래서 왜?

그렇다면 왜 객체 지향을 선택해야 하는가? 절차 지향보다 느리고, 함수형과는 다르게 동시성 처리도 해야 하는데 말이다.

사실 객체 지향 패러다임을 꼭 선택할 필요는 없다.
처음 말했던 내용을 다시 말하자면

프로그래밍 패러다임은 기능에 따라 프로그래밍 언어를 분류하는 방법이다

즉, 정답이 있는게 아닌 선택의 문제라는 것이다. 선택이 문제가 아니라면 중요한 건 선택의 이유다.

빠른 처리속도가 필요하다면 절차 지향을 고려해 볼 수도 있고, 동시성이 중요한 프로그램을 제작해야 한다면 함수형 패러다임을 선택할 수 있을 것이다.

튼튼한 설계를 갖는 크고 복잡한 프로그램을 설계해야 할 땐 객체 지향 프로그래밍을 선택하면 될 것이다.

그렇다면, 다시 돌아가서 처음 요구 사항을 다시 보자.

냉장고 안의 음식들을 관리하고 싶어.

이런 간단한 요구 사항에 왜 객체 지향을 선택했냐 라고 묻는다면 어떻게 대답해야할까?

객체 지향이 좋다는데요?

라고 대답하면 큰일...날 것이다. 처한 상황은 모두 다를 것이고, 동일한 상황이라도 다른 선택을 할 수 있다. 같이 일하는 팀원은 다른 선택을 하고 싶을 수도 있다. 이럴 때 필요한 것이 이유다.


누군가 왜? 라고 묻는다면 선택한 이유는 말할 수 있어야 합리적인 선택을 한 게 아닐까?

참고자료

wikipedia - Programming Paradigm
3대 프로그래밍 패러다임의 등장과 부흥

profile
아는 척 하기 좋아하는 콩

0개의 댓글