Skip to content

Latest commit

 

History

History
276 lines (203 loc) · 5.94 KB

File metadata and controls

276 lines (203 loc) · 5.94 KB

MVC

코드를 구성하기 위해 특정 패턴을 따른다. 코드와 코드가 수행하는 기능을 논리적으로 분리하는 방법이다.

Model

  • 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야 한다.
  • 뷰나 컨트롤러에 대해서 어떤 정보도 알지 말아야 한다.
  • 변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야만 한다.

view

  • 모델이 가지고 있는 정보를 따로 저장해서는 안된다.
  • 모델이나 컨트롤러와 같이 다른 구성요소들을 몰라야 된다.
  • 변경이 일어나면 변경통지에 대한 처리방법을 구현해야만 한다.

controller

  • 모델이나 뷰에 대해서 알고 있어야 한다.

  • 모델이나 뷰의 변경을 모니터링 해야 한다.

  • 온라인 샵을 가정하고 이번 챕터를 진행해보자!

기존 프로젝트를 MVC 패턴으로 리펙토링 하기

controller

  • routes/shop.js

    router.get('/', (req, res, next) => {
    // 데이터와 통신 : model
      const products = adminData.products;
    // veiw 보내줌 : controller
        res.render('shop', {
        prods: products,
        pageTitle: 'Shop',
        path: '/',
        hasProducts: products.length > 0,
        activeShop: true,
        productCss: true
      });
    });
  • 모든 로직을 controllers 폴더로 분리하기

    exports.getAddProduct = (req, res, next) => {
      res.render('add-product', {
        pageTitle: 'Add Product',
        path: '/admin/add-product',
        productCSS: true,
        formCSS: true,
        activeAddProduct: true
      });
    };

    결과

    • controllers/products.js

      const products = [];
      
      exports.getAddProduct = (req, res, next) => {
        res.render('add-product', {
          pageTitle: 'Add Product',
          path: '/admin/add-product',
          productCSS: true,
          formCSS: true,
          activeAddProduct: true
        });
      };
      
      exports.postAddProdcut = (req, res, next) => {
        products.push({ title: req.body.title });
        res.redirect('/');
        console.log('2222', products);
      };
      
      exports.getProducts = (req, res, next) => {
        res.render('shop', {
          prods: products,
          pageTitle: 'Shop',
          path: '/',
          hasProducts: products.length > 0,
          activeShop: true,
          productCss: true
        });
      };
    • routes/shop.js

      const products = [];
      
      exports.getAddProduct = (req, res, next) => {
        res.render('add-product', {
          pageTitle: 'Add Product',
          path: '/admin/add-product',
          productCSS: true,
          formCSS: true,
          activeAddProduct: true
        });
      };
      
      exports.postAddProdcut = (req, res, next) => {
        products.push({ title: req.body.title });
        res.redirect('/');
        console.log('2222', products);
      };
      
      exports.getProducts = (req, res, next) => {
        res.render('shop', {
          prods: products,
          pageTitle: 'Shop',
          path: '/',
          hasProducts: products.length > 0,
          activeShop: true,
          productCss: true
        });
      };
    • /routes/admin.js

      const express = require('express');
      const path = require('path');
      const proudctsController = require('../controllers/products');
      
      const router = express.Router();
      
      router.get('/add-product', proudctsController.getAddProduct);
      
      router.post('/add-product', proudctsController.postAddProdcut);
      
      module.exports = router;

    model

    • models/product.js 생성

      기본의 입력받은 데이터 처리하는 js 파일 생성

      const products = [];
      
      module.exports = class Product {
        constructor(t) {
          this.title = t;
        }
      
        save() {
          products.push(this);
        }
      
        static fetchAll() {
          return products;
        }
      };
    • controllers/product.js 수정

      const Product = require('../models/product');
      
      exports.getAddProduct = (req, res, next) => {
        res.render('add-product', {
          pageTitle: 'Add Product',
          path: '/admin/add-product',
          productCSS: true,
          formCSS: true,
          activeAddProduct: true
        });
      };
      
      exports.postAddProdcut = (req, res, next) => {
        const product = new Product(req.body.title);
        product.save();
        res.redirect('/');
      };
      
      exports.getProducts = (req, res, next) => {
        const products = Product.fetchAll();
        res.render('shop', {
          prods: products,
          pageTitle: 'Shop',
          path: '/',
          hasProducts: products.length > 0,
          activeShop: true,
          productCss: true
        });
      };

    리펙토링

    • models/product.js

      const fs = require('fs');
      const path = require('path');
      
      const p = path.join(
        path.dirname(process.mainModule.filename),
        'data',
        'products.json'
      );
      
      const getProductsFromFile = cb => {
        fs.readFile(p, (err, fileContent) => {
          if (err) {
            return cb([]);
          } else {
            cb(JSON.parse(fileContent));
          }
        });
      };
      
      module.exports = class Product {
        constructor(t) {
          this.title = t;
        }
      
        save() {
          getProductsFromFile(products => {
            products.push(this);
            fs.writeFile(p, JSON.stringify(products), err => {
              console.log(err);
            });
          });
        }
      
        static fetchAll(cb) {
          getProductsFromFile(cb);
        }
      };

요약

Model

  • 데이터를 표현하고 관리하고 저장하고 업데이트함.
  • 어디에 저장하든 괜찮다. (메모리, 저장공간, 데이터베이스)

View

  • 유저가 보는 프론트
  • 많은 로직을 담는것 보다 간단히 해야한다.

Controller

  • 모델과 뷰를 연결
  • 라우터 역할