몇만 줄의 코드, 어떤 부분의 로직을 바꿔야 할 때, 에러 원인을 찾을 때, 절차지향형으로 막 작성한다면 너무 어려울 것이다. 이러한 문제점을 해결하기 위해 어떤 경우에는 어떤 식으로 코드를 작성하자, 이런 경우에는 이런 형식으로 코드를 작성하자고 정한 규약 또는 약속을 디자인패턴이라고 한다.
디자인 패턴 또는 아키텍처가 필요한 이유?
이것은 일상생활의 모든 메커니즘과 닮아 있다고 생각한다. 패턴과 아키텍처는 창의력과 거리가 멀다고 생각하는데, 만약 집을 정리하거나 컴퓨터 파일들을 정리하고 휴대폰 화면을 구성할 때 창의적으로 배치를 한다면 나중에 내가 다시 찾기에도 어렵고 타인이 사용하기엔 더욱 어렵다.
개발을 혼자 하고 나중에 코드를 들여다 볼 일이 없다면 마구 창의적으로 작성해도 문제 없을 것이다. 그러나 서비스로 개발하고 지속적으로 관리하고 다른 개발자와 공유하고 협업하려면 알아보기 쉽고 정돈이 되어 있어야 한다. 규칙이 있다면 이해하기도 쉽고 찾기도 쉬울 것이다. 관심사를 분리하고 모듈화하고 폴더링을 하여 계층을 나누는 등을 통해 일의 효율과 범용성을 높일 수 있다.
예를 들어, redux 라이브러리의 action, dispatch, store는 facebook이 개발한 flux 패턴(action -> dispatch -> store -> view)이 기반이 된, 반영된 산물이다.
크게 생성패턴, 구조패턴, 행동패턴 3가지로 나뉜다.
객체 생성 방법이 들어간 디자인패턴
객체, 클래스 등 큰 구조를 만들 때 유연하고 효율적으로 만드는 방법
객체나 클래스 간 알고리즘, 책임 할당에 관한 디자인패턴
하나의 클래스에 오직 하나의 인스턴스만을 가지는 패턴. 클래스는 여러 개의 인스턴스를 가질 수 있지만 그렇게 하지 않고 하나만 만들어 이를 기반으로 로직을 만든다. 보통 데이터베이스 연결모듈에 많이 사용된다.
여러 개의 인스턴스 생성에 드는 비용을 줄일 수 있다.
의존성이 높아진다
TDD 시 단위테스트는 테스트가 서로 독립적이어야 하고 테스트를 어떤 순서로든 실행할 수 있어야 하는데, 미리 생성된 인스턴스를 기반으로 구현하는 패턴이므로 마치 전역변수처럼 영향을 받아 서로 의존적이고 코드 실행 순서의 영향을 받는다. (이런 이유로 안티패턴이라고 하는 사람들도 있다)
앱의 데이터인 데이터베이스, 상수, 변수 등을 뜻한다. 뷰에서 데이터를 생성하거나 수정할 때 컨트롤러를 통해 모델이 생성 또는 업데이트된다.
예를 들어 사용자가 네모박스에 글자를 적을 때, 모델은 네모박스의 크기 정보, 글자 내용, 글자의 위치, 글자의 포맷 정보 등이다.
inputbox, checkbox, textarea 등 사용자 인터페이스 요소를 나타낸다. 모델을 기반으로 사용자가 볼 수 있는 화면을 뜻한다. 모델이 가지고 있는 정보를 따로 저장하지 않아야 하고 변경이 일어나면 컨트롤러에 이를 전달해야 한다.
하나 의상의 모델과 하나 이상의 뷰를 잇는 다리 역할을 한다. 이벤트 등 메인 로직을 담당한다. 모델과 뷰의 생명주기를 관리하거나, 모델 및 뷰의 변경 통지를 받으면 이를 해석하여 각각의 구성 요소에 해당 내용에 대해 알려준다.
앱이 복잡해질수록 모델과 뷰의 관계가 복잡해진다.
C가 Presenter로 교체된 패턴. 뷰와 프레젠터가 1:1 관계라서 MVC 패턴보다 더 강한 결합을 지닌 디자인 패턴이다.
C가 VM로 바뀐 패턴.
facebook이 만든 단방향으로 데이터 흐름을 관리하는 디자인 패턴이다.
action -> dispatch -> store -> view 순서가 정해져 있어서 일관성이 높아지고 테스트, 디버그가 쉽다.
과거에 화면, API, 회원 등이 하나의 단일 시스템이었다. 모노릭스.
MSA의 철학은 API같은 함수를 사용하여 서로 간에 통신을 한다.
Netflix에서 큰 장애가 일어나서 전체 서비스가 다운된다면?
한군데가 다운이 되어도 나머지 부분은 이상이 없도록하여 전체 장애를 막자
회원이 가파르게 늘어나고 있고 서비스도 추가하고 인프라를 늘리고 있다.
서비스 몇가지 기능들 중에 조회 기능이 전체 서비스의 API 호출 중에 90% 이상을 차지하고 있고 급격하게 늘어나고 있다. 그렇다면 조회 기능만을 탑재한 인프라만 늘리면 효율적으로 인프라를 관리할 수 있다.
결제, 정산, 회원 등의 기능에는 변동이 없고 조회 기능만 일주일에 한 번씩 업데이트가 되고 발전하고 있다. 전체 코드를 빌드할 필요 없이 해당되는 부분만 빈번하게 업데이트할 수 있다.
(i.e. 어떤 팀이 배포를 빈번하게 하는데 다른 팀까지 모두 날 새야하는 문제가 있을 때)
복잡도가 증가한다.
ROI(Return Of Investment)를 따져봐야 한다. 레거시 코드를 바꿀 경우 어플리케이션에서 인프라까지 모두 바꾸어야 하고, 관리하는 요소가 더욱 늘어나며 구조가 더욱 복잡해지기 때문에 오히려 장애를 일으킬 수도 있다.