Nagative Programming Paradimes

지인호·2022년 2월 17일
1

TIL

목록 보기
26/28
post-thumbnail

POWERED BY CLEAN ARCHITECTURE!

*글을 읽기 전에*
- 패러다임이란 프로그래밍을 하는 방법으로, 대체로 언어 독립적이다.
- 패러다임은 어떤 프로그래밍 구조를 언제 사용해야하는지를 결정한다.

개발자의 자유를 제한하는 패러다임들에 대하여

본 글의 제목은 Nagative Programming Paradimes 로, 영문 그대로 해석하자면 부정적인 프로그래밍 패러다임들 이다. 무엇이 부정적인것일까?

본 글에서는 여러 프로그래밍 패러다임들중 개발자의 자유를 제한하는 패러다임들에 대해 소개한다. 즉, 자유도 관점에서 Nagative 한 프로그래밍 패러다임들에 대해서 소개한다.

이러한 Nagative Programming Paradime 에는 구조적 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍 3가지가 존재하며, 내가 가장 존경하는 엔지니어이신 로버트 C 마틴

앞으로도 Nagative 한 프로그래밍 패러다임은 영원히 이 3가지만 존재할 것 이다.

각 패러다임이 제한하는 것들

구조적 프로그래밍

무분별한 점프(goto)는 프로그램 구조에 해롭다

개발을 하다보면, goto 의 해로움에 대한 이야기를 듣는경우가 가끔 있다. 그렇다면 goto 가 해로우며, 구조적 프로그래밍은 어떻게 점프로인한 문제들을 해결하였을까?

우선 goto 의 해로움이라는 화두를 연 사람은 바로 데이크스트라라는 프로그래머 이다. 그는 프로그래밍을 수학적인 원리인 증명을 통해 프로그램의 오류발생을 해결하려고 하였다. 이를 위해서 그는 프로그래밍에 대한 유클리드 계층구조를 구성하려고 하였다. 이를 위해 모듈을 더 작은 단위로 재귀적으로 분해할 때 goto 가 이를 방해하는 경우가 있다는것을 알게되었고, goto 의 사용을 이러한 분할정복 접근을 방해하지 않는 사용들인 분기(if, then, else) 와 반복(do, while)를 사용함으로서 해결하려고 하였다.

이러한 이유로 인해, 구조적 프로그래밍은 if, then, else, do, while, until 같은 구조를 통해 제어흐름의 직접적인 제어에 대한 규칙을 부여하여 이를 제한한다.

객체 지향 프로그래밍

제어흐름의 간접적인 제어에대한 규칙을 부여한다

OOP 가 등장하기 이전에는 다형성을 구현하기 위해서, 함수 포인터를 사용하였다. 하지만 이러한 함수포인터의 경우 초기화와 호출에 대한 관례를 지켜야 했는데, 이 관례는 명시적인 규칙이 아니기 떄문에, 프로그래머가 규칙을 지키지 않아도 컴파일 오류가 발생하지 않았다.

이를 해결하기 위해 객체지향은 함수 포인터를 제한하고, 다형성에 대한 규칙을 추가하였다.

또한, 기존 프로그래밍 언어나 패러다임들은 의존관계와 제어흐름이 모두 한방향으로 흐르고 있었지만, 객체지향은 이러한 다형성을 통해 의존관계를 역전시킨다.


즉, 의존성 역전을 통해서 제어흐름과 관계없이 소스코드의 의존성을 설정할 수 있다.

함수형 프로그래밍

할당문에 대해 규칙을 부여한다

함수형 프로그래밍은 현재까지 소개한 모든 패러다임중 가장 빨리 나왔다.

함수형 프로그래밍 패러다임은 1930 년대 람다 계산법에서 기반하였으며, 아래에 설명할 객체지향의 문제로 인해 현재 가장 잘 사용되고있는 패러다임이다.

함수형 프로그래밍 패러다임에서 변수는 없다.
정확히는, 변수는 초기화 이후 변경되지 않으며, 이를 불변성 이라고 한다.

이러한 불변성이 대체 왜 중요할까? 어째서 함수형 프로그래밍은 개발자에게서 변수의 변경 즉 값의 재할당을 빼앗아갔는가?

답은 단순하다. 경합상태, 교착상태, 동시갱신 문제 모두 가변 변수로 인해 발생하기 때문이다.

변수가 갱신(재할당)되지 않는다면 동시에 업데이트되지 않고, 동시에 한 자원에 대한 쓰기작업이 존재하지 않으므로, 교착상태나 경합상태자체가 이루어질 수 없다.

아마 1970년대 개발자가 이 소리를 들었다면 입에 거품을 물었을것이다. 변수가 변하지 않는다는것은 메모리효율성이 급격히 떨어진다는 소리이기도한데, 하드웨어의 성능 제약에서 어느정도 벗어난 지금과는 달리, 그당시에 하드웨어는 간단한 소프트웨어를 돌리는것 조차 사람보다 큰 컴퓨터를 사용해야했기 때문이다.

여기서 우리가 주목해야할 단어는 어느정도 이다. 우리는 아직 하드웨어의 성능제약에서 완전히 벗어나지 못하였다. 그러므로 이러한 함수형 프로그래밍을 실현하기위해선 어느정도의 불변성과의 타협이 필요하다

가변성의 분리

가장 중요한 타협중 하나로, 어플리케이션 내의 가변컴포넌트와 불변컴포넌트를 분리하는 것 이다.

자바8 로 예시를 들어보자. 자바 8에는 불변컴포넌트인 즉 순수함수로만 구성된 컴포넌트인 Stream API 가 존재한다.

동시에 우리가 일반적으로 작성하는 자바 어플리케이션은 아마 가변컴포넌트일 것 이다. 이렇듯, 불변 컴포넌트와 가변컴포넌트를 분리하고, 가변컴포넌트에서의 상태변경은 트랜젝션 처리를 하여 가변변수를 여러 동시성문제들로부터 보호한다.

이벤트 소싱

그렇다면 이러한 트랜젝션 자체를 저장하는건 어떨까?
계속 이야기했듯이 하드웨어의 한계는 소프트웨어 개발자의 시야에서 급격하게 사라지고 있다(완전히 사라졌다는 뜻은 아니다)

그렇다면 전술한 가변성 분리에서 일어나는 트랜젝션 (원자성을 보장하는 상태변경작업) 자체를 저장하여, 매 조회때마다 모아진 트랜젝션을 처리하는것은 어떨까?
물론, 2020년에 당근페이에 가입한 사람의 2022년까지의 모든 입출금 트랜젝션을 저장하고, 조회시마다 처리할수는 없다. 하지만 적어도, 매일 자정 혹은 어플리케이션의 동작시간만 저장하고 이후에는 실제 값에 반영시키면 된다.

그럼에도 이이야기가 터무니없게 들린다면 git 같은 소스코드 버전관리시스템이 정확히 이방식으로 동작한다는것을 생각하면 도움이 될 것 이다.

위와같은 타협을 통해서 우리는 함수형 프로그래밍 패러다임을 실현시킬 수 있다. 즉 여러 문제들에서 해방될 수 있다. 규칙이 많아지는데 문제가 적어지다니 신기하지 않은가?

구조적/객체지향/함수형...그다음은 없다

지금까지 모든 패러다임들은 모두 프로그래머에서 권한을 박탈한다. 즉, 무엇을 해서는 안되는지를 규칙으로 부과한다. 이를 통해 현재까지 세 패러다임은 우리에게서 goto 문과 함수포인터, 할당문에 대한 권한들을 앗아갔다. 아마 더 박탈할 수 있는 권한이 있을까?

적어도 Clean Architecture 의 저자인 로버트 C 마틴은 없다고 단언하고있다.

해당 글은 Clean Architecture 에 기술된 프로그래밍 패러다임에 대한 내용을 기반으로 정리한 내용입니다. 
혹시 잘못되었거나 정확하지 않은 설명을 찾으시면 언제든지 댓글을 통해 알려주세요! 
긴 글 읽어주셔서 감사합니다 😀
profile
테오의 스프린트 17기 퍼실리테이터

0개의 댓글