본문 바로가기

SearchDeveloper/클린 아키텍처

[2] 3~6장 패러다임 개요 (구조적, 객체지향, 함수형 프로그래밍)

언어의 역사

1945년: 앨런 튜링이 바이너리 언어로 반복분, 분기문, 할당, 서브루틴, 스택 을 활용해 사람이 식별가능한 형태로 프로그램을 코드로 작성

1940년대 후반:“언어” 어셈블리 처음 등장. 바이너리 코드로 짜야했던 프로그래머의 고된일이 줄어듦.

1951년: 최초의 컴파일러 A0 등장. by 그레이스 호퍼

패러다임이란

프로그래밍을 하는 방법. 언제 어떤 프로그래밍 구조를 사용해야 하는지 결정한다.

세 가지 패러다임을 알려주겠다.

구조적 프로그래밍

프로그래밍의 역사

다익스트라는 네덜란드 최초의 프로그래머라는 직업을 가진 사람이다. 다익스트라는 어려운 프로그래밍을 해결하기 위해 증명이라는 수학적인 원리를 적용했다.

“프로그래머" 는 입증된 구조를 이용하고, 이 구조를 코드와 결합시켜 코드가 올바름을 스스로 증명하게 하는 방식이다.

구조적 프로그래밍의 탄생

증명을 하려면, 필수적으로 분할 정복 접근법(작은 문제로 쪼개 해결하며 위로 올라가는 기법) 을 써야 한다.

근데 goto 로 인해 모듈은 작은 단위로 분해하는데 방해가 됐다.

반면 방해가 되지 않는 경우도 있었는데, 분기(if/else) 나 반복(do/while) 을 쓸 때 였다.

그리고 이미 2년전 모든 프로그램은 순차, 분기, 반복 세 가지 구조만으로 모든 프로그램을 표현할 수 있다는 사실을 증명됐다.

즉, 모듈을 증명 가능하게 하는 제어 구조 = 모든 프로그램을 만들 수 있는 제어 구조 임을 밝혀졌고, 구조적 프로그래밍이 이렇게 탄생했다.

(혜인) 구조적 프로그래밍은 순차, 분기, 반복을 가지고 프로그래밍한다는 뜻 같다. 절차적이랑 약간 다른 듯..?

소프트웨어는 수학이 아닌 과학이다.

  • 수학은 참임을 입증하는 원리다.
  • 과학은 거짓임을 입증하는 원리다. 거짓을 입증하지 못하면 참이다.

테스트도 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 순 없다고 했다.

구조적 프로그래밍의 의미

프로그램을 증명 가능한 세부 기능으로 나누고, 테스트를 통해 거짓인지 증명하려고 시도한다. 만약 테스트가 통과한다면 참이라고 여길 수 있는 것이다.

그러니, 소프트웨어 아키텍트는 모듈, 컴포넌트, 서비스가 테스트하기 쉽도록 만들어야 한다.

객체 지향 프로그래밍

객체지향을 설명하기 위해 나오는 캡슐화, 상속, 다형성에 대해 살펴보자

캡슐화

객체 지향은 데이터와 함수를 쉽고 효과적으로 캡슐화할 수 있게 한다. 하지만 객체지향 언어만 캡슐화를 지원하는 건 아니다.

ex. C 언어는 헤더파일로 구분을 지어 완벽한 캡슐화를 제공

심지어 자바와 C#은 헤더와 구현체를 분리하지 않고 캡슐화를 강제하지 않기 때문에(잘하겠지라는 믿음을 기반) 오히려 캡슐화를 약화시켰다고 할 수 있다.

상속

: 단순히 변수와 함수를 하나의 유효 범위로 묶어 재정의 하는 일

상속도 객체 지향에서만 할 수 있는 새로운 개념은 아니지마 편리한 방식으로 제공하는건 맞음.

ex. C 언어에서 불편하지만 마치 상속받은 것처럼 구현할 수는 있음

다형성

객체 지향 이전에도 다형성을 표현할 수는 있었다. 단, 포인터로.

이 포인터를 응용한 것이 다형성이다. 그래서 객체 지향이 새롭게 만든 개념은 아니지만 좀 더 안전하고 편리하게 사용할 수 있게 해준다.

다형성의 장점

예를 들어 입출력 드라이버가 있으면 새 입출력 장치가 추가된다고 해도 프로그램 소스코드를 변경할 필요가 없다. 입출력 드라이버 구현체만 바꿔주면 되기 때문이다. 이렇게 플러그인처럼 뺐다 꼽기 쉬워 플러그인 아키텍처라고 하며 장치 독립적으로 기능하는 장점이 있다. 객체 지향의 등장으로 인해 플러그인 아키텍처를 쉽게 적용할 수 있게 됐다.

의존성 역전

소스코드 의존성의 원래 방향은 제어의 흐름을 따르게 된다.

고수준 함수가 저수준 함수를 호출하는 순대로 흐른다.

그런데 인터페이스가 추가되면,

ML1과 I 인터페이스 사이의 소스 코드 의존성(상속 관계)이 제어 흐름과 반대가 된다.

즉 다형성이 있으면 소스 코드 의존성을 원하는 방향으로 설정할 수 있다.

그렇게 되면 장점은 UI 와 DB 가 업무 규칙의 의존, 즉 플러그인이 되기 때문에 UI 와 DB 를 업무 규칙에 독립적으로 배포할 수 있는 배포 독립성을 가지고, 개발 독립성을 가진다.

결론: 객체 지향이란 다형성을 이용해 전체 시스템의 모든 소스 코드 의존성에 대한 절대적인 제어 권한을 획득할 수 있는 능력이다. → 고수준과 독립적으로 저수준 모듈을 독립적으로 개발하고 배포할 수 있다.

함수형 프로그래밍

= 람다 계산법

함수형 프로그래밍의 특징: 가변 변수가 없다. 변수 x 가 한 번 초기화되면 절대 변하지 않는다.

가변 변수가 없을 때 장점?

race condition, deadlock, 동시 업데이트 문제가 발생하지 않는다.

상태 변경은 트랜잭션 메모리 같은 기법(ex. CAS 알고리즘)을 사용해 가변 변수를 보호한다.

이벤트 소싱

가변 변수로 인한 문제를 줄이기 위해. 발생한 모든 트랜잭션(이벤트)를 누적하여 저장한다. 상태값이 필요해지면 단순히 상태의 시작점부터 모든 트랜잭션을 처리한다.

  • 이런 기법이 가능한 이유: 지금 시대는 처리 능력이 빠르고, 저장공간과 램이 비싸지 않기 때문.
  • 모두 저장하면 장점: 데이터에 변경이 일어나지 않으므로 동시성 문제도 싹 사라진다.

(혜인) 불변성이라는 점에서 함수형과 연계되어 이 개념이 출현한 듯. 데중심이랑 DDD 에서도 들어본 용어이다

데이터 중심 애플리케이션 설계 11장 - 이벤트 소싱

DDD 이벤트 소싱

https://gyuwon.github.io/blog/2020/06/23/essence-of-event-sourcing.html

 

 

 

레퍼런스

 

클린 아키텍처

'SearchDeveloper > 클린 아키텍처' 카테고리의 다른 글

[6] 17~19 경계  (1) 2024.01.13
[5] 15~16 아키텍처와 독립성  (1) 2024.01.13
[4] 12~14 컴포넌트  (0) 2023.11.05
[3] 8~11장 SOLID  (0) 2023.11.05
[1] 1~2 장 설계와 아키텍처란?  (0) 2023.11.05