OOP 5대 설계 원칙 - SOLID
첫번째 원칙 SRP(Single Responsibility Principle)
: 하나의 메서드는 하나의 책임만 져야한다
-> 관심사(concern) 즉 해야할 작업의 분리를 해야한다
객체지향적 설계를 위해서는 '분리'를 잘 해야하는데 첫째는 관심사, 둘째는 자주 변하는 것과 자주 변하지 않는 코드, 마지막으로 공통(중복)코드를 분리해야한다.
아래의 코드는 입력, 처리,출력 관심사가 분리되지 않는 메서드를 보여준다.
@PostMapping("/login")
public void login(HttpServletRequest req, HttpservletResponse res){
//////입력//////
String id = req.getParameter("id");
String pwd = req.getParameter("pwd");
//////입력//////
//////처리//////
if(!checkLogin(id, pwd)){
...
return "/login";
}
String name = LoginService.getName(id);
//////처리//////
//////출력//////
res.setContentType("text/html");
res.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
...
out.println("</html>);
//////출력//////
}
입력의 분리는 요청메시지의 parameter로 저장된 변수를 매핑된 메서드의 파라미터에 선언하면 Spring에서 자동으로 값을 넣어준다.
@PostMapping("/login")
public void login(String id, String pwd, HttpservletResponse res){
//////처리//////
if(!checkLogin(id, pwd)){
...
return "/login";
}
입력은 분리했고, 처리와 출력은 어떻게 구분할까?
우선 구분을 하면 처리된 결과를 출력에 넘겨주는 수단이 필요하다. Spring은 이를 Model객체를 통해 결과값을 view(출력)단에 넘겨준다.
또한 출력을 PrintWriter 객체로 하지 않고, 출력 파일(ex. jsp)을 따로 분리하여 Model 객체로 건네받은 데이터를 출력 파일에 적용한 결과물을 응답으로 보낸다.
@PostMapping("/login")
public void login(String id, String pwd, Model m){ //입력의 분리
if(!checkLogin(id, pwd)){ //처리의 분리
...
return "/login";
}
String name = LoginService.getName(id);
m.addAttribute(name);
return "home"; //원래는 redirect여야한다.
}
//home.jsp파일 출력의 분리
<html>
<head></head>
<body>
<p>${param.name}님 안녕하세요</p>
</body>
</html>
이렇게 입력, 처리, 출력이 분리된다.
@RequestMapping("/getMypage")
public String main(String id, String pwd, Model m){
...
return "myPage";
}
@RequestMapping("/getMypage")
public void main(int age, String name, Model m){
...
}
@RequestMapping("/getMypage")
public ModelAndView main(String id, String pwd){
//Controller에서 Model객체 직접 생성
ModelAndView mv = new ModelAndView();
...
//ModelAndView객체에 처리 결과값 저장
mv.addObject(name, "youngja");
mv.addObject(age, "33");
//출력을 처리할 view페이지의 이름 지정
mv.setViewName("myPage");
return mv;
}
reflection API(jdk1.8, -parameters 옵션)
java파일을 컴파일 할 때 컴파일러는 메서드의 파라미터 타입은 중요하게 여겨 저장하지만, 파라미터의 이름은 저장하지 않습니다. 그래서 reflectionAPI를 사용하여 코드를 작성해도, 컴파일 된 상태에서는 변수 이름이 저장되어있지 않기 때문에 읽을 수 없습니다.
따라서 컴파일 할 때 - -parameters 옵션을 줘야합니다.
class file의 local variable table의 지역변수를 읽어서 가져와야한다.
이미 옵션을 주지 않고 컴파일 된 경우가 있기 때문에 두 가지 방법을 모두 고려해야한다.