티스토리 뷰
MVC 패턴이란 무엇인가?
- Model-View-Controller의 약자로, 개발시 3가지의 형태로 나누어 개발하는 패턴을 말한다.
- 어플리케이션 개발 시 사용자 인터페이스 영역과 비즈니스 로직 처리 영역을 분리시킨다.
Model
- 어플리케이션이 무엇을 할지 정의한다.
- 어플리케이션의 정보, 데이터를 나타낸다. ( 데이터베이스, 변수 , 초기화값 )
- 위와같은 정보들의 가공을 책임지는 컴포넌트이다.
- 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야 한다.
- 뷰, 컨트롤러에 대해 어떠한 정보더 알아선 안된다.
- 정보 변경시, 변경 통지에 대한 처리 방법을 구현해야 한다. 모델 속성의 변경시 외부에 알려야하고, 외부에서 모델 속성의 변경을 요구시 이를 처리해야한다.
View
- input 텍스트, 체크박스와 같은 사용자 인터페이스 항목을 나타낸다.
- 즉 데이터의 입출력 담당하여 해당 데이터 기반으로 사용자들에게 화면을 보여준다.
- 뷰는 모델이 가지고 있는 정보를 따로 저장해선 안된다. 즉, 모델로부터 받은 데이터를 뷰 내부에 저장해선 안된다.
- 모델, 컨트롤러와 같이 다른 구성요소들을 몰라야 한다.
- 화면에서 사용자가 화면에 표시 된 내용을 변경시, 이를 모델에게 전달해서 모델을 변경해야한다. 이를 위해서 변경 처리를 구현해야한다.
Controller
- 데이터 (model)과 사용자 인터페이스 (view) 요소를 연결하는 중간다리 역할을 한다.
- 즉, 사용자가 데이터를 클릭 , 수정하는 것에 대한 '이벤트' 처리 부분
- 컨트롤러는 모델, 뷰에대해 알고 있어야 한다.
- 모델, 뷰의 변경을 모니터링 해야한다. 즉, 모델, 뷰로부터 변경 통지를 받으면 이를 해석해 각각의 구성요소에 통지해야 한다.
- 어플리케이션의 메인 로직을 담당한다.
-
클라이언트로 부터 리퀘스트를 받고, form에서 input을 받은 데이터를 화면에 출력하는 웹 어플리케이션을 MVC패턴을 통해 구현해보기 - view는 이전에 구현해놓았던 ejs 파일들을 사용하면 되고, model과 controller를 구현해준다. model에서는, 기존에 route 파일에 array로 저장해놓았던 데이터를 class를 통해 생성, 저장 및 불러내고, controller는 route js파일 내 render함수를 따로 구현해주도록 한다.
1. Model: 기존의 array에 저장하던 데이터를 클래스를 통해 생성, 저장 및 내보내고, 해당 class를 exports해준다.
여기서 fetchAll() 메서드가 static 인 이유는, 해당 인스턴스에 대한 데이터만 전송하는게 아니라, class 전체에 대한 데이터를 전송해야하기 때문이다.
const products= [];
module.exports= class Product{
constructor(title){ // 인자로 title받아오면 저장,
this.title=title;
}
save(){
products.push(this); //products array에 저장
}
static fetchAll(){ //해당 array 반환
return products;
}
}
2. Controller: js파일에서 route를 처리하는 render 함수를 넣어준다.
- 기존 route 처리 js 파일
const express = require('express');
const router = express.Router();
const path = require('path');
const products = [];
router.get('/add-product',(req,res,next)=>{
res.render('admin',{
pageTitle:'Add Product :)',
path:'/admin/add-product'
});
});
router.post('/add-product',(req,res,next)=>{
products.push({title:req.body.title});
res.redirect('/');
})
exports.routes=router;
exports.products=products;
const express = require('express');
const router = express.Router();
const path = require('path');
const adminData = require('./admin');
router.get('/',(req,res,next)=>{
const products = adminData.products;
res.render('shop', {
prods:products, //product 정보
pageTitle:"Shop",
path:"/",
});
});
module.exports=router;
- / Controllers / product.js 파일에서 route.render함수 구현 - 해당 함수 exports
exports.getAddProduct=(req,res,next)=>{ // get방식 /admin/add-product
res.render('admin', {
pageTitle:'Add Product',
path:'/admin/add-prdouct'
});
};
exports.postAddProduct=(req,res,next)=>{ // post방식 /admin/add-product
const product = new Product(req.body.title); //인스턴스 생성, req.body.title(책이름) 생성자
product.save(); // products array에 push
res.redirect('/'); // 기본페이지로 리다이렉트
};
exports.getProducts=(req,res,next)=>{ // get방식 '/'
const products = Product.fetchAll(); //products array 가져오기
res.render('shop',{
pageTitle:'shop',
prods:products,
path:'/'
});
};
- 기존의 route js 파일에서는 , 해당 함수를 import 해서 get 혹은 post의 인자로 넘겨준다.
const express = require('express');
const route = express.Router();
const productsController = require('../controllers/products');
route.get('/add-product',productsController.getAddProduct);
route.post('/add-product',productsController.postAddProduct);
module.exports=route;
const express= require('express');
const route = express.Router();
const productsController = require('../controllers/products');
route.get('/',productsController.getProducts);
module.exports=route;
참조
'web : back-end > node js' 카테고리의 다른 글
[node js] Express: 동적 페이지 처리하기 (0) | 2020.06.23 |
---|---|
[node js] Express: Model 에서 file형태로 데이터 저장 및 읽어오기 (0) | 2020.06.21 |
[node js] Express: EJS 템플릿 엔진 (0) | 2020.06.20 |
[node js] Express: Handlebars 템플릿 엔진 (0) | 2020.06.19 |
[node js] Express: Pug 템플릿 엔진 (0) | 2020.06.18 |
댓글