본문 바로가기
디자인패턴

디자인패턴- MVC

by 윤-찬미 2020. 11. 7.

디자인패턴은 개발분야와 상관없이 "개발자" 라면 조금 더 유연하고 알찬 코드를 짜기 위해 배워 둘 필요가 있다.

 

MVC디자인 패턴

MVC디자인 패턴은 개발자라면 한번쯤은 들어본 디자인패턴이다.

어쩌면 가장 많이 쓰이고 있는 디자인 패턴이 아닐까 싶다.(가장 단순함)

 

M : MODEL 

V : VIEW

C : CONTROLLER

개발할 때 위처럼 3가지로 각각의 역할들을 분리시켜 개발하는 방법 인데요.

 

 

  • Model : 어플리케이션에서 사용되는 데이터와 그 데이터를 처리하는 부분.
  • View : 사용자에서 보여지는 UI 부분 말그대로 뷰.
  • Controller : 사용자의 입력(Action)을 받고 처리하는 부분입니다 view와 model의 중간자 라고 봐도 되겠네요.

단점 

VIEW와 MODEL이 서로 의존성이 강하다.

 

글로만 보면 정확히 코드에서 어떻게 사용되는지 모를 수도 있으니까

www.sitepoint.com/mvc-design-pattern-javascript/

 

The MVC Design Pattern in Vanilla JavaScript - SitePoint

Tired of learning yet another framework? Camilo Reyes teaches you how to implement the MVC design pattern (model-view-controller) in vanilla JavaScript.

www.sitepoint.com

이 링크를 참조 하여 보는 것도 좋을 듯 하다.

var PenguinModel = function PenguinModel(XMLHttpRequest) {
  this.XMLHttpRequest = XMLHttpRequest;
};

PenguinModel.prototype.getPenguin = function getPenguin(index, fn) {
  var oReq = new this.XMLHttpRequest();

  oReq.onload = function onLoad(e) {
    var ajaxResponse = JSON.parse(e.currentTarget.responseText);
    var penguin = ajaxResponse[index];

    penguin.index = index;
    penguin.count = ajaxResponse.length;

    fn(penguin);
  };

  oReq.open('GET', 'https://codepen.io/beautifulcoder/pen/vmOOLr.js', true);
  oReq.send();
};

var PenguinView = function PenguinView(element) {
  this.element = element;

  this.onClickGetPenguin = null;
};

PenguinView.prototype.render = function render(viewModel) {
  this.element.innerHTML = '<h3>' + viewModel.name + '</h3>' +
    '<img class="penguin-image" src="' + viewModel.imageUrl +
      '" alt="' + viewModel.name + '" />' +
    '<p><b>Size:</b> ' + viewModel.size + '</p>' +
    '<p><b>Favorite food:</b> ' + viewModel.favoriteFood + '</p>' +
    '<a id="previousPenguin" class="previous button" href="javascript:void(0);"' +
      ' data-penguin-index="' + viewModel.previousIndex + '">Previous</a> ' +
    '<a id="nextPenguin" class="next button" href="javascript:void(0);"' +
      ' data-penguin-index="' + viewModel.nextIndex + '">Next</a>';

  this.previousIndex = viewModel.previousIndex;
  this.nextIndex = viewModel.nextIndex;

  var previousPenguin = this.element.querySelector('#previousPenguin');
  previousPenguin.addEventListener('click', this.onClickGetPenguin);

  var nextPenguin = this.element.querySelector('#nextPenguin');
  nextPenguin.addEventListener('click', this.onClickGetPenguin);
};

var PenguinController = function PenguinController(penguinView, penguinModel) {
  this.penguinView = penguinView;
  this.penguinModel = penguinModel;
};

PenguinController.prototype.initialize = function initialize() {
  this.penguinView.onClickGetPenguin = this.onClickGetPenguin.bind(this);
};

PenguinController.prototype.onClickGetPenguin = function onClickGetPenguin(e) {
  var target = e.currentTarget;
  var index = parseInt(target.dataset.penguinIndex, 10);

  this.penguinModel.getPenguin(index, this.showPenguin.bind(this));
};

PenguinController.prototype.showPenguin = function showPenguin(penguinModelData) {
  var penguinViewModel = {
    name: penguinModelData.name,
    imageUrl: penguinModelData.imageUrl,
    size: penguinModelData.size,
    favoriteFood: penguinModelData.favoriteFood
  };

  penguinViewModel.previousIndex = penguinModelData.index - 1;
  penguinViewModel.nextIndex = penguinModelData.index + 1;

  if (penguinModelData.index === 0) {
    penguinViewModel.previousIndex = penguinModelData.count - 1;
  }

  if (penguinModelData.index === penguinModelData.count - 1) {
    penguinViewModel.nextIndex = 0;
  }
 this.penguinView.render(penguinViewModel);
};

var penguinModel = new PenguinModel(XMLHttpRequest);

var targetElement = document.getElementById('listOfPenguins');
var penguinView = new PenguinView(targetElement);

var controller = new PenguinController(penguinView, penguinModel);

controller.initialize();

controller.onClickGetPenguin({ currentTarget: { dataset: { penguinIndex: 0 } } });