아키텍쳐가 어쩌고 아키텍트가 어쩌고 MV뭐시기가 어쩌고 저쩌고... 잘난듯 떠들어대는 그들의 말을 하나라도 더 알아듣고 같이 잘난듯 떠들어제끼고 싶은 나의 마음을 담아 포스팅을 해본다.
일단 모르는영역이고 당연히 아는것도 없기에 이글에 나의 생각은 극히 적다.
그저 남들이 쓴 글을 내가 알아먹기 쉽게 정리할뿐..
(직접 따라쓰다보면 문장화 하다보면 머리속에서 정리가 되더라)
나도 얼른 이런거 많이 알아서 아는척 여기저기 잘난듯 말하고 다니고싶어 그분들의 가르침을 정리해본 글이다.
그리고 이왕이면 그들처럼 구조적으로 개발하고싶은 욕심과 함께.
아래의 영상내용을 기록한 글입니다. 링크는 맨 아래 혹은 여기
이런...이런 뭐랄까 알수없는 동물사진과 함께 굉장히 있어보이는 단어로 되어있는 표지..
바로 이거지.. 이걸 흠모해서 멀쩡한 직장 때려치우고 개발자의 길로 들어섰지..
아키텍쳐란 무엇인가...
소프트웨어 분야에서 이 단어가 무엇을 의미하는가...
구성요소들간의 관계, 환경, 설계와 발전을 관리하는 원칙으로 이루어진 시스템의 근본적인 구조
IEEE의 정의이다.
위 동영상의 마틴 파울러(Refactoring 저자)는 이 정의에 대해 너무 포괄적이다라고 말하였다.
소프트웨어 프로젝트를 잘 꾸려나가고 있을 때 중요한점은 프로젝트 내부 소스코드에 대해 잘 알고있는 프로젝트에 참여하고있는 개발자들이 있을건데 이 개발자들의 상식이 아키텍쳐에 영향을 미칠거란 점이다.
위의 문구는 중요한 사실인데 아키텍쳐라는것은 사회적 요소가 꽤나 영향이 크기 때문이다.
개발자들이 소프트웨어 프로젝트를 진행하고 프로젝트가 지속적으로 잘 커지고 있을 때는 보통 프로젝트를 주도하고 있는 팀원들간에 프로젝트에 대한 이해도가 잘 공유될 때 이다.
이게 중요한 사실이다. 하지만 상기 이미지의 아키텍쳐에 대한 정의는 너무 일반적이다.
하나 더 중요하게 살펴봐야할 사실이 있다.
아키텍쳐는 반드시 프로젝트가 시작되기 전에 잘 정의되어야 한다는 점이다.
보통 소프트웨어 프로젝트를 진행할 때 가장 걱정하는것중 하나는 한번 결정하면 변경하기가 매우 어렵다는 점 이다.
위의 두가지 지식을 공유하고 바꾸기 어렵다는 점 이 어려운 2개가 합쳐질 때
비로소 아키텍쳐에 대한 정의를 정할 수 있을것이다.
그렇다.. 아키텍쳐는 바로 뭐가되었든 일단 중요한것들이다...
이것은 아주 심오한 정의를 가지고 있다.
소프트웨어 설계자들은 소프트웨어 시스템이나 아키텍쳐를 설계할 때 무엇이 중요한지 핵심가치에 대해서 생각한다. 팀장님들은 팀장으로서 소프트웨어 프로젝트를 이끌어나갈 때 무엇을 핵심가치로 둘것인가 정할것이다. 혹은 혼자 프로젝트를 진행할 때 에도 무엇이 핵심인지 고민할것이다. 코드를 작성할 때 에도 무엇이 가장 중요한지 핵심을 생각하면서 소스코드에 녹인다.
즉, 아키텍쳐는 핵심가치를 위한 중요한 결정들이다.
이러한 핵심가치를 위한 결정들이 다른 어떤 문제보다도 중요하다.
그래서 아키텍쳐란 무언가 중요한 것이다.
아니 대체 왜... 왜 이렇게 알아야할 것이 많은거야..
근데 그게 좋다. 그게 너무 멋있다. 그래서 개발자가 되고 싶다.
소프트웨어 개발을 하다보면 이러한 말을 종종 듣는다고 영상의 마틴 파울러 아저씨는 말씀하셨다.
아 이건 뭐랄까... 동서고금 직종을 막론하고 공통적이구나 라는 생각을 한다..
이전 직장에서도 여러 아이디어를 준비해놓고 절대 한번에 오픈하지 않았다.
(이미 검증이 다 끝나있는 아이디어들 이다.)
빨리 적용하고 품질을 개선하는것이 고객관점에서 더 좋더라도 말이다.
반가운 말이다.
소프트웨어 직군에서 이 말은 설계 단계에서 모듈화에 대해 크게 걱정하지 않고,
품질이 낮더라도 수많은 기능 개선을 해왔다는 말이다.
사람들은 이런 과정에서 좌절감을 느끼게 되고 이 문제에 대해 이렇게 말한다.
'소프트웨어 전문가로서 훌륭하게 일을 해야만해! 우리는 우리의 전문적인 기준을 준수해야해!'
'우리는 전문가로서 일을 잘 해야해! 우리는 개발 장인이 되어야해!'
허나 파울러 아저씨의 견해는 불행히도 이러한 입장을 가지게되면 패배할것이라는 견해이다.
왜냐하면 위와같은 도덕적인 견해는 장인정신과 경제의 싸움이기 때문이다.
그리고 늘 이기는 건 경제적 관점이다.
만약 왜 아키텍쳐가 중요한지 잘 말하고 싶다면 즉, 장인정신이 이기도록 하고싶다면 경제라는 개념을 도입해야한다.
소프트웨어에서 장인정신과 경제 논쟁의 문제점은 품질이란 내가 비용을 지불할 수 있는 어떤 것이라는 생각이다.
우리는 어떤 것을 구매하는 모든 순간순간 이런 생각을 적용한다.
차를 사든, 옷을 사든 우리는 품질과 비용을 트레이드오프 한다.
하지만 소프트웨어에서 품질이란 전현 다른 것이다.
또한 중요한것은 평가하는 사람이 외부의 사람들이라는 것이다.
위의 이미지를 보면 소비자들 혹은 사용자들은 품질을 볼 수 없다.
잘 모듈화된 프로그램인지 좋은 아키텍쳐를 가지고 있는지 어쩐지 그들은 관심도 없고 볼 수도 느낄수도 없다.
그러니 파울러 아저씨는 소프트웨어는 2가지 형태의 품질을 가지고 있다고 한다.
그것은 바로 내부적인 것과 외부적인 것 이다.
소프트웨어 아키텍쳐는 내부의 품질과 관련되어 있다.
그리고 내부 품질은 직접적으로 보이지 않는다.
예를들어 만일 누군가가 완전 기능이 동일하지만 10만원 더 비싼 좋은 품질의 소프트웨어와 동일 기능에 품질이 낮은 소프트웨어 중 고르라고 한다면 굳이 비싼 소프트웨어를 골라야 할 이유가 있을까?
똑같은 기능을 가진 소프트웨어를 두고 10만원을 더 내야 한다면 아마도 보통 내부품질이 낮은 제품을 더 싼값에 선택할 것이다.
하지만 소프트웨어 내부 품질은 장기적 관점에서 중요한 것이다.
위의 그래프는 소프트웨어의 고도화에 대한 그래프이다.
아키텍쳐와 디자인에 신경을 쓰지 않은 소프트웨어에서는 시간이 지날수록 새로운 기능을 추가하기가 아주 어렵다.
왜냐하면 기능을 추가할수록 이미 존재하는 소스코드를 바꾸는데 시간이 오래걸리기 때문이다.
하지만 우리가 좋은 아키텍쳐를 가져가도록 지속적으로 관심을 기울이고 소스코드를 리팩토링 하면서 더 나은 방향으로 가져간다면 이런 노력들을 통해서 기능을 추가하는데 어려움을 겪지 않고 오히려 소프트웨어 고도화가 더 빨라질 수 있다.
이러한 소프트웨어는 아주 잘 컴포넌트화 되어있고, 소프트웨어 고도화 작업 시 해야할일은 어떻게 소프트웨어 기능을 변경할지 정하고 변경하는것이기 때문이다.
어디를 변경해야할 지 더 빨리 찾게되고 그러면서 가속도가 붙는다.
왜냐하면 이미 존재하는 소스코드가 플랫폼화가 되는 것이고 이 플랫폼위에서 더욱 빠르게 개발할 수 있기 때문이다.
이것이 아키텍쳐가 잘 설계되어야 하는 이유이다.
우리는 이렇듯 잘 설계된 아키텍쳐위에서 개발하기 원한다.
당연히 내부적으로 퀄리티가 떨어지는 제품을 10만원 더 싸게 사는것이 그 당시에는 좋은 선택일 수 있다.
하지만 더 나은 내부 품질을 가진 소프트웨어를 고른다면 새로운 기능이 더 빠르게 많이 추가할 수 있다.
내부 품질이 떨어지는 제품은 우리의 시간을 계속해서 잡아먹는다.
우리가 지속적으로 업데이트하기 위해 CI, CD를 도입하는 것과 관련이 있다.
지속적으로 기능을 추가하는 것은 그만큼 중요하기 때문이다.
결국 경제학적 관점에서 소프트웨어 아키텍쳐가 중요하다는것이다.
우리가 좋은 아키텍쳐를 가져가지 못한다면, 우리가 좋은 퀄리티의 소스코드를 가지기 위해 노력하지 않는다면 우리는 고객을 속이는 것이고 경쟁 제품에 비해 나쁘게 만듦으로서 장기적 관점에서 기능이 고도화되지 못하고 이는 고객을 뺏기게 되는것이다.
위의 그래프에서 잘 설계된 소프트웨어는 짧은 기간에도 많은 기능들이 추가된다.
이것이 바로 아키텍쳐의 정의이고 아키텍쳐가 중요한 이유이다.
마스터 teo 의 말씀에 의하면 특정한 규칙들을 하나씩 만들어서 개발하다보면 이것이 반복되어 하나의 특정 패턴이 만들어지고, 이러한 패턴들을 모두가 이해하고 따를 수 있도록 하는 구조를 아키텍쳐라고 정의했다.
아키텍쳐란 좋은 구조를 만드는것이고, 좋은 구조의 첫번쨰 조건은 좋은 분류다.
그리고 이 MVC 아키텍쳐는 코드를 Model, View, Controller 이렇게 3가지 역할로 분류한다.
웹 프론트엔드에서의 View는 HTML과 CSS로 만들어지는 결과물을 의미한다.
화면에 실제 반영되는 데이터를 주관하는 영역을 Model이라고 부른다.
이 Model의 범주는 아키텍쳐에 따라 달라진다.
Javascript의 Object일 수도 있고,
서버의 API로 받는 데이터일수도 있고,
서버에있는 DB일 수도 있다.
결국 화면이 아닌 소프트웨어가 다뤄야할 중요한 데이터 영역이다.
UI 소프트웨어의 본질은 단순하다.
우선 데이터를 화면에 그린다. 그리고 유저가 어떤 동작을 취하면 데이터가 바뀐다. 그리고 데이터가 바뀌면 다시 화면이 바뀐다.
Model의 데이터를 받아 화면에 그리고, 화면으로 부터 사용자의 동작을 받아서 Model을 변경한다.
이러한 Model과 View 사이의 중간 역할을 하는 것을 Controller라고 한다.
웹 프론트엔드라는 개념이 없던 초창기 시절의 MVC는
- DB를 Model
- HTML, CSS, Javascript를 View
- 가운데거 라우터를 통해 데이터를 처리하고 새로운 HTML을 만들어서 보여주는 백엔드를 Controller
라고 취급했다.
그러다가 프론트엔드의 역할이 추가되고 ajax라는 기술이 만들어지면서 이제는 HTML을 서버에서 직접 만들 필요가 없어졌다.
이때부터 프론트엔드의 MVC 개념이 바뀌게된다.
- ajax로 부터 받는 데이터와 그 데이터를 통해 변경될 수 있는 상태를 Model
- HTMl과 CSS로 만들어지는 화면을 View
- javascript가 중간에 서버의 데이터를 받아 화면을 바꾸고 이벤트를 처리해서 서버에 데이터를 전달하는 Controller
브라우저에서 버튼을 클릭했을 때 일어나는 일을 예시로 들어보자.
이 버튼에는 하나의 기능을 수행하는 이벤트가 바인딩 되어 있다.(하나의 기능을 수행하게 하는것이 잘 구현된 버튼이다)
사용자는 View의 버튼을 통해 이벤트를 호출한다 -> View에서 호출된 이벤트로 Controller가 서버에 데이터를 요청하던지 직접 변경하던지해서 Model을 변경한다 -> Model이 변경되면 View에 변경된 Model을 반영한다.
이 떄 Model은 직접 View를 변경할 수 없고, Controller를 통해 변경해야 한다.
그래서 프론트엔드의 MVC는
View -> Controller -> Model -> Controller -> View 형태이다.
// Model
let state = 0;
const $button = document.querySelector('button');
// View
const render = () => {
document.body.innerHTML = state;
};
// Controller
const setState = newState => {
state = newState;
render();
};
$button.addEventListener('click', () => {
setState(state + 1);
});
MVC 이후에 react, vue, angular등의 라이브러리와 프레임워크를 사용하며 Controller도 직접 조작할 필요 없이, 화면에 보여주는 ViewModel만 변경해주면 된다는 개념에서 등장한것이 MVVM 이다.
jQueary로 작업하다보니 상당히 불편한 점을 발견하였다.
데이터를 찾아서 데이터를 바꾸고 데이터를 수정하고 이벤트를 연결하고 이벤트를 수정하는 부분들에서 피곤한 반복적인 패턴이 나타나게 된다는것을 알게 된 것이다.
(일일히 addEventListner 달아주고 이런거 말하는듯)
하여 선언적 방식으로 개발을 하고자 하였다.
NOTE: 선언적 프로그래밍은 간단히 설명하면 코드로 로직을 만들지 않고 약속된 선언을 바탕으로 해서 자동으로 필요한 코딩을 하는 거라고 생각하시면 되겠습니다.
ex) html과 css, jsx와 같은 템플릿 들이 다 같은 그런 개념이죠.
이러한 개념을 바탕으로 템플릿 바인딩 기반의 라이브러리들이 만들어진다.
(angular, vue, react)
Model이 변하면 View를 수정하고 View에서 이벤트를 받아서 Model을 변경한다는 Controller의 역할은 그대로 인데 이를 구현하는 방식이 jQuery와 같은 DOM 조작에서 템플릿과 바인딩을 통한 선언적 방식으로 변하게 된다.
즉, 코드에서 DOM을 조작하는 코드가 사라지고 이 기능들을 프레임워크가 담당하게 된다.
이제 개발자는 화면에 그려져야할 데이터만 만들어서 프레임워크에 전달해주면 프레임워크가 알아서 그려준다.
이를 View를 그리는 Model만 다루게 되었다는 의미로 ViewModel이라고 부르며 이 방식을 MVVM이라고 부른다.
MVC에서 MVVM으로 오며 달라진 부분
- 컨트롤러의 반복적인 기능이 선언적 방식으로 개선
- Model과 View의 관점을 분리하려 하지 않고 하나의 템플릿으로 관리하려는 방식으로 발전(기존에는 class나 id등으로 간접적으로 HTML에 접근하려 했다면 이제는 직접적으로 HTML에 접근하는 방법으로 확장)
웹 서비스가 발전하며 이제는 하나의 Page가 아니라 Page안에 여러 모듈이 있고 Modal이나 여러 화면들이 하나의 화면에서 구성이 될 수 있도록 발전하게 되었다.
그래서 MVVM이 화면단위가 아니라 조금 더 작게 재사용 할 수 있는 단위로 만들어서 조립하는 방식으로 발전하였다.
이것이 Component 패턴임
컴포넌트는 재사용이 가능해야 한다는 원칙에 따라 가급적 비즈니스 로직을 포함시키지 않으려고 개발했다.
비즈니스 로직이 들어가면 컴포넌트의 재활용성은 상당히 떨어진다.
그래서 비즈니스 로직을 관장하고 있는 컴포넌트를 Container 컴포넌트라 그러고 혹은 이제 비지니스 로직을 가지고 있지 않은 데이터만 뿌려주는 형태의 컴포넌트를 Presenter 컴포넌트로 분리하여 최상단 혹은 1depth에 Container를 두고 비지니스 로직을 관리하는 Container-Presenter 아키텍쳐가 만들어집니다.
teo.log : 프론트엔드에서 MV* 아키텍쳐란 무엇인가요?
마틴 파울러 : 소프트웨어 아키텍처의 중요성 (한글 자막)
개발 성장 일지 : 프론트엔드의 MVC
도움되는 포스팅 감사합니다 :)