티스토리 뷰
개요
각 패러다임은 프로그래머에게서 권한을 박탈한다. 어느 패러다임도 새로운 권한을 부여하지 않는다. 각 패러다임은 부정적인 의도를 가지는 일종의 추가적인 규칙을 부과한다. 즉, 패러다임은 무엇을 해야 할지를 말하기보다는 무엇을 해서는 안 되는지를 말해준다.
-Clean Architecture (로버트 C. 마틴)
프로그래밍 패러다임은 프로그래밍의 *패러다임 형태입니다. 프로그래머에게 프로그래밍의 관점을 갖게 해 주고, 결정하는 역할을 합니다.
(*패러다임: 어떤 한 시대 사람들의 견해나 사고를 근본적으로 규정하고 있는 테두리로서의 인식의 체계, 또는 사물에 대한 이론적인 틀이나 체계를 의미하는 개념)
우리가 어떠한 프로그래밍 언어를 배울 때 흔히 볼 수 있는 이야기들이 있습니다. 예를들면 C++는 객체 지향 프로그래밍이라고 하고 자바스크립트는 함수형 프로그래밍을 지원한다고 합니다. 저는 예전에 그냥 그런게 있는가 보다 하며 살짝 보기만 하고 넘어갔었는데, 프로그래밍 언어를 이해하기 위해 어떠한 프로그래밍 패러다임들이 존재하는지, 어떤 개념인지 정리할 필요가 있다고 생각하였습니다.
객체 지향 프로그래밍
객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체" 들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다.
객체 지향 프로그래밍은 클래스, 객체, 메서드의 구조로 프로그래밍 하는 것입니다. 클래스는 객체를 구성하는 틀, 객체는 클래스로 만들어진 인스턴스, 메서드는 객체가 동작하는 기능입니다.

메타몽이라는 포켓몬종(class)이 실제로 풀숲에서 hp와 mp 값을 가지고 나타났습니다. (object) 이 때 메타몽이 변신하기를 사용하여 피카츄가 되었네요. (method)
객체 지향 프로그래밍은 캡슐화, 상속, 다형성의 특징을 가집니다.
- 캡슐화: 객체의 속성과 행위를 하나로 묶고 구성된 집단을 서로 구분 짓는 선을 그을 수 있습니다. 구분선 바깥에서 데이터를 은닉할 수 있습니다.
- 상속: 부모클래스의 속성과 기능을 이어받아 사용할 수 있고 필요한 경우 일부분을 변경하여 사용할 수 있습니다.
- 다형성: *오버라이딩과 *오버로딩으로 코드의 재사용성을 높이고 관리하기 쉽게 만듭니다.
(*오버라이딩: 부모클래스의 메소드를 같은 이름으로 동작 방법을 변경(재정의)하는 것
*오버로딩: 같은 이름의 메소드를 중복으로 선언하고 매개변수는 다르게 정의하는 것)
객체 지향 프로그래밍의 핵심은 다형성에 있습니다. 의존성의 역전을 통해 소스코드의 의존성을 원하는 방향으로 설정할 수 있습니다. 이것이 객체지향이 지향하는 것 입니다. (아키텍트의 관점에서)
(*의존성의 역전: *저수준의 모듈을 *고수준의 모듈에 의존하도록 의존성의 방향을 제어흐름과 반대로 만드는 것)
(*저수준의 모듈: 구현된 객체, *고수준의 모듈: 인터페이스와 같은 객체 형태에 대한 추상적 개념)
의존성 역전을 통해 저수준의 모듈들은 독립성을 보장받게 됩니다. 그리고 이러한 요소들이 프로그램의 제어흐름의 간접적인 전환에 대해 규칙을 부과합니다.
함수형 프로그래밍
함수형 프로그래밍은 자료 처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임이다.
함수형 프로그래밍은 *람다 대수에 근간을 두고있습니다. 람다 대수가 튜링 완전성을 만족시켰기 때문에 프로그래밍에서도 쓰일 수 있었습니다.
(*람다 대수: 추상화와 함수 적용 등의 논리 연산을 다루는 형식 체계)
(*튜링 완전: 순차실행, 선택 실행, 반복 실행이 가능한 것)
함수형 프로그래밍은 함수를 통해 가변성을 분리하여 프로그램의 안정성을 높입니다. 이때 사용하는 함수의 여러가지 규칙과 개념이 있습니다.
(*가변성: 가변 변수, 가변 컴포넌트)
순수 함수
*부작용이 없는 함수를 칭합니다. 이 함수를 *1급 객체로 취급하여 사용합니다. 이를 통해 순수한 함수는 스레드 안전하고, 병렬적인 계산이 가능합니다.
*부작용
- 변수의 값이 변경됨
- 자료 구조를 제자리에서 수정함
- 객체의 필드값을 설정함
- 예외나 오류가 발생하며 실행이 중단됨
- 콘솔 또는 파일 I/O가 발생함
*1급 객체
- 함수는 다른 함수의 매개변수로 전달될 수 있음.
- 함수는 다른 함수의 결과로서 반환될 수 있음.
- 함수는 변수에 할당될 수 있음.
익명 함수
익명함수란 이름이 없는 함수를 뜻합니다. 전통적인 명령형 언어에서는 모든 함수에 이름이 부여되어야만 하지만 함수형 프로그래밍 언어에서는 이름없이 사용할 수 있습니다.
고차 함수
고차 함수는 함수를 인자로 전달받거나 함수를 결과로 반환하는 함수를 말합니다. 고차 함수는 인자로 받은 함수를 필요한 시점에 호출하거나 *클로저를 생성하여 반환합니다.
(*클로저: 일급 객체 함수의 개념을 이용하여 스코프에 묶인 변수를 바인딩 하기 위한 일종의 기술)
함수형 프로그래밍은 이처럼 여러 규칙을 함수에 부과하여 데이터의 가변성을 제어합니다. 이를통해 프로그램의 안정성과 병렬처리의 속도 향상을 꾀할 수 있습니다.
프로토콜 지향 프로그래밍
프로토콜과 익스텐션을 이용하여 컴포넌트들을 모듈화하고 넓은 범위의 타입에 상속과 같은 기능을 사용함
프로토콜은 특정 역할을 수행하기 위한 메서드, 프로퍼티, 기타 요구사항 등의 청사진입니다. 프로토콜을 채택한 타입은 요구하는 기능을 구현하여 프로토콜은 준수해야합니다. 객체 지향 프로그래밍의 인터페이스와 유사하다고 볼 수 있습니다.
이 프로토콜과 함께 익스텐션을 사용한다면 프로토콜의 요구사항을 미리 구현해둘 수 있습니다. 이것이 프로토콜 지향 프로그래밍의 장점이 드러납니다. 구조체, 클래스, 열거형 등의 구조화된 타입에 프로토콜을 사용할 수 있기 때문에 사용폭이 넓고 비용에 이점이 있습니다.
또한 *프로토콜 컴포지션을 지원하기 때문에 기능의 모듈화가 명확해 집니다. 기능을 명확히 나누어 단위로 묶어 표현하고 초기 구현을 하여 프로토콜 컴포지션을 하면 되니까요.
(*프로토콜 컴포지션: 한 타입에 여러 프로토콜을 채용할 수 있게 해주는 기능)
애플은 2015년 9월, WWDC에서 스위프트 버전 2.0을 발표하면서 스위프트는 프로토콜 지향 언어(Protocol-Oriented Language)라고 발표했습니다. Swift는 구현해야하는 여러 타입들을 protocol 이라는 규칙을 채택하여 사용하도록 만들었습니다. Swift의 모토인 Safe, Fast, Expressive을 이 프로토콜 지향 패러다임에서 느낄 수 있었습니다.
반응형 프로그래밍
반응형 프로그래밍이란, 데이터의 흐름과 변경사항의 전파에 중점을 둔 선언적 프로그래밍 패러다임이다
반응형 프로그래밍은 수식을 선언적으로 작성 해두고 데이터 값을 변경하면 즉시 변경사항이 전파되어 수식의 값이 변경되는 것이 대표적인 예제입니다.
var b = 1
var c = 2
var a = b + c
b = 10
console.log(a) // 3 (not 12 because "=" is not a reactive assignment operator)
// now imagine you have a special operator "$="
// that changes the value of a variable
// (executes code on the right side of the operator and assigns result to left side variable)
// not only when explicitly initialized,
// but also when referenced variables (on the right side of the operator) are changed
var b = 1
var c = 2
var a $= b + c
b = 10
console.log(a) // 12
(wiki의 예제)
위쪽의 a는 b가 변경되어도 값이 변하지 않았지만 밑쪽의 a 는 b가 변경되자 함께 변경되었습니다. 이러한 개념을 확장한 패러다임이 반응형 프로그래밍입니다.
이전에는 DOM 조작을 통해 화면을 구현하기 위하여 Render를 해야하는 시점에 필요한 데이터를 모두 불러와서(Pull)화면을 출력하였습니다. 하지만 반응형 프로그래밍에서는 값이 변경될때마다 변경된 값을 탬플릿으로 데이터를 전달(Push)하여 화면을 출력합니다.
(*react는 setState()할때마다 push한다)
반응형 프로그래밍은 프론트엔드 프로그래밍에서 중요합니다. 왜냐하면 비동기 프로그래밍에 유용하기 때문입니다. 기존 pull 기반의 비동기 순서를 맞추는 방식으로는 비동기가 복합적으로 존재하면 개발 난이도가 비약적으로 어려워지게 됩니다. 하지만 push 기반으로 개발한다면 문제를 쉽게 해결할 수 있습니다.
이에대한 자세한 내용은 여기를 참고하여 보시는 것을 적극 추천드립니다. 제가 단편적으로 이렇게 써놓은 글보다 이글을 정독한다면 훨씬 더 딥하고 쉽게 반응형 프로그래밍을 이해하실 수 있을 것 같습니다.
반응형 프로그래밍은 이전에 React 로 개발하며 자연스럽게 사용한 것 같은데, 이렇게 작동원리, 방식을 생각하며 사용하지는 못했습니다. 제어의 역전이라는 개념은 새롭게 알게되었는데, 비동기 처리 프로그래밍을 할 때 아주 유용하게 사용할 것 같습니다. 반응형 프로그래밍은 규칙을 부과하여 행동을 제약하는 것이 아닌, 관점을 바꾸어 상황에 유리한 프로그래밍을 하게 해준다고 느꼈습니다.
프로그래밍 패러다임에 대한 나의 생각
몇가지 프로그래밍 패러다임을 정리하며 새로운 개념도 많이 알게되었습니다. 또한 여러 패러다임들이 어떠한 관점에서 만들어졌는지 궁금했었는데 이제는 알게되어 속시원한 느낌입니다. 프로그래밍 패러다임에 우열이 있는것이 아니기 때문에 실제 개발에서 어떤 상황에서 어떤 프로그래밍 패러다임이 적합한지 판단하는 것이 중요할 것 같습니다. 손 안에 좋은 도구들이 있으면 상황에 맞게 사용해야죠!
(다만 객체 지향과 프로토콜 지향 프로그래밍 패러다임 둘중에서는 프로토콜 지향 프로그래밍이 상위호환이 아닌가 하는 생각이 듭니다. 현재 공부한 바로는 객체 지향을 조금 더 확장한 기능이 프로토콜 지향 같아서 그렇게 느끼고 있습니다.)
Reference
Clean architecture - 로버트 C 마틴. 2부 벽돌부터 시작하기: 프로그래밍 패러다임
https://blog.itcode.dev/posts/2021/08/17/dependency-inversion-principle 의존성 연전 원칙
https://mangkyu.tistory.com/111 함수형 프로그래밍이란?
https://breakout-theworld.tistory.com/50 함수형 프로그래밍과 1급 객체
https://blog.yagom.net/531/ 프로토콜 지향 프로그램
https://jinnify.tistory.com/42 프로토콜 지향 프로그램 - 1 (프로토콜이란)
https://yozm.wishket.com/magazine/detail/1334/ 프로그래밍 패러다임과 반응형 프로그래밍 그리고 Rx
'Development' 카테고리의 다른 글
애자일 방법론 (0) | 2022.03.19 |
---|