Git Product home page Git Product logo

dreamofcleanarchitecture's Introduction

foreunwoo's github stats

dreamofcleanarchitecture's People

Contributors

foreunwoo avatar

Watchers

 avatar

dreamofcleanarchitecture's Issues

구조적 / 객체지향적 / 함수형 프로그래밍 정리

TIL

날짜: April 4, 2022

# Clean Architecture

## 1. 구조적 프로그래밍


증명


  • 증명(proof)라는 수학적인 원리 적용 → 문제 해결 시도

    • 비전 : 공리, 정리, 따름정리, 보조정리로 구성되는 유클리드 계층구조 만드는것
  • 유클리드 계층구조를 사용하여 프로그래머도 사용 가능하다고 믿음

    • 프로그래머는 입증된 구조를 이용하고, 구조를 코드와 결합 시켜, 코드가 올바르다는 사실을 스스로 증명하게 되는 방식
  • goto 문장

    • 모듈을 더 작은 단위로 재귀적으로 분해하는 과정에 방해되는 경우 발견
    • 모듈을 분해할 수 없다면, 합리적으로 증명할 때 필수적인 기법인 분할 정복 접근법 사용 못함
    • 모듈을 분해할 때 문제가 되지 않는 경우 있음
      • if / then / else 와 do / while 과 같은 분기와 반복이라는 단순한 제어 구조에 해당
      • 이런 종류의 제어 구조만을 사용한다면 증명 가능한 단위로까지 모듈을 재귀적으로 세분화 가능
  • 이러한 제어구조는 순차 실행과 결합 할때 특별함을 알게 됨

    • 모든 프로그램을 순차, 분기, 반복이라는 세가지 구조만으로 표현할 수 있는 사실을 증명
    • 모듈을 증명하게 하는 바로 제어구조가 모든 프로그램을 만들 수 있는 제어 구조의 최소 집합과 동일하는 사실로 구조적 프로그래밍이 탄생
  • 단순한 열거법을 이용해 순차 구문이 올바름을 입증할 수 있다는 사실 보여줌

    • 각 순차 구문의 입력을 순차 구문의 출력까지 수학적 추적
  • 분기

    • 열거법을 재 적용하는 방식으로 처리
    • 먼저 분기를 통한 각 경로를 열거
    • 결과적으로 두 경로가 수학적으로 적절한 결과를 만들어낸다면, 증명은 신뢰
  • 반복

    • 귀납법을 사용하여 증명

해로운 서명서


  • goto문 해로움을 야기
    • 10년간 이슈 > 결국 goto 문장이 거의 사라짐
    • 제어 흐름을 제약 없이 직접 전환할 수 있는 선택권 자체를 언어에서 제공하지 않음
  • 자바의 경우
    • break문이나 예외가 goto 문이랑 유사

기능적 분해


  • 구조적 프로그래밍
    • 모듈을 증명 가능한 더 작은 단위로 재귀적으로 분해 할 수 있게 되었음
    • 결국, 모듈을 기능적으로 분해 할수 있음을 뜻함
    • 거대한 문제 기술서를 받더라도 문제를 고수준의 기능들로 분해
    • 분해한 기능들은 구조적 프로그래밍의 제한된 제어 구조를 이용하여 표현
  • 구조적 분석이나 구조적 설계 기법이 1970년 후반~1980년대에 걸쳐 인기
    • 대규모 시스템을 모듈과 컴포넌트로 나눔
    • 더 나아가 모듈과 컴포넌트는 입증할 수 있는 아주 작은 기능들로 세분화

테스트


  • “테스트는 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 수 없다"고 말한적 있음
  • 프로그램이 잘못되었음을 테스트를 통해 증명할 수 있지만, 프로그램이 맞다고 증명할 수는 없음
  • 소프트웨어는 과학과 같음
    • 최선을 다하더라도 올바르지 않음을 증명하는데 실패함으로써 올바름을 보여주기 때문
  • 구조적 프로그래밍
    • 증명 가능한 세부 기능 집합으로 재귀적으로 분해할 것을 강요
    • 이후, 테스트를 통해 증명 가능한 세부 기능들이 거짓인지를 증명하려고 시도
    • 거짓임을 증명하려는 테스트가 실패한다면, 이 기능들은 목표에 부합할 만큼 충분히 참이라 여김

결론


  • 구조적 프로그래밍이 가치있는 이유
    • 프로그래밍에서 반증가능한 단위를 만들어 낼 수 있는 능력 때문
    • 아키텍처 관점에서는 기능적 분해를 최고의 실천법 중 하나로 여기는 이유
    • 가장 작은 기능에서부터 가장 큰 컴포넌트에 이르기까지 모든 수준에 대해 반증 가능성에 대해 주도
    • SW 아키텍트는 모듈, 컴포넌트, 서비스가 쉽게 반증 가능하도록 (테스트하기 쉽도록) 만들기 위해 분주히 노력

## 2. 객체지향적 프로그래밍


  • 좋은 아키텍처를 만드는 일은 객체지향 설계 원칙을 이해하고 응용하는데서 출발
  • OO란?
    • 실제 설계를 모델링하는 새로운 방법
    • OO는 현실세계와 의미적으로 가깝기 때문에 OO를 사용하면 SW를 좀 더 쉽게 이해 할 수 있음
    • 본질 설명 위해 세가지 개념을 적절하게 조합하거나, 최소한 세가지 요소를 반드시 지원
      • 캡슐화
      • 상속
      • 다형성

캡슐화


  • 데이터와 함수를 쉽고 효과적으로 캡슐화 하는 방법을 OO언어가 제공
  • 데이터와 함수가 응집력 있게 구성된 집단을 서로 구분 짓는 선을 만듬
    • 구분선 바깥에서 데이터는 은닉
    • 일부 함수만이 외부에서 노출
  • 실제 OO언어에서 각각 클래스의
    • private 멤버 데이터
    • public 멤버 함수로 표현

상속


  • 상속이란
    • 단순히 어떤 변수와 함수를 하나의 유효 범위로 묶어서 재 정의하는 일에 불과
  • 단일 상속 개념을 사용

다형성


  • 함수를 가리키는 포인터를 응용한 것이 다형성이라 함

다형성이 가진힘


  • 장치에 의존적인 수많은 프로그램을 만들고 나서야, 이들 프로그램이 다른 장치에서도 동일하게 동작할 수 있도록 만든것이 필요
    • 플러그링 아키텍처
      • 입출력 장치 독립성을 지원하기 위해 만들어졌고,
      • 거의 모든 운영체제에서 구현
  • OO의 등장으로 언제 어디서든 플러그인 아키텍처 적용 할 수 있게 됨

의존성 역전


  • 다형성이 나오기전 SW 구조
    • 호출 트리에서 소스 코드 의존성의 방향은 반드시 제어 흐름을 따르게 됨
    • 제어흐름은 시스템의 행위에 따라 결정
    • 소스 코드 의존성은 제어 흐름에 따라 결정
  • 인터페이스 사이의 소스 코드 의존성(상속 관계)이 제어 흐름과 반대
    • 의존성 역전
  • OO언어가 다형성을 안전하고 편리하게 제공한다는 사실을 통해 소스 코드 의존성을 어디에서든 역전시킬 수 있다는 뜻을 의미
  • 소스코드 의존성은 소스 코드 사이에 인터페이스를 추가함으로써 방향을 역전시킬 수 있음
  • 소스코드 의존성이 제어흐름의 방향과 일치되도록 제한되지 않음
  • 호출하는 모듈이든 아니면 호출 받는 모듈이든 관계없이 소프트웨어 아키텍트는 소스코드 의존성을 원하는 방향으로 설정 가능
  • 분리된 컴포넌트 또는 배포 가능한 단위(예 : jar, DLL, Gem 파일등) 로 컴파일 할 수 있고,
  • 이 배포 단위들의 의존성 역시 소스 코드 사이의 의존성과 같음
  • 시스템의 모듈을 독립적으로 배포할 수 있게 되면, 서로 다른 팀에서 각 모듈을 독립적으로 개발 할 수 있음 → 개발 독립성

결론


  • 00란
    • 다형성을 이용하여 전체 시스템의 모든 소스 코드 의존성에 대한 절대적인 제어 권한을 획득할 수 있는 능력
    • 아키텍트는 플러그인 아티텍처를 구성
    • 고수준의 정책을 포함하는 모듈은 저수준의 세부사항을 포함하는 모듈에 대해 독립성 보장
    • 저수준의 세부 사항은 중요도가 낮은 플러그인 모듈로 만들 수 있음
    • 고수준의 정책을 포함하는 모듈과는 독립적으로 개발하고 배포할 수 있음

## 3. 함수형 프로그래밍


불변성과 아키텍처


  • 변수의 가변성을 염려하는가?
    • 경합조건, 교착상태 조건, 동시 업데이트 문제가 모두 가변 변수로 인해 발생
    • 락이 가변적이지 않다면 교착상태도 일어나지 않음
  • 동시성 애플리케이션에서 모든 문제, 즉 다수의 스레드와 프로세스를 사용하는 모든 애플리케이션은 가변 변수가 없다면 문제는 발생되지 않음
  • 아키텍트라면
    • 동시성(concurrency)문제에 지대한 관심이 필요
    • 스레드와 프로세스가 여러 개인 상황에서도 설계한 시스템이 여전히 강건
    • 불변성이 정말로 실현 가능한지 확인 해봐야함

가변성의 분리


  • 불변성에서 가장 타협되는 것중 하나는 애플리케이션

  • 애플리케이션 내부의 서비스를 가변 컴포넌트와 불변 컴포넌트롤 분리

  • 불변 컴포넌트에서

    • 순수하게 함수형 방식으로만 작업이 처리
    • 어떤 가변 변수도 사용되지 않음
  • 불변 컴포넌트는

    • 변수의 상태를 변경할 수 있는 , 즉 순수 함수형 컴퍼넌너가 아닌 하나 이상의 다른 컴포넌트와 서로 통신
  • 상태 변경은

    • 컴포넌트를 갖는 동시성 문제에 노출
    • 트랜잭션 메모리와 같은 실천법을 사용하여 동시 업데이트와 경합 조건 문제로부터 가변 변수를 보호
    • 트랜잭션 메모리는 데이터베이스가 디스크의 레코드를 다루는 방식과 동일한 방식으로 메모리의 변수 처리
    • 즉, 트랜잭션을 사용하거나 또는 재시도 기법을 통해 이를 변수로 보호
  • 애플리케이션을 제대로 구조화하려면 변수를 변경하는 컴포넌트와 변경하지 않는 컴포넌ㄴ트를 분리

    • 분리하려면 가변 변수들을 보호하는 적절한 수단인 필요
  • 현명한 아키텍트라면 가능한 한 많은 처리를 불변 컴포넌트로 옮겨야 하며, 가변 검포넌트에서는 가능한 많은 코드를 빼내어야 한다

이벤트 소싱


  • 상태가 아닌 트랜잭션을 저장하자는 전략
  • 상태가 필요해지면 단순히 시작점부터 모든 트랜잭션을 처리

결론


  • 구조적 프로그래밍 : 제어흐름의 직접적인 전환에 부과되는 규율
  • 객체 지향 프로그래밍 : 제어흐름의 간접적인 전환에 부과되는 규율
  • 함수형 프로그래밍 : 변수 할당에 부과되는 규율
  • SW, 즉 컴퓨터 프로그램은 순차, 분기 , 반복, 참조로 구성.

4/4 스터디 정리📝

클린아키텍처 4~6장

중근

구조적 프로그래밍의 역사가 새롭게 느껴졌다.
구조적 프로그래밍은 옛날 방식이라고만 생각했다.
최근에는 쓰이지 않는 것으로 생각했는데, 테스트 기반이 구조적 프로그래밍에서 출발했다는 사실을 알게 되면서 나의 선입견이 깨졌다.

다형성이라는 게 구조적 프로그래밍에서 기반은 캡슐화나 상속에 대해서는 기반은 그대로나
쉽게 바꿔주는 부분이다. 이 파트는 다형성을 가장 중요하게 다룬 것 같다.
함수 포인터의 영역을 지정해준다는 게 위험하다는 사실이 인상 깊었다.

함수형 프로그래밍에 대해서
동시성이나 비동기에서 영향이 있다는 것이 새롭게 느껴졌다.
안드로이드 패러다임이 상태값에 따라서 화면을 변경해주고 처리되는 로직으로 바뀌고 있는데,
요새 왜 그런 패러다임으로 바뀌는지 알게 되었다.
가변 변수를 보호하기 위해서 가는 게 아닐까 생각하게 됨.

세 개의 프로그래밍 방식을 알아야지만 아키텍처 이해가 가능해서 이 개념들을 짚고 넘어가는 게 아닐까? 하는 생각이 들었다.

은우

테스트 얘기를 하면서 소프트웨어는 과학과 같다는 말이 나온다.
최선을 다하더라도 올바르지 않음을 증명하는데 실패함으로써 올바름을 보여주기 때문이라는 말이 인상적이었다.
테스트의 중요성을 한 번 더 느끼게 되었음.

다수의 스레드와 프로세스를 사용하는 애플리케이션에서 발생하는 모든 문제는 가변 변수가 없다면 절대 생기지 않는데,
그렇다면 불변성은 정말로 실현 가능할지 궁금해졌다.

이벤트 소싱에서 트랜잭션을 저장한다는 얘기가 나오는데, 예로 소스 코드 버전 관리 시스템을 같이 든다.
소스 코드 버전 관리 시스템에서 커밋 로그 하나가 트랜잭션이 아닐지 생각해봄.

6/1 스터디 정리

중근

컴포넌트라는 개념이 아직 생소하다.
지금은 이론적인 것만 배운 것 같고, 적용하기엔 아직 어렵다.
직접 만들고 사용을 할 때 정리한 것들을 다시 참고해서 응집도나 결합을 다시 체크해 봐야 할 것 같다.

컴포넌트 단위가 배포 단위라는 거라고 할 때 jar 파일이라고 하니 조금 더 이해가 되었다.
이걸 실질적으로 어떻게 프로젝트에 녹일 수 있을까? 고민하게 되었다.
지금 할 수 있는 건 ui 컴포넌트 정도인데, 그걸로 좀 더 내 걸로 만들 수 있지 않을까 싶은 기대감이 있음.

이 장은 컴포넌트 내에서의 SOLID 원칙을 얘기하는 것 같다.
모듈과 컴포넌트의 차이? 컴포넌트는 좀 더 동적인 개념이고, 그에 비해 모듈은 좀 더 정적이다.
컴포넌트 == 독립적인 실행 프로그램
예를 들어서, 네트워크면 네트워크를 관장하는 모듈, 즉 그 집합 자체가 컴포넌트가 아닐지

응집도와 결합도에 대한 이해가 조금 부족하지 않나? 그것들을 생각하면서 개발했던 경험이 부족한 것 같다.

은우

그 전 장에서는 클래스에 대한 개념을 주로 다뤘는데 컴포넌트는 그에 비해서 더 큰 개념인 것 같다.
컴포넌트 == 패키지라고 생각했는데, 패키지보다는 더 큰 개념인 것 같음.
컴포넌트 < 패키지(모듈의 집합) < 모듈(함수들의 집합)
빠른 이해를 돕기 위해 패키지라고 생각하자면, 만약 탈퇴 로직을 작성해야 할 때 Leave 패키지를 만들어 관련 클래스들을 모아놓는데 그런 부분에서 여기서 설명하는 개념(REP, CCP)들이 적용되지 않나 싶었다.

릴리즈와 재사용성의 연관성?
소프트웨어 컴포넌트가 릴리스 절차를 통해 추적 관리되지 않거나 릴리스 번호가 부여되지 않는다면 해당 컴포넌트를 재사용하고 싶어도 할 수도 없고, 하지도 않을 것이다.
p.113 다이어그램에 대해 좀 더 얘기가 필요할 듯.

14장 컴포넌트 결합 쪽을 읽으면서 SOLID 개념을 확장해서 설명하고 있다는 느낌이 들었다.
개념들간 연결되어 있다는 생각이 들었음.
이전 장에서나 이 장(SDP, SAP)에서도 의존성 역전을 강조하는데 인터페이스를 좀 잘 활용해야겠다고 생각.
인터페이스를 어떻게 잘 설계할 수 있을지 고민하게 되었다.

4/11 스터디 정리

규칙 [ 내가 설명할 수 있는 단어로 내것으로 만들자 ]

  • 이것이 무엇인지
  • 왜 사용해야 하는지
  • 어떻게 프로젝트에 적용할지 (BBOXX 화면에 적용해볼 수 있는 부분을 찾기)
    • 화면 : 감정일기 작성 부분
    • 3주차 - 다음 스터디까지 정리해오기

중근

  • SRP : 단일 책임에서는 오해와 사실 중 하나의 함수 단위가 아니라 데이터 구조 그 범위라는 것을 말한 내용 그거만 새롭게 알게 됨
  • OCP : 확장을 해야 되는 부분 그러니까 이게 진짜 실질적으로 확장을 할까 아니면 재사용을 할까 이걸 계속 고민을 해야 되는 것 같다
  • LSP : 자바에서는 상속 개념을 많이 사용하고 있었으나, 코틀린에서는 어떻게 쓰는지 확인 해봐야겠습니다.
  • ISP : ISP가 아키텍처가 아닌 언어와 관련된 문제라고 결론 내릴 여지가 있음이란 부분을 새롭게 알게 됨
  • DIP : DI와 연관된 개념으로 다시 한번 체크한 개념이다.

은우

  1. 단일 책임 원칙 (SRP)
    퍼사드(Facade) 패턴?

  2. 개방-폐쇄 원칙 (OCP)
    개방-폐쇄 원칙 (기존 코드를 수정하기보다 반드시 새로운 코드를 추가하는 방식으로 시스템을 확장하는 원칙) 지키기가 가장 어려운 것 같다.
    기존 코드 수정할 일이 없도록 처음부터 기반을 잘 만드는 법은?
    유지보수까지, 확장 가능성까지 생각하며 시스템 설계가 필요함.
    시스템을 컴포넌트 단위로 분리하고, 저수준 컴포넌트에서 발생한 변경으로부터 고수준 컴포넌트를 보호할 수 있는 형태의 의존성 계층구조가 만들어지도록 해야 한다.

  3. 리스코프 치환 원칙 (LSP)
    인터페이스를 잘 설계하는 것이 중요하다.
    그에 맞춰 예외 처리에 힘쏟을 필요가 없는 구현체가 만들어지기 때문에
    ios 프로토콜과 자바의 인터페이스가 비슷한 개념

  4. 인터페이스 분리 원칙 (ISP)
    하나의 구현체는 한 가지의 인터페이스를 가져야 한다는 것을 깨달음.

  5. 의존성 역전 원칙 (DIP)
    변동성이 큰 구체에는 의존하면 안 된다는 사실. 변동성이 낮은 인터페이스에 의존해야 함.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.