MVC 패턴, 왜 사용할까
개발자는 프로그램을 개발할 때 당장의 개발 뿐만 아니라 이후에 있을 유지보수나 기능 추가, 에러사항에 대한 대응 등을 고려한다. 코드 한 줄을 변경해야 할 때, 매번 거의 모든 코드를 변경해야 한다면 개발자들은 힘들 것이다. 다시 말하자면 이는 각 코드가 서로에 대한 의존도가 높다는 것이고, 앞서 말한 상황을 피하기 위해서는 의존도를 낮춰야 한다는 것이다.
MVC 패턴이란 무엇이고, 어떻게 사용할까. 간단한 개념과 예시가 다음 링크에 있다.
MVC 아키텍처란
언어 : JAVA 수업 주제 : Class 및 객체지향의 개념 MVC 아키텍처란 Class란 Class란 메서드(함수)와 필드(변수)의 집합체이다. 또한 Class는 프로그램을 개발할 때 기능 단위로 분리하여 작성한다. 자동차
codezaram.tistory.com
MVC 패턴 제대로 사용하기
Java 환경에서 작성하였습니다.
문제점 :
나는 MVC 패턴에 대해 공부한 뒤, 개발할 때 적용하기로 마음먹었다.
간단한 프로그램에서는 어떻게든 설계하여 구조에 맞게 잘 프로그래밍했지만, 복잡한 프로그램에서는 잘 되지 않았다.
문제는 GUI가 들어갔을 때 심각해졌다. 서로 관여하지 말아야 할 View와 Model이 서로를 호출하며 MVC 모델을 사용하지 않았을 때의 코드로 돌아가고 있었다.
해결 방안 :
MVC 패턴에서 Model과 View는 서로 관여할 수 없으며 모든 제어는 Controller를 통해서 이루어져야 한다. 의존성의 차이는 GUI를 구현할 때 ActionListener를 어디에 구현하는가에 따라 갈렸다.
ActionListener라는 리스너 interface가 있다. 리스너는 사용자의 행동을 감지하고, 행동에 따라 메서드 내에 작성된 코드를 실행하는 인터페이스이다. ActionListener는 크게 세 가지의 형태로 구현할 수 있다.
- 해당 GUI구성요소의 코드를 작성하며 Listener를 넣을 때 내부에 작성하기
- Listener를 다른 클래스로 구현하고 호출해서 Listener 넣기
- Listener를 Controller 클래스의 내부 클래스로 구현하고 호출해서 Listener 넣기
Listener를 구성요소를 작성할 때 같이 넣는 경우
import javax.swing.*;
import java.awt.event.*;
public class Example{
public Example{
JButton btn = new JButton();
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//행동 감지 시 실행할 내용
}
});
}
}
위의 경우, 매 구성요소마다 ActionListener를 작성해야 하므로 코드의 길이가 길어지고 가독성이 떨어진다. 또한 Model을 직접 호출하면 안되므로 Controller를 호출해야 한다. Controller 호출 시 View와 Controller이 서로 호출하는 문제가 발생한다. 따라서 적합하지 않다.
Listener를 다른 클래스로 구현하는 경우
import java.awt.event.*;
public class ExampleListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//행동 감지 시 실행할 코드
}
}
import javax.swing.*;
public class ExampleView{
public ExampleView(){
JButton btn = new JButton();
btn.addActionListener(new ExampleListener);
}
}
리스너가 다른 클래스에 구현되었으므로 호출하지 않는 이상 Example Class 내의 요소에는 접근할 수 없다. 또한, Controller에게 행동이 감지되었다고 알리기 위해 Controller를 호출해야 한다. 따라서 적합하지 않다.
Listener를 내부 클래스로 구현하는 경우
import java.awt.event.*;
public class ExampleController{
private exampleView ex;
public ExampleController(){
ex = new ExampleView(new ExampleListener);
}
public class ExampleListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//행동 감지 시 실행할 코드
}
}
}
import javax.swing.*;
public class ExampleView{
public ExampleView(ActionListener _myActionListener){
JButton btn = new JButton();
btn.addActionListener(_myActionListener);
}
}
위의 예시와 같이 Controller의 내부 Class로 ActionListener를 구현한다면 View에서 Controller를 호출할 필요 없이 Model의 변경을 자유자재로 할 수 있다. 또한 View의 구성요소들도 get 함수 구현을 통해 호출할 수 있다. 이러한 장점은 Controller에서 모든 것을 통제하기 때문에 가능한 것이다. 사용자의 행동이 감지되면 그에 따른 코드를 동작시키는 일도 통제의 일환이기에 Controller의 취지에도 부합한다. ActionListener를 많이 구현할 필요 없기 때문에 가독성이 좋다는 장점도 있다. MVC 패턴을 사용할 때 위의 방식대로 코드를 작성한다면 한단계 높은 수준의 프로그램을 구현할 수 있을 것이다.