Search
▪️

The Model View Controller (MVC)

What is the MVC?

MVC는 Separation of Concern를 위해 고안된 디자인 패턴이다.
Models는 기본적으로 프로젝트에서 쓰이는 데이터들을 표현하는 Object를 말한다. 즉, 데이터들을 활용 (불러오거나 저장하는 등)하는데 쓰이는 것들을 말한다.
Views는 이전에 작성했던 HTML 파일들이나, Template 파일들을 의미한다. 이런 파일들은 우리가 실제로 볼 수 있는 것들을 말한다. 사용자가 원하는 적절한 Content들을 보여주는 역할을 담당한다. 가공된 데이터들이 Template Engine에 주입되어 Template Engine이 View를 Render하도록 한다.
Controllers는 위에서 언급한 Models와 Views를 연결 포인트라고 할 수 있다. 일반적으로 Views는 Application에서 쓰이는 로직들을 신경 쓰지 않고 보여주는 역할만 수행하고, Models는 오로지 데이터들을 어떻게 불러오고 어떻게 저장할지만 신경쓰기 때문에 Controllers는 불러온 데이터들을 특정 Logic으로 처리하여 Views에 보내는 역할을 한다.
즉, Controller는 일종의 Middleman 역할을 수행한다. 그렇다면 Routes들은 무엇일까? → Routes들은 특정 Path에 따라서 실행되는 HTTP Method에 따라 어떤 Controller의 Code를 수행해야 하는지 정해준다.
또한, Express가 Middleware를 사용한다는 특징 덕에 Controller 역시 여러 Middleware의 Function들로 나뉘어 구현된다. (특정 Logic에 따라서 구분 짓는다.)

Defining a Model

Model을 정의할 때, ES5에서는 function 키워드를 이용하여 function Object() {} 와 같이 정의하고, ES6에서는 class Object {}와 같이 정의할 수 있다.
ES6 기준으로 하여, Class 선언 시 생성자를 작성해야 하는데 이는 constrctor function을 통해서 작성할 수 있다. constructor() {}로 이용한다.

Storing Data in Files Via the Model

Path Module과 File System Module을 이용한다.
Path Module을 이용하여 디렉토리와 파일 명을 지정하고 File System Module을 통해서 파일에 접근한다.
File System Module의 readFile()을 통해서 파일을 읽을 수 있지만, 매우 매우 큰 파일에 대해서는 readFile() 보다 더 효율적인 방법이 있다. 파일로 작업하기 전에 파일을 다 읽을 때까지 기다리는 방법이 아닌, Stream을 이용하는 방식이 이에 해당 된다. 이 때는 createReadStream()을 이용한다. 이 때 readFile()의 첫 번째 인자는 Path, 두 번째 인자는 Error와 Buffer를 인자로 갖는 Callback Function이다.
File System Module의 writeFile()을 통해서 파일을 쓸 수 있다. writeFile()의 첫 번째 인자는 Path, 두 번째 인자는 Write할 Content(JSON 파일로 저장 시 JSON으로 먼저 만들어주는 과정이 필요하다.), 세 번째 인자는 Error을 인자로 갖는 Callback Function이다.
JSON 파일의 경우, JSON.parse() Method를 이용하여 Decoding, JSON.stringify() Method를 이용하여 Encoding 할 수 있다.
파일로 읽고 쓸 때, JSON Array로 잘 데이터를 처리를 한 것 같음에도 Length를 활용 했을 때 오류가 생긴다면 그 이유는 무엇인가? → Node.js 특성 상 Blocking Code는 지양해야 한다. 그러하기 때문에 readFileSync()나 writeFileSync()는 이용을 지양했다. 즉, readFile()과 writeFile()은 비동기 코드이다. 두 Method를 정의하면서 등록한 Callback Function들은 Event Emitter에 붙어서 Event가 발생할 때 호출 되도록 설계된 Method들이다. 따라서 Event가 발생하면서 Event Emitter에 붙어서 Callback Function이 해당 Event를 처리하는 동안 이 함수를 호출 하고 있는 Method는 이미 return을 해버려서 Length 자체를 이용을 못 하는 것이다. 코드에는 이상이 없지만 Length를 이용하려고 하면 'undefined'가 출력되는 이유가 이런 것이다.
해당 문제에 대해서 고치는 방법은 여럿 있겠지만, readFile()과 writeFile() 이용하는 Method에 추가 인자를 받는 방법으로 해결할 수 있다. 추가 인자는 Callback Function이다. 예를 들어서, cb라는 Callback Function을 받았다고 치자. 원래 Method에는 [] 와 같은 일반 배열이 return 되는 것 일텐데, 이를 cb([])로 처리한다. 그렇다면 readFile()과 writeFile()을 갖는 이 함수를 호출 할 때, 인자로 넣는 cb는 어떤 Callback Function 인가? → 특정 배열을 이용하려는 Logic들을 Anonymous Function으로 처리하여 Callback Function 내로 Logic을 옮겨서 처리한다.