본문 바로가기
Study/JSP

[JSP] command패턴

by YoungD 2023. 9. 21.

 

Command패턴 

 특정이름의 파라미터(command)에 명령어 정보를 담아서 전달하여 각 명령어에 따른 로직을 처리하는 코드를 별도의 클래스로 작성하는 것

 

 

FrontController는 요청'만' 받고 class가 실행

웹에서 요청받기 위해 FrontController로 만들었지만 (서블릿에서 Class 호출 가능) 기능 구현을 나누기 위해

클래스들로 분리

 

Command패턴을 사용하는 이유 : 객체지향, 유지보수에 용이

servlet과 다르게 class는 용량이 적다

 

 

 

 

<JoinService> class 생성

   public String execute(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException {

   System.out.println("회원가입 기능실행");

 

 

   String email = request.getParameter("email");

   String pw = request.getParameter("pw");

   String phone = request.getParameter("phone");

   String addr = request.getParameter("addr");

 

 

   MemberDTO dto = new MemberDTO(email, pw, phone, addr);

 

 

   MemberDAO dao = new MemberDAO();

   int cnt = dao.join(dto);

 

   if (cnt > 0) {

   System.out.println("회원가입 성공");

   } else {

   System.out.println("회원가입 실패");

      }

 

   return "main.jsp";

   }

 

 

<LoginService> class 생성

   public String execute(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException {

   System.out.println("로그인기능 실행");

 

   String email = request.getParameter("email");

   String pw = request.getParameter("pw");

 

   MemberDTO dto = new MemberDTO(email, pw);

 

   MemberDAO dao = new MemberDAO();

   MemberDTO info = dao.login(dto);

 

   if (info != null) {

      System.out.println("로그인 성공");

      System.out.println(info.toString());

    세션에 로그인 정보 저장 || 세션은 서버에 있는 영역

   HttpSession session = request.getSession();

   session.setAttribute("info", info);

   } else {

      System.out.println("로그인 실패");

      }

 

   return "main.jsp";

      }

 

   }

 

 

 

<FrontController> 

   if(command.equals("JoinService.do")) {

   회원가입기능 구현

   JoinService service = new JoinService();

   String moveUrl = service.execute(request, response);

   response.sendRedirect(moveUrl);

 

   }else if(command.equals("LoginService.do")) {

   로그인기능 구현

   LoginService service = new LoginService();

   String moveUrl = service.execute(request, response);

   response.sendRedirect(moveUrl);

         }

 

      }

<JoinService> 와 <LoginService> class를 실행시키는 곳

 

 

 

 

<ICommand> 인터페이스 생성 (execute 메소드를 구현하기 위해)

 

 

   package com.front;

   public interface ICommand {

   public String execute(HttpServletRequest request, HttpServletResponse response)

   throws ServletException, IOException;  (요청 파라미터를 동일한 메소드로 처리하도록하기위한 추상 메소드 정의)

 

   execute 매개변수로 전달받은 SQL구문을 수행하는 메소드 라는 메서드를 클래스마다 강제할 수 있는 법

 

   }

요청을 받고 (HttpServletRequest)  요청을 처리한 후 응답을 보낸다(HttpServletResponse)
=> 이러한 공통사항을 인터페이스로 작성

 

   public class LoginService implements ICommand

class에서 ICommand implement 해주기

 

 

<FrontController>

   ICommand service = null  동일한 부모형태인 ICommand형태로 up캐스팅

   if(command.equals("JoinService.do")) {

    회원가입기능 구현

   service = new JoinService();

 

   } else if(command.equals("LoginService.do")) {

    로그인기능 구현

   service = new LoginService();

      }

   String moveUrl = service.execute(request, response);

   response.sendRedirect(moveUrl);

 

훨씬 간결해진 코드

 

 


 

구체적인 기능을 다양하게 설계해놓으면 유사한 작업을 하는 클래스들은 같은 방식으로 사용할 수 있어 한 번 클래스를 익혀놓으면 다른 클래스도 쉽게 접근해서 사용할 수 있다.(다형성)

비슷한 형태의 클래스를 여러 개 정의해야 할 경우 클래스들이 공통적으로 갖는 메소드를 인터페이스 내의 추상 메소드로 정의해놓고 이 인터페이스의 구현 클래스에서 상속을 받아 서브 클래스에서 적합한 로직을 기술하도록 한다. 이렇게 인터페이스에 다형성을 위한 메소드를 정의해놓으면 이를 상속 받는 서브 클래스에서 오버라이딩 하지 않으면 컴파일 에러가 발생하기 때문에 강제로 동일한 접근방식을 취할 수 있도록 할 수 있다.