객체 지향 프로그래밍(OOP)과 함수형 프로그래밍(FP)

sean k·2023년 3월 30일
0

개념정리

목록 보기
4/7

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

현실 세계의 사물을 모델링하여 소프트웨어를 개발하는 방법론입니다.

  • 데이터와 이를 처리하는 동작을 하나로 묶어서 객체(Object)라는 개념으로 표현합니다. 이러한 객체는 데이터와 메서드(Method)라는 동작을 함께 가지고 있으며, 객체 간에는 상속(Inheritance)과 다형성(Polymorphism) 등의 관계가 존재합니다.
  • 데이터와 동작을 캡슐화(Encapsulation)하여 외부에서 직접적으로 접근하는 것을 제한합니다. 이를 통해 객체의 내부 구현을 숨기고, 객체 간의 결합도를 낮춤으로써 유연하고 확장 가능한 코드를 작성할 수 있습니다.
  • 다양한 디자인 패턴(Design Pattern)을 이용해 객체 간의 상호작용을 구성합니다.
  • 데이터와 함수를 하나의 논리적인 단위로 묶어서 유지보수 및 코드 재사용성을 증가시키는 장점이 있습니다.
// Person 클래스 정의
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // 정보 출력 메서드
  printInfo() {
    console.log(`이름: ${this.name}, 나이: ${this.age}`);
  }
}

// Student 클래스 정의 (Person 클래스를 상속받음)
class Student extends Person {
  constructor(name, age, grade) {
    super(name, age);
    this.grade = grade;
  }

  // 학년 정보 출력 메서드
  printGrade() {
    console.log(`${this.name}의 학년은 ${this.grade}학년 입니다.`);
  }
}

// Person 객체 생성
const person1 = new Person('홍길동', 30);
person1.printInfo(); // 출력: 이름: 홍길동, 나이: 30

// Student 객체 생성
const student1 = new Student('김철수', 18, 1);
student1.printInfo(); // 출력: 이름: 김철수, 나이: 18
student1.printGrade(); // 출력: 김철수의 학년은 1학년 입니다.

위 코드에서는 Person 클래스와 Student 클래스를 정의하고, Student 클래스가 Person 클래스를 상속받아 구현되었습니다. Person 클래스는 name과 age라는 속성과 printInfo()라는 메서드를 가지고 있으며, Student 클래스는 Person 클래스의 속성과 메서드에 더해 grade라는 속성과 printGrade()라는 메서드를 가지고 있습니다.

이렇게 객체 지향 프로그래밍을 이용하면 객체 간의 관계를 상속과 다형성 등의 개념으로 구현할 수 있으며, 객체 내부의 데이터와 동작을 캡슐화하여 유연하고 확장 가능한 코드를 작성할 수 있습니다.

함수형 프로그래밍(Functional Programming)

수학적 함수 개념을 이용하여 소프트웨어를 개발하는 방법론입니다.

  • 상태를 변경하는 것이 아닌, 함수 호출을 통해 값을 전달하고 반환하는 방식으로 동작합니다. 이러한 함수 호출을 통해 부작용(Side Effect)를 최소화하며, 코드의 가독성과 재사용성을 높일 수 있습니다.
  • 일급 함수(First-Class Function) 개념이 중요합니다. 이는 함수를 변수나 데이터 구조체에 할당하거나, 함수의 인자로 전달하거나, 함수를 반환하는 등의 기능을 제공합니다. 이를 통해 함수를 모듈화하여 코드를 작성할 수 있으며, 함수의 조합을 통해 더욱 복잡한 동작을 수행할 수 있습니다.
  • 불변성(Immutability)도 중요한 개념입니다. 이는 데이터가 변하지 않는 것을 의미합니다. 이를 통해 다양한 문제를 해결할 수 있으며, 코드의 신뢰성을 높일 수 있습니다.
  • 병렬 처리와 분산 처리 등의 분야에서 특히 효과적입니다. 이는 상태를 변경하지 않으므로 여러 개의 스레드나 프로세스에서 동시에 실행할 수 있기 때문입니다.
  • JavaScript에서는 함수를 변수에 할당하거나, 함수를 반환하는 등의 기능을 지원하며, 불변성을 유지하는 함수형 라이브러리도 존재합니다.
  • 부수 효과(side effect)를 최소화하여 안정적인 코드를 작성할 수 있는 장점이 있습니다.
// 1. 함수를 변수에 할당하기
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;

// 2. 함수를 인자로 전달하기
const operate = (fn, a, b) => fn(a, b);

const result1 = operate(add, 2, 3); // 5
const result2 = operate(multiply, 2, 3); // 6

// 3. 함수를 반환하기
const makeAdder = x => y => x + y;

const add3 = makeAdder(3);
const add5 = makeAdder(5);

const result3 = add3(2); // 5
const result4 = add5(2); // 7

// 4. 불변성 유지하기
const list = [1, 2, 3];

// 배열의 내장 함수인 map 함수를 이용하여 새로운 배열을 반환하면서 불변성을 유지합니다.
const doubledList = list.map((num) => num * 2);

// 5. 커링(Currying) 사용하기
const addCurry = a => b => c => a + b + c;

const add1 = addCurry(1);
const add2 = add1(2);
const result5 = add2(3); // 6

위 예시 코드에서 add 함수는 함수형 프로그래밍 예시 코드입니다. 이 함수는 인자 x를 받고, 또 다른 함수를 반환합니다. 반환된 함수는 인자 y를 받고, x와 y를 더한 값을 반환합니다. add5 변수는 add(5)를 호출하여 반환된 함수를 할당한 것입니다. add5(3)을 호출하면 5와 3을 더한 8이 출력됩니다.

적합한 패러다임을 선택하기

객체 지향 프로그래밍을 사용하는 상황

객체 지향 프로그래밍은 복잡한 데이터 구조를 다루는 데에 적합한 프로그래밍 패러다임입니다. 때문에 큰 규모의 프로젝트에서는 객체 지향 프로그래밍이 적합합니다.
예를 들어, 게임에서 캐릭터나 아이템 등의 다양한 속성을 가진 객체를 처리할 때처럼 코드를 디버깅하거나 수정해야 하는 경우, 객체 지향 프로그래밍은 클래스를 이용해 코드를 모듈화하고, 코드의 재사용성을 높일 수 을 높일 수 있습니다. 또한, 코드를 클래스 단위로 구성하기 때문에 코드를 파악하기 쉽고 수정하기도 용이합니다.

함수형 프로그래밍을 사용하는 상황

함수형 프로그래밍은 상태를 변경하지 않고, 병렬 처리가 필요한 경우, 대규모 시스템 개발이 필요한 경우, 코드 유지보수가 중요한 경우에 적합합니다. 부수 효과(side effect)를 최소화하여 안정적인 코드를 작성할 수 있고 데이터가 불변(immutable)하게 다루어져야 하는 경우 데이터를 다룰 때 생기는 문제들을 줄일 수 있습니다. 데이터를 분할하고 각각의 조각에 대해 함수를 실행하는 것이 가능하기 때문입니다.

0개의 댓글