09. 관심사 분리와 MVC 패턴 - 이론 24:36
1. 관심사의 분리 Separation of Concerns
해야할 작업(concern)을 관심사라고 정의한다.
우리가 좋은 객체지향 프로그램을 설계하려면 다음과 같은 원칙을 지켜야 한다.
OOP 5대설계원칙 - SOLID, 객체지향 설계 원칙(SOLID)
- 단일 책임 원칙(SRP, Single Responsibility Principle):모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함
- 개방 폐쇄의 원칙(OCP, Open-Closed Principle):소프트웨어 개체(클래스, 모듈, 함수 등등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다
- 리스코프 교체(치환)의 원칙(LSP, Liskov Substitution Principle):컴퓨터 프로그램에서 자료형 {\displaystyle S}S가 자료형 {\displaystyle T}T의 하위형이라면 필요한 프로그램의 속성(정확성, 수행하는 업무 등)의 변경 없이 자료형 {\displaystyle T}T의 객체를 자료형 {\displaystyle S}S의 객체로 교체(치환)할 수 있어야 한다는 원칙
-인터페이스 분리 원칙(ISP, Interface Segregation Principle):클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙
-의존성 역전 원칙(DIP, Dependency Inversion Principle):의존 관계를 맺을 때 변화하기 쉬운 것 보다 변화하기 어려운 것에 의존하라는 원칙을 의미한다.
분리에는 3가지 원칙이 있다.
1. 관심사
2. 변하는것, 자주 변하지 않는 것, common, uncommon이 좀 더 올바른 표현이다.
3. 공통(중복)코드
1. 입력의 대한 부분(공통코드)을 분리(Model)하여 하나의 관심사를 줄일 수 있다.
2. 처리(Controller)에 대한 코드를 통해 Model 객체에 접근한다.
3. 출력(view)의 분리 - 변하는 것과 변하지 않는 것의 분리
2. 관심사의 분리와 MVC패턴 - 실습
package com.fastcampus.ch2;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
// 년월일을 입력하면 요일을 알려주는 프로그램
@Controller
public class YoilTeller { // http://localhost:8080/getYoil?year=2021&month=10&day=1
// public static void main(String[] args) {
@RequestMapping("/getYoil")
public void main(HttpServletRequest request, HttpServletResponse response) throws IOException {
//문자열 배열 자동으로 만들어줌.
//관심사 Concerns -> 해야할 작업
//OOP 5대 설계원칙 - SOLID
//SRP : 단일책임의 원칙(하나의 메서드는 하나의 책임)
//관심사 분리에는 3가지 원칙이 있다.
//1. 관심사
//2. 변하는것, 변하지 않는 것
// common, uncommon
//3. 공통(중복)코드
// 1. 입력
String year = request.getParameter("year");
String month = request.getParameter("month");
String day = request.getParameter("day");
//2. 작업(요일계산)
int yyyy = Integer.parseInt(year);
//문자열을 정수값으로 변환하여 받아옴.
int mm = Integer.parseInt(month);
int dd = Integer.parseInt(day);
Calendar cal = Calendar.getInstance();
cal.set(yyyy, mm - 1, dd);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); //1. 일요일, 2. 월요일 ...
char yoil = " 일월화수목금토".charAt(dayOfWeek);
//3. 출력
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter(); // response 객체에서 브라우저로의 출력 스트림을 얻는다.
out.println(year + "년 " + month + "월 " + day + "일은 ");
out.println(yoil + "요일입니다.");
}
}
관심사 분리 코드. ↓
package com.fastcampus.ch2;
import java.io.IOException;
import java.util.Calendar;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
// 년월일을 입력하면 요일을 알려주는 프로그램
@Controller
public class YoilTellerMVC { // http://localhost/ch2/getYoilMVC?year=2021&month=10&day=1
// public static void main(String[] args) {
@RequestMapping("/getYoilMVC")
// URL 매핑은 중복된게 있으면 안됨.
// public void main(HttpServletRequest request, HttpServletResponse response) throws IOException {
public String main(int year, int month, int day, Model model) throws IOException {
//입력받을 값을 매개변수로 선언, Model을 선언해서
// ModelAndView mv = new ModelAndView();
//1. 유효성 검사
//왜? 값이 들어왔는지 안들어왔는지 확인해야해서.
if(!isValid(year, month, day))
return "yoilError";
//2. 요일 계산
char yoil = getYoil(year, month, day);
// 3. 계산한 결과를 model에 저장
model.addAttribute("year", year);
model.addAttribute("month", month);
model.addAttribute("day", day);
model.addAttribute("yoil", yoil);
// mv.addObject("year", year);
// mv.addObject("month", month);
// mv.addObject("day", day);
// mv.addObject("yoil", yoil);
//4. 결과를 보여줄 view를 지정
// mv.setViewName("yoil");
// return mv;
return "yoil"; // /WEB-INF/view/yoil.jsp
}
//private로 메서드를 생성한 이유는 여기 안에서만 사용되기 때문
private char getYoil(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); //1. 일요일, 2. 월요일 ...
return " 일월화수목금토".charAt(dayOfWeek);
}
private boolean isValid(int year, int month, int day) {
if(year==-1 || month==-1 || day==-1)
return false;
return (1<=month && month<=12) && (1<=day && day<=31); // 간단히 체크
}
}
3. 관심사의 분리와 MVC패턴 - 이론
pom.xml
pom.xml 파일을 업데이트 하면 프로젝트 우클릭 -> Maven -> Update Project.. 해줘야함.
매개변수 이름 얻어오기.
1. ReflectionAPI ->자바 8 이후 버전 - parmeters 옵션 체크
preferences -> compiler
2. Classfile
@WebServlet 톰캣오류. -> Bulid Path -> Libraries -> Add Library -> Server Runtime -> Tomcat