IT/책

[Clean Architecture] 2부, 프로그래밍 패러다임

Terriermon 2021. 11. 27. 15:10

Clean Architecture

2부, 프로그래밍 패러다임



패러다임이란
-
프로그래밍을 하는 방법, 언어에 독립적

-어떤 프로그래밍 구조를 사용할 지, 언제 이 구조를 사용해야 하는 지 결정


3장, 패러다임 개요

3가지 패러다임: 구조적 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍

구조적 프로그래밍
- 최초로 적용된 패러다임

- 무부별한 점프(goto문장)은 프로그램에 해로움
-> if/then/else, do/while/until 등 구조로 변경

- 제어 흐름의 직접적인 전환에 대해 규칙을 부과


객체 지향 프로그래밍
- 스택 프레임을 힙으로 옮기면 함수 호출이 반환된 이후에도 함수에서 선언된 지역 변수가 오랫동안 유지할 수 있음을 발견 -> 클래스의 생성자

- 지역 변수 = 인스턴스 변수, 중첩 함수 = 메서드

- 제어흐름의 간접적인 전환에 대해 규칙을 부과


함수형 프로그래밍
- 람다 계산법: 불변성, 심볼의 값이 변경되지 않음

- 할당문에 대해 규칙을 부과


결론
- 패러다임은 프로그래머에게서 권한을 박탈함

- goto문, 함수 포인터, 할당문을 사용할 수 없음




4장, 구조적 프로그래밍

goto문의 멸망

증명
- 데이크스트는 증명을 이용해 어려운 프로그래밍을 해결하고자 함

- 유클리드 계층구조를 프로그래밍에 적용 **성공하지 못함 **
-> 프로그래머는 입증된  구조를 이용하고 코드가 올바르다는 사실을 스스로 증명

- goto문장을 사용하면 제어 단위로 모듈을 재귀적으로 세분화 하는 것이 가능

- 모든 프로그램은 순차, 분기, 반복으로 표현할 수 있음

- 증명
> 순차 구문: 순차 구문의 입력을 순차 구문의 출력까지 수학적으로 추적

> 분기: 열거법을 재적용, 분기 통과 시 경로를 열거

> 반복: 귀납법 사용


기능적 분해
- 증명 가능한 작은 단위로 재귀적으로 분해 할 수 있음
> 모든 모듈을 기능적으로 분해


테스트
- 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 수 없음


결론
- 프로그래밍에서 반증 가능한 단위를 만들어 내는 것이 구조적 프로그래밍이다.



5장, 객체 지향 프로그래밍

객체지향(Object-Oriented, OO)
- 캡슐화, 상속, 다형성

캡슐화
- 데이터와 함수를 쉽고 효과적으로 캡슐화 하는 방법을 OO언어가 제공

- 데이터와 함수가 응집력 있게 구성된 집단을 서로 구분지음

- 데이터 은닉, 일부 함수만 노출

- pirvate, protected, public

- OO가 완벽한 캡슐화를 제공하지는 않음


상속
- 변수와 함수를 하나의 유효 범위로 묶어서 재정의

- 다중 상속을 OO가 쉽게 제공함


다형성
- STDIN, STDOUT 등 유닉스 운영체제를 표준 함수로 모아둠
>  장치: 열기, 닫기, 읽기, 쓰기, 탐색

- OO를 사용하면 다형성을 쉽게 사용할 수 있음

- 제어흐름을 간접적으로 전환하는 규칙을 부과

- 변경이 쉬움


의존성 역전
- 전형적인 호출 트리의 경우 main 함수가 고 -> 중 -> 저 함수들을 호출함
> 소스코드 의존성은 제어흐름을 따르게 됨

- main 함수가 고수준 함수를 호출하기 위해서 함수가 포함된 모듈 이름을 지정해야 함
Ex) #include, import, using 등
> 소스 코드의 의존성은 제어 흐름에 따라 결정

의존성 역전(interface 등)
- 제어 흐름과 방향이 일하지 않음

- 소스코드 의존성이 낮음
> 모듈을 독립적으로 배포 (배포 독립성)
> 서로 다른 팀에서 각 모듈을 독립적으로 개발 (개발 독립성)



6장, 함수형 프로그래밍

- 함수형 언어에서 변수는 변경되지 않음
> 가변 변수는 프로그램 실행 중 상태가 변할 수 있음

불변성과 아키텍처
- 경합 조건, 교착 조건, 동시 업데이트 문제 모두 가변 변수로 인해 발생됨

- 다수의 스레드와 프로세스를 사용할 때, 가변 변수가 없으면 발생하지 않음


가변성의 분리
- 불변 컴포넌트에서는 순수하게 함수형 방식으로만 작업 처리
> 트랜잭션 메모리와 같은 실천법을 통해 가변 변수를 보호

- 재시도 기법으로 가변 변수 보호
ex) atom: 값 변경 시, 반드 시 swap! 이용


이벤트 소싱
- 상태가 아닌 트랜잭션을 저장하는 전략, 상태가 필요해지면 상태의 시작점부터 트랜잭션을 처리

- 데이터 저장소에서 변경과 삭제가 일어나지 않아 업데이트 시 문제가 일어나지 않을 수 있음

- 저장 공간과 처리 능력만 충분하다면, 애플리케이션이 완전한 불변성을 갖도록 할 수 있음


결론
- 구조적 프로그래밍은 제어흐름의 직접적인 전환에 부과되는 규율
- 객체 지향 프로그래밍은 제어흐름의 간접적인 전환에 부과되는 규율
- 함수형 프로그래밍은 변수 할당에 부과되는 규율

소프트웨어는 순차, 분기, 반복, 참조로 구성됨