본문 바로가기

함수형 사고로 객체지향을 재해석하다 언어 경계를 넘는 하이브리드 설계 감각

storybust 님의 블로그 2025. 11. 21.

개발을 하다 보면 “클래스는 잘 나눴는데, 왜 코드가 점점 복잡해질까?”라는 의문이 생깁니다. 저도 한때는 객체지향(OOP)이 모든 문제의 해답이라고 믿었습니다. 하지만 프로젝트가 커질수록 객체 간의 의존성이 얽히고, 상태 관리가 점점 어려워졌죠. 그러다 함수형 프로그래밍(FP)을 접하면서 깨달았습니다. 객체지향이 구조를 설계한다면, 함수형은 흐름을 설계한다는 사실을요. 이 두 패러다임은 대립이 아니라 보완 관계입니다. 함수형 사고를 객체지향에 녹여내면, 코드가 훨씬 단순하고 예측 가능해집니다. 이 글에서는 TypeScript, Kotlin, Swift 같은 현대 언어를 중심으로, 함수형과 객체지향을 결합한 하이브리드 설계 감각을 이야기해보려 합니다.

 

 

객체지향의 강점과 한계, 그리고 함수형의 개입

객체지향은 현실 세계의 개념을 코드로 옮기기 좋은 패러다임입니다. 클래스, 상속, 다형성은 복잡한 시스템을 구조적으로 표현하는 데 탁월하죠. 하지만 문제는 상태(state)입니다. 객체가 많아질수록 상태 변화가 얽히고, 디버깅이 어려워집니다. 반면 함수형 프로그래밍은 불변성(immutability)과 순수 함수(pure function)를 통해 상태를 최소화합니다.

 

저는 Kotlin 프로젝트에서 data class와 copy()를 활용해 불변 객체를 다루면서, 버그가 눈에 띄게 줄어드는 걸 경험했습니다. 함수형의 핵심은 “데이터를 바꾸지 않고, 새로운 데이터를 만들어낸다”는 사고방식입니다. 이 철학을 객체지향에 도입하면, 클래스 중심의 설계가 훨씬 안정적으로 변합니다.

 

 

TypeScript에서 배우는 ‘함수형 객체지향’

TypeScript는 자바스크립트의 유연함 덕분에 함수형과 객체지향을 자연스럽게 섞을 수 있습니다. 예를 들어, 클래스 내부에서도 map, filter, reduce 같은 고차 함수를 적극적으로 활용하면, 복잡한 로직을 깔끔하게 표현할 수 있습니다. 저는 한 번은 상태 관리 로직을 전부 클래스 메서드로 구현했다가, 나중에 순수 함수로 분리했더니 테스트 코드가 절반으로 줄었습니다.

 

TypeScript의 유니온 타입 함수형 유틸리티는 객체지향 구조 안에서도 함수형 사고를 실현할 수 있게 해줍니다. 즉, “객체는 데이터의 껍데기, 함수는 행동의 본질”이라는 관점을 유지하면 코드가 훨씬 유연해집니다.

 

 

Kotlin에서 배우는 ‘함수형 문법으로 객체를 다루는 법’

Kotlin은 함수형과 객체지향이 가장 자연스럽게 공존하는 언어 중 하나입니다. let, apply, run, also 같은 스코프 함수는 객체지향의 문맥 안에서 함수형 스타일을 구현할 수 있게 해줍니다. 저는 Android 앱에서 복잡한 UI 상태를 관리할 때, copy()와 sealed class를 조합해 상태 전이를 함수형으로 표현했습니다.

 

이 방식은 if-else 분기보다 훨씬 명확하고, 새로운 상태가 추가될 때도 안전하게 확장할 수 있습니다. Kotlin의 철학은 명확합니다. “객체는 존재를 표현하고, 함수는 변화를 표현한다.” 이 두 가지를 분리하면 코드의 책임이 선명해지고, 유지보수가 쉬워집니다.

 

 

Swift에서 배우는 ‘값 중심의 설계 감각’

Swift는 함수형 개념을 언어 차원에서 적극적으로 받아들였습니다. map, flatMap, compactMap 같은 고차 함수는 컬렉션뿐 아니라 옵셔널(Optional)에도 적용됩니다. 저는 iOS 프로젝트에서 옵셔널 체이닝을 적극 활용하면서, nil 체크 로직이 거의 사라졌습니다. Swift의 함수형 사고는 “값을 중심으로 사고하라”는 철학을 강조합니다.

 

즉, 객체의 상태를 직접 바꾸기보다, 새로운 값을 반환하는 방식으로 설계하는 것이죠. 이 접근법은 UI 상태 관리나 데이터 변환 로직에서 특히 강력합니다. Swift의 구조체(struct)는 불변성을 기본으로 하기 때문에, 함수형 설계와 찰떡궁합입니다.

 

 

함수형 사고로 객체지향을 재해석하는 세 가지 관점

  • 1. 상태보다 변환에 집중하라: 객체의 내부 상태를 바꾸기보다, 새로운 객체를 반환하는 함수를 설계하세요.
  • 2. 상속보다 조합을 우선하라: 함수형의 합성(composition) 개념을 적용하면, 복잡한 상속 구조를 단순화할 수 있습니다.
  • 3. 부수효과를 최소화하라: 함수형의 핵심은 예측 가능한 코드입니다. 외부 상태를 변경하지 않으면 디버깅이 훨씬 쉬워집니다.
    저는 이 세 가지 원칙을 적용하면서, 코드 리뷰에서 “이 로직은 왜 이렇게 명확하지?”라는 피드백을 자주 받았습니다. 함수형 사고는 단순히 문법이 아니라, 코드를 바라보는 관점의 전환입니다.

 

하이브리드 설계가 주는 실질적 이점

함수형과 객체지향을 결합하면, 코드의 테스트 용이성, 확장성, 예측 가능성이 모두 향상됩니다. 예를 들어, 비즈니스 로직을 순수 함수로 분리하면 단위 테스트가 쉬워지고, 객체는 데이터와 책임만 명확히 가지게 됩니다. 또한 함수형 패턴을 도입하면, 비동기 처리나 상태 전이 같은 복잡한 문제도 훨씬 단순하게 표현할 수 있습니다. 저는 이 접근법을 통해 팀 프로젝트의 버그 리포트 수를 절반 이하로 줄인 경험이 있습니다. 하이브리드 설계는 단순히 트렌드가 아니라, 복잡한 시스템을 단순하게 유지하는 실용적 전략입니다.

 

 

객체와 함수, 그 사이의 균형을 찾는 일

결국 좋은 설계란 한쪽 패러다임에 치우치지 않는 균형의 예술입니다. 객체지향은 구조를, 함수형은 흐름을 다룹니다. 이 둘을 조화롭게 섞으면, 코드가 단단하면서도 유연해집니다. 함수형 사고로 객체지향을 재해석한다는 건, “상태를 제어하는 대신, 변화를 설계한다”는 의미입니다. 언어의 경계를 넘어 이 감각을 익히면, 어떤 기술 스택에서도 흔들리지 않는 설계 감각을 갖게 됩니다.

댓글