MVC?

타다닥·2024년 1월 17일
0
post-thumbnail
post-custom-banner

MVC

  • Model View Controller
  • 소프트웨어 설계와 관련된 디자인 패턴이다. 자주 쓰이는 설계 방법의 패턴을 형식화해놓은 것으로 보면 된다.
  • model, view, controller 로 각 기능별로 나눠서 작업을 처리하는 방식이다.
  • 서버측의 코드를 분리하고자 나오게 되었다. 백엔드 코드를 사용하면서 구현해낼 때 사용하는 패턴이다.
  • MVC를 이용하는 프레임워크로는 PHP, Express, Angular 등이 있다
  • 장점
    • 각 패턴들을 구분해서 개발하기 때문에 유지보수에 용이하다.
    • 확장성이 높고 협업에 용이하다.
  • 단점
    • 의존성 분리가 어렵다. 분리해서 만들더라도 결국은 엮여있다.
    • 설계 단계가 복잡하고 시간이 오래 걸린다. 클래스의 단위가 많아진다.

MVC의 흐름과 역할

(도움 받은 링크)

  • router
    • 액션이 생기면 특정한 주소로 이동하도록 도와주는 역할이다. 이러한 요청들에 대한 정보를 모아둔다.
    • 주소에 따라 다른 페이지를 보여주는 동작에 대한 부분!
    • endpoint에 따라 적절한 라우터로 이동하도록 연결해준다. controller를 호출하는 것!
      • 여기서 controller는 바로 view를 호출하거나, 필요에 따라 model을 거쳤다가 view를 호출한다.
  • controller
    • 유저와 소통하며 필요한 데이터를 주고받는다.
    • view와 model을 연결해준다.
    • view에서 일어나는 액션을 model로 전달해서 작업을 처리한다. model에서 사용하는 데이터를 가공해서 veiw로 보내주는 역할
  • model
    • 데이터를 직접 다루고 처리하는 역할을 한다.
    • 데이터베이스와 통신하며 데이터를 다루게 된다.
    • controller에게 명령을 받아 데이터를 관리한다.
  • view
    • 유저가 직접 보는 화면을 보여주는 역할이다.
    • view에서 만든 페이지를 controller에게 전달, controller는 유저에게 전달해준다.

MVC 기본 폴더 구조

  • 예를 들어 User Table이 있다면 그 안에는 기본적으로 CRUD구조로 나누어져 있다.
    • C : 회원가입(insert)
    • R : 로그인(select)
    • U : 회원정보 수정(update)
    • D : 탈퇴(delete)
  • 보통 이런식으로 파일을 만들어주고, 테이블 단위로 쪼개서 분리하는 식이다.
  • 이런식으로 분리를 해서 각 파일을 넣는다.

MVC 사용해보기

▶️ 로그인 창을 만들어보자. 아이디의 비번의 값을 데이터에 저장해놓고, 입력한 값에 따라 로그인의 성공여부를 화면에 보여준다.

  • 진행은 Router, Controller, Model, View 순서대로 해보자.
    • Router 분리 (요청을 정의한다.)
    • Controller 분리 (요청에 대한 데이터 처리한다. Veiw render,Client에 응답)
    • Model 분리 (db에 접근하여 데이터를 select, insert, update, delete한다.)

최상단 index.js

05-mvc-prac>index.js

  • 기본 세팅을 해준다. 파일을 실행할 때 결국은 하나의 파일을 실행하는 것이기 때문.
  • use() 를 사용해 Router를 미들웨어로 걸어준다.
const express = require("express");
const app = express();
const PORT = 8000;

app.set("view engine", "ejs");
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

//Router 정의해서 가져오고 사용하겠다.
const router = require("./routes/user");
app.use("/user", router);

//-----존재하지 않는 get요청에 대해서 처리하기 위한 부분
//얘는 위치도 중요하다. 위에서 부터 읽으니까 !
//위에서 다 걸러져서 왔는데 아무도 특정한 get요청을 받아주지 않을 때 들어온다.
// *은 어떤 라우터든 상관없다는거.
app.get("*", function (req, res) {
  res.send("페이지를 찾을 수 없습니다.");
});

app.listen(PORT, function () {
  console.log(`Sever Open: ${PORT}`);
});

router

파일 경로 : 05-mvc-prac>routes>user.js

  • 어떤 기능들을 사용 할 지에 대해 최상단 index.js에 작성했다.
  • router는 액션이 생기면 특정한 주소로 이동하도록 도와주는 역할이다. 이러한 요청들에 대한 정보를 모아둔다.
    • express에서 사용하는 router를 모아놓은 것이다. (미들웨어로 사용되는)
  • 기본 요청 (get, post)에 대한 것들을 작성해준다.
  • 그리고 endpoint에 따라 적절한 라우터로 이동하도록 연결해준다. 여기서 작성만 한다고 동작이 되지는 않는다.
  • 이 router자체를 모듈화해 객체로 넘겨준다. 어디로? Cotroller로. 경로를 연결해주는 것.
    • 그럼 이후 Cotroller가 View 와 Model을 연결해줄거다.
const express = require("express");
const router = express.Router();
const controller = require("../controller/Cuser");

//기본적으로 /user를 사용하겠다고 정의했기 때문에 아래 주소로 연결되게 된다.
// localhost:8000/user
router.get("/", controller.main);

// localhost:8000/user/login
router.post("/login", controller.login);

//router자체를 모듈화해 객체로 넘겨준다.
module.exports = router;

controller

파일경로 : 05-mvc-prac>controller>Cuser.js

  • View 와 Model을 연결해준다.
  • 중간에서 뭘 가져오고 내보낼 건지 작성한다고 보면 된다. (Model에서 데이터를 가져오는 것에 대한)
  • 경로와 연결 될 함수 내용을 정의해주는 부분이기 때문에 req, res 객체의 사용이 가능하다.
//Model에 있는 데이터를 가져와서 사용하겠다.
//아래는 결국 해당 파일에 작성된 getUser라는 함수를 가져오는 셈이다.
const User = require("../model/User");

//----- 경로와 연결 될 함수 내용을 정의한다.
//메인 페이지에 대한 요청과 응답 부분
exports.main = (req, res) => {
  res.render("index");
};

//----- 로그인을 했을 때에 대한 요청과 응답 부분
//Model에서 가져온 데이터는 userData = {id: "jeong", pw: "12345"}
//가져와서 사용하는거기 때문에 함수 안에 새로 정의해준다.
exports.login = (req, res) => {
  const userData = User.getUser();
  let data;
  if (req.body.userid == userData.id && req.body.password == userData.pw) {
    data = {
      isSuccess: true,
      msg: "로그인 성공!",
    };
  } else {
    data = {
      isSuccess: false,
      msg: "로그인 실패!",
    };
  }
  res.send(data);
};

model

파일경로 : 05-mvc-prac>model>User.js

  • 데이터를 직접 다루고 처리하는 역할을 한다.
  • controller에게 명령을 받아 데이터를 관리한다.
exports.getUser = () => {
  const id = "jeong";
  const pw = "12345";
  return { id, pw };
};

view

  • 유저가 직접 보는 화면을 보여주는 역할이다.
  • view에서 만든 페이지를 controller에게 전달, controller는 유저에게 전달해준다.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  </head>
  <body>

    <h2>로그인</h2>
    <form name="login">
      <fieldset>
        <legend>ID</legend>
        <input type="text" name="userid" />
      </fieldset>
      <fieldset>
        <legend>Password</legend>
        <input type="password" name="password" />
      </fieldset>

      <button type="button" onclick="clickLogin()">로그인</button>
    </form>
    <div class="login-result"></div>

    <script>
      function clickLogin() {
        const form = document.forms["login"];
        const data = {
          userid: form.userid.value,
          password: form.password.value
        }

        axios({
          method: "POST",
          url: "/user/login",
          data: data
        }).then((res) => {
          // { isSuccess: ??, msg : ?? }
          const {
            isSuccess,
            msg
          } = res.data
          const element = document.querySelector(".login-result");
          element.innerHTML = msg;

          const color = isSuccess ? "blue" : "red";
          element.style.color = color
        })
      }
    </script>
  </body>
</html>

💬

아주아주 헷갈렸던 내용이다. 내 기억으로는 MVC에 대해 제대로 이해하지도 못한채로 1차 프로젝트를 진행했던 것 같다. 하지만 뭐든 실전에서 배우는게 더 크다고 했던가, 실제로 프로젝트를 진행해보니 이해가 되었었다. 노션에 정리해놓은 날짜는 10월 26일..! 벨로그에 다시 업로드를 하면서 내용을 보니 또 새롭게 이해가 되는 느낌이다. 뒤늦게 업로드하면서복습하는 느낌도 들고 괜찮은거 같기도..하다..!

profile
프론트엔드 ㄱH발ㅈr ㅎH보ㅈr - ☆
post-custom-banner

0개의 댓글