ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [포스코x코딩온] MVC패턴(데이터베이스X)
    [포스코x코딩온] 웹개발자 풀스택 부트캠프8기 2023. 8. 5. 23:38
    728x90

    MVC(모델-뷰-컨트롤러)(Model View Controller)

    MVC구조는 소프트웨어 아키텍처(애플리케이션 개발 모델) 유형 중 하나로 전체 애플리케이션을 모델, 뷰, 컨트롤러로 구분하여 사용자 인터페이스와 비즈니스 로직을 상호 분리하여 개발하는 구조이다.

     

    • 모델
      • 자신의 상태가 바뀔 때마다 컨트롤러와 뷰에게 알려준다. 모델의 상태 변화 통보에 따라 뷰는 최신 결과를 보여주며 컨트롤러는 적절한 명령을 추가하거나 변경한다.
      • 데이터를 처리하는 부분
      • 모델로부터 정보를 얻어와서 사용자에게 출력물을 보여준다.
      • UI 관련된 것을 처리하는 부분
    • 컨트롤러
      • 모델과 뷰에게 명령을 보낼 수 있다. 모델에 명령을 보내면 모델의 상태가 바뀐다. 뷰에 명령을 보내면 모델에 의한 뷰 표시 방법을 변경할 수 있다.
      • View와 Model을 연결해주는 부분

    MVC 흐름

    MVC 구조는 GUI를 사용하는 애플리케이션 개발 모델에서 많이 사용하며, 사용자 인터페이스와 비즈니스 논리를 상호 독립적으로 구성요소를 변경할 수 있는 장점을 제공한다.

    • MVC 이용 웹 프레임워크
      • ASP.NET (CLI) : MS가 개발한 동적인 웹 사이트, 웹 애플리케이션, 웹 서비스 개발을 지원하는 웹 애플리케이션 프레임워크
      • Codelgniter(PHP): 간편한 인터페이스와 논리적인 구조로 서버 지원을 최소화한 프레임워크
      • Laravel(PHP) : 오픈소스 웹 프레임워크이며 MVC 아키텍처와 모듈 방식의 패키징 시스템으로 가장 대중적인 PHP 프레임워크
      • Spring(Java) : 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로 공공기관의 웹 서비스 개발 시 사용을 권장하는 전자정부 표준 프레임워크
      • struts(Java) : 자바 기반의 JSP만을 위한 오픈소스 프레임워크
      • Vue.js(JS) : 반응형 및 구성 가능한 뷰 구성요소를 제공하여 단순한 사용자 인터페이스를 구축하는 데 사용되는 프레임워크
      • React.js(JS) : 페이스북에서 개발하는 대화형 사용자 인터페이스를 구축하는 선언적이고 동적이며 유연한 프레임워크
      • Angualr.js(JS) : 데이터 중심적, 테스트 주도적, 선언적 HTML의 특징을 가지고 사용자 환경에서 쉽고 빠르게 HTML 어휘를 확장 가능한 프레임워크
      • Django(Python) : 고도의 데이터베이스 기반 웹 사이트를 작성하는 데 용이하며 강력한 라이브러리를 제공하지만 모바일 환경 구현이 어려운 프레임워크
      • Ruby on Rails(Ruby) : 데이터베이스를 이용한 웹 애플리케이션을 개발할 때 반복되는 코드를 대폭 줄여 개발 시간이 단축 가능한 오픈소스 프레임워크
    • 장점
      • 패턴들을 구분해 개발
      • 유지보수가 용이
      • 유연성이 높다
      • 확장성이 높다
      • 협업에 용이
    • 단점
      • 완벽한 의존성 분리가 어렵다
      • 설계 단계가 복잡
      • 설계 시간이 오래 걸린다
      • 클래스(단위)가 많아진다

    百聞不如一見. 직접 만들어 보자.

     

    mvc폴더에 프로젝트 생성

    mkdir mvc #폴더 생성
    cd mvc #폴더 이동
    
    npm init -y #프로젝트 시작 명령어(-y 옵션: package.json 기본 값으로 생성)
    #package.json에서 "main" 값을 index.js에서 app.js로 변경(진입점 파일명)
    
    #app.js 파일 생성
    #views/index.ejs 파일 생성
    #.gitignore 파일 생성
    
    npm install express ejs #express와 ejs 패키지 설치

    MVC 패턴을 적용한 폴더 구조

    • controller : view 와 model 연결하는 부분
    • model : 데이터 처리하는 부분
    • routes : 경로 설정하는 부분
    • views : UI 관련 처리

    파일별 코드 모아 보기

    • app.js
    const indexRouter = require("./routes"); //index는 생략 가능
    app.use("/", indexRouter); //localhost:PORT/경로를 기본으로 ./routes/index.js 파일에 선언한 대로 동작
    • Router을 불러오는 부분으로 특정 시작 url의 역할을 구분할 수 있다.
    더보기
    app.get("*", (req, res) => {
      res.render("404");
    });
    • 404 Error 라우팅으로 맨 마지막 라우트로 선언해야 한다.(JS는 위에서 부터 읽어오기 때문이다.)
    • * : 그 외 나머지 주소는 모두(all) 잘못된 요청임을 사용자에게 알린다.
    • 클라이언트가 올바르지 않은 주소로 요청 시 Error 페이지 렌더링
      • 이 부분을 제외하면 나머지는 기본 세팅이나 마찬가지이다.
    const express = require("express");
    const app = express();
    const PORT = 8000;
    
    app.set("view engine", "ejs");
    app.set("views", "./views");
    app.set("/static", express.static(__dirname + "/static"));
    
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json());
    
    const indexRouter = require("./routes"); //index는 생략 가능
    app.use("/", indexRouter); //localhost:PORT/경로를 기본으로 ./routes/index.js 파일에 선언한 대로 동작
    
    //404=> 맨 마지막 라우트로 선언해야 함.
    app.get("*", (req, res) => {
      res.render("404");
    }); // *:그 외 나머지 주소는 모두(all) 잘못된 요청임을 사용자에게 알림.
    
    app.listen(PORT, () => {
      console.log(`http://localhost:${PORT}`);
    });
    • routes/index.js
      • 경로를 controller와 연결하여 설정이 가능하다.
    const express = require("express");
    const controller = require("../controller/Cmain.js");
    const router = express.Router();
    
    router.get("/", controller.main); //GET /
    router.get("/comments", controller.comments); // GET /comments
    router.get("/comment/:id", controller.comment); //GET/comment/:id
    
    module.exports = router;
    
    //경로를 controller와 연결해 설정 가능
    • model/Comment.ks
      • 아직 데이터베이스와 연결을 하지 않았으므로 직접 코드에 넣어준다.
      • 댓글 목록은 배열로 가져오고 각 댓글은 객체로 저장된다.
    //데이터 베이스 선택하는 부분
    exports.commentInfos = () => {
      return [
        {
          id: 1,
          userid: "hellowrold",
          data: "2023-08-05",
          comment: "안녕하세요~~",
        },
        {
          id: 2,
          userid: "happy",
          data: "2023-07-05",
          comment: "반갑습니다.~~",
        },
        {
          id: 3,
          userid: "lucky",
          data: "2022-01-21",
          comment: "운이 좋군요~~",
        },
        {
          id: 4,
          userid: "bestpart",
          data: "2023-02-05",
          comment: "처음입니다~~",
        },
      ];
    };
    • controller/Cmain.js
    더보기
    const Comment = require("../model/Comment");.
    더보기
    exports.comments = (req, res) => {
      console.log(Comment.commentInfos());
      res.render("comments", { commentInfos: Comment.commentInfos() });
    };
    • 위의 두 부분을 통해 컨트롤러와 모델을 연결한다.
    const Comment = require("../model/Comment");
    
    exports.main = (req, res) => {
      res.render("index");
    };
    
    //댓글 목록
    exports.comments = (req, res) => {
      console.log(Comment.commentInfos());
      res.render("comments", { commentInfos: Comment.commentInfos() });
    };
    
    exports.comment = (req, res) => {
      console.log(req.params.id);
    
      const commentId = req.params.id;
      const comments = Comment.commentInfos();
      console.log(comments[commentId - 1]);
      //:id 변수에 숫자가 아닌 값 처리
      if (isNaN(commentId)) {
        return res.render("404");
      }
      //존재하지 않는 댓글 id
      if (commentId < 1 || commentId > commentId.length) {
        return res.render("404");
      }
      res.render("comment", { commentInfos: comments[commentId - 1] });
    };
    • comment.ejs 
      • 화면 구성
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>댓글 자세히 보기</title>
      </head>
      <body>
        <h1><%= commentInfos.userId %>님의 댓글입니다.</h1>
        <a href="/comments">댓글 목록 보기</a>
        <p>작성일: <%= commentInfos.date %></p>
        <p>댓글 내용: <%= commentInfos.comment %></p>
      </body>
    </html>
    • comments.ejs 
      • 화면 구성
    <!DOCTYPE html>
    <html lang="ko">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>댓글 목록 보기</title>
      </head>
      <body>
        <h1>댓글 모음</h1>
        <a href="/">홈으로 이동하기</a>
        <ul>
          <% for (let i = 0; i < commentInfos.length; i++) { %>
          <li>
            <b><%= commentInfos[i].userId %></b> -
            <a href="/comment/<%= i + 1 %>"><%= commentInfos[i].comment %></a>
          </li>
          <% } %>
        </ul>
      </body>
    </html>

    데이터베이스를 연결하지 않고 MVC 패턴에 대해 맛만 보았다.

    다음 글에서는 MySQL을 연결하여 MVC 패턴을 적용해보겠습니다.

    https://github.com/DongHo-Kang/KDT-8-web/tree/acc69979097404e097f84de42b095898c135d7b2/230805_mvc

     

    728x90
Designed by Tistory.