함수형 프로그래밍 - 함수형 vs 객체지향형

Doodream·2022년 10월 3일
0
post-thumbnail

객체지향형

  • 객체 기반의 캡슐화/은닉화를 통해 가변상태의 무결성을 유지합니다.
  • 객체의 데이터와 잘게 나뉜 기능이 단단하게 유착되어 응집도가 높아집니다.
  • 잘게 나뉜 기능을 구현하기 위해 특수한 자료형을 생산합니다.

→ 객체 지향은 데이터와 데이터 관계의 본질에 초점을 맞춥니다.

함수형

  • 소수의 자료형에서 작동하는 독립적이고 분리된 함수를 더 많이 사용하게 됩니다.
    → 함수형은 기능에 초점을 맞춥니다.

자바스크립트는 두 특징을 모두 갖고 있습니다.
이러한 특징을 가진 두 패러다임을 적절히 잘 결합하면 최고의 코드를 생산할 수 있습니다.

함수형객체지향형
합성 단위함수객체(class)
프로그래밍 스타일선언적명령형
데이터와 기능독립적인 순수함수가 느슨하게 결합클래스 안에서 메서드와 단단하게 결합
상태 관리객체를 불변 값으로 취급인스턴스 메서드를 통해 객체를 변이시킴
제어 흐름함수와 재귀루프와 조건 분기
스레드 안전동시성 프로그래밍 가능캡슐화하기 어려움
캡슐화모든 것이 불변이라 필요없음데이터의 무결성 때문에 필요

동시성 프로그래밍 : Concurrent : 시분할로 여러 작업이 마치 동시에 일어나는 것처럼 보이게 하는것

객체를 값으로 취급

먼저 자바스크립트에서는 원시값 (String, Number, Symbol, Boolean, BigInt, undefined, null)을 const 선언을 사용해서 정의를 하면 선언된 변수는 더 이상 변하지 않으므로 해당 변수에 대한 불변성을 지킬 수 있습니다.

하지만 자바스크립트에서 거의 대부분의 객체는Object의 인스턴스 입니다. 즉, 불변성을 지키기 어렵습니다.
이를 위해서 객체를 값으로 취급하는 방식을 소개합니다.

값 객체 패턴 (value object Pattern)

const userInfo = (name, age)  => {
  const _name = name
  const _age = age || 0
  return {
    name: () => {
      return _name
    },
    age: () => {
      return _age
    },
    modifyInfo: (newName, newAge) => {
      return userInfo(newName, newAge)
    }
  }
}


const DoodreamInfo = userInfo('Luke', 29)
DoodreamInfo.age() // 29
const newDoodreamInfo = DoodreamInfo.modifyInfo('Doo', 30)
newDoodreamInfo.age() // 30

위 패턴에서은 const 선언으로 정의한 DoodreamInfo 라는 객체값의 프로퍼티에 직접 값을 넣지 않음으로서 객체 내부의 값을 직접 접근 시키지 않습니다. age와 name과 같은 함수 프로퍼티를 사용함으로서 getter와 같은 역할을 하게됩니다.

이렇게 정의된 인스턴스는 값을 정의한 후로 내부에 정의된 데이터가 변하지 않습니다. 즉, 외부에서 객체내부의 값을 직접 수정하지 못함으로서 객체 불변성을 지키게됩니다. 이러한 패턴을 사용하는 데이터는
tuple, pair, point, zipCode, coordinate, money, date 같은 형식으로 만들어지는 형식이 모두 값 객체 패턴입니다.

이런식의 패턴은 기존 값을 변하게 않게 하기 위해서 레거시 객체와 상호작용하거나, 계층적 데이터 구조에서 사용되게 됩니다.

가동부를 깊이 동결 : Object.freeze()

const freezeObj = Object.freeze({data: 'text', data2: 'text2'})
freezeObj.data = 2
freezeObj.data // 'text'

Object.freeze 라는 함수는 객체의 한 단계의 프로퍼티들의 값들을 동결합니다. Object 안의 메타속성(숨김 속성)인 writable 속성을 false로 설정하여 프로퍼티 값이 바꾸니는 것을 방지합니다. 하지만 명확하게 프로퍼티에 객체가 있는 중첩 객체 데이터들은 동결하지 못합니다.
이러한 동결을 얕은 동결(shallow freeze) 이라고 표현합니다.

확실하게 모든 데이터들을 동결하고 싶다면 재귀적으로 밑의 모든 객체에 대하여 freeze 적용을 해주어야 한다.


// MDN 출처
function deepFreeze(object) {
  // 객체에 정의된 속성명을 추출
  const propNames = Object.getOwnPropertyNames(object);

  // 스스로를 동결하기 전에 속성을 동결
  for (let name of propNames) {
    let value = object[name];
    object[name] = value && typeof value === "object" ? deepFreeze(value) : value;
  }
  return Object.freeze(object);
}

애플리케이션에서 하나의 객체의 값을 절대 변경시키지 않고 데이터의 흐름을 이어가는 것은 상당히 불편합니다.
그때 그때 원본객체의 값을 이용해서 새로운 객체를 생성하여 엄격하게 한 객체에 대한 불변성을 지키며 대응한다면 큰 도움이 될 것 입니다.

profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글