본문 바로가기

IT공부/기타

[ETC] 함수형 프로그래밍과 객체 프로그래밍의 차이

** 함수형 프로그래밍이란?

 : 함수가 중심이 되는 패러다임,

   모든 작업은 함수로 구성되며 데이터를 불변하게 다룰려고 노력

 

   데이터를 불변하게 다루며, 함수 호출에 따른 부작용을 최소화

   이로 인해 프로그램 예측이 가능하고 테스트가 쉬워짐

 

   함수는 데이터에 대한 반환을 나타내며,

   순수 함수(Pure Function)는 주어진 입력에 대한 항상 동일한 출력을 생성

 

   일반적으로 상속과 다양성을 지원하지 않음

   대신 함수를 조합하여 원하는 기능을 만들기 위해 함수를 조립하고 재사용

 

 

** 객체 프로그래밍이란?

 : 객체가 중심이 되는 패러다임,

   데이터와 해당 데이터를 조작하는 메서드(함수)를 하나의 단위로 묶어서 사용

 

   객체의 상태를 변경할 수 있으며 , 이러한 상태 변경은 메서드 호출을 통해 이루어짐

   객체 내부의 상태를 변경할 수 있는 것은 부작용을 가져올 수 있음

 

   메서드는 객체의 동작을 나타내며, 객체 내부의 상태에 접근하고 변경할 수 있음

   다양한 객체는 다양한 메서드를 가질 수 있으며, 다형성을 통해 동일한 메서드 명을 다르게 구현할 수 있음

 

   상속과 다형성을 지원

   상속을 통해 새로운 객체의 기능을 확장하거나 재정의 가능

 

 

** 두 패러다임은 각자의 장점과 적용 사항이 있으며, 프로그램의 목적과 요구사항에 따라 선택해야 함

 

   함수형 프로그래밍은 병렬처리와 상태관리가 중요한 경우에 유용

   객체형 프로그래밍은 대규모 시스템을 모델링하고 유지하는데 유용

 

   최근에는 두 패러다임을 조합하여 사용하는 추세이며,

   이를 함수형 객체지향 프로그래밍(FP-OOP) 또는 함수형 리액티브 프로그래밍(FRP)이라고 부름

 

 

** 코드 비교(객체 지향은 자바, 함수 지향은 코틀린)

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void sayHello() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }

    public void haveBirthday() {
        age++;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        person.sayHello();
        person.haveBirthday();
        System.out.println(
        	"After a year, " + person.getName() + 
            " is now " + person.getAge() + " years old."
        );
    }
}

 

 

data class Person(val name: String, val age: Int)

fun sayHello(person: Person) {
    println("Hello, my name is ${person.name} and I am ${person.age} years old.")
}

fun haveBirthday(person: Person): Person {
    return person.copy(age = person.age + 1)
}

fun main() {
    val person = Person("Alice", 30)
    sayHello(person)
    val personAfterBirthday = haveBirthday(person)
    println("After a year, ${personAfterBirthday.name} is now ${personAfterBirthday.age} years old.")
}

 

 

** 주요 차이점

 : 자바에서는 클래스와 메서드를 사용하여 객체를 정의하고 상태를 변경,

   코틀린에서는 클래스와 함수를 사용하여 불변 데이터를 다루고 변환

 

   코틀린에서는 함수가 부작용 없이 입력과 출력 간의 관계를 나타내는 데 중점을 두며, 객체의 상태를 변경하지 않음

   자바에서는 객체의 상태를 직접 변경하는 메서드가 호출되어 부작용이 발생할 수 있음

 

   함수형 프로그래밍은 데이터 불변성과 순수 함수를 강조하여 부작용을 최소화하고 예측 가능한 코드를 작성하는데 목표

   객체형 프로그래밍은 데이터와 메서드를 객체로 묶어서, 객체의 상태를 변경하는 것이 일반적

 

   (ex)

      ㄴ 객체형 프로그래밍은 객체를 통하여 메서드 접근(캡슐화)

              person.sayHello();

              person.haveBirthday();

      ㄴ 함수형 프로그래밍은 그냥 접근

              sayHello(person)

              val personAfterBirthday = haveBirthday(person)
              println("After a year, ${personAfterBirthday.name} is now ${personAfterBirthday.age} years old.")

 

 

** 함수형 프로그래밍의 장점

 : 병렬처리 - 함수형 프로그래밍은 데이터의 불변성을 강조하므로 다수의 스레드나 프로세스를 병렬처리 하기 쉬움,

   예측가능성 - 순수 함수와 불변 데이터는 예측 가능한 동작을 가짐 디버깅과 테스트가 용이,

   모듈화 - 함수형 코드는 작은 함수로 나누기 쉽고 모듈화와 재사용성이 높음,

   오류 감소 - 불변 데이터와 부작용의 최소화로 인해 예기치 않은 오류를 줄일 수 있음

 

   => 함수형 프로그래밍 언제 도입할까?

        ㄴ 병렬 처리나 동시성이 중요한 프로젝트일 때

        ㄴ 예측 가능한 동작과 테스트 용이성이 요구되는 경우

        ㄴ 데이터 처리와 변환을 주요 작업하는 경우

        ㄴ 함수를 매개변수로 전달하거나 반환하는 기능이 필요한 경우

 

 

** 객체 지향 프로그래밍의 장점

 : 모델링 - 객체 지향 프로그래밍은 현실 세계의 개체와 상호 작용을 모델링 하기에 적합하며

                 코드를 직관적으로 이해하기 쉽게 만듦,

   재사용성 - 상속, 다형성, 캡슐화 등의 기능을 사용하여 코드 재사용성을 높일 수 있음,

   유지 보수성 - 객체 지향 코드는 코드의 일부를 변경하더라도 다른 부분에 미치는 영향을 줄이는 데 도움줌,

   대규모 프로젝트 - 대규모 시스템을 구축하고 관리할 때 객체 지향 프로그래밍은 코드를 구조화 하는 데 도움됨

 

   => 객체 지향 프로그래밍 언제 도입할까?

        ㄴ 현실 세계의 개념을 모델링하거나 데이터와 동작을 객체로 묶어야 할 때

        ㄴ 코드의 재사용성이 높아야 할 때

        ㄴ 대규모 소프트웨어 시스템을 개발하고 유지 보수해야 할 때

        ㄴ 다형성과 상속 등의 객체 지향 특성이 필요한 경우

 

 

 

 

** 출처

   : ChatGPT와의 대화