21.02.10

민주·2021년 2월 10일

[디자인 패턴]

1. 디자인 패턴의 정의
- 설계 문제에 대한 해답을 문서화 하기 위해 고안된 방법
- 소프트웨어 개발과정에서 자주 나타나는 과제를 해결하기 위한 방법
- 패턴은 특정한 상황에서 구조적인 문제를 해결하는 방식을 설명해준다.
- 쉽게 말해 디자인패턴은 틀을 잡아주는 것이다.

2. 패턴 사용시 주의 사항
- 디자인 패턴은 일반적으로 대규모 프로그램 개발에 적합하다.
- 각 디자인 패턴이 유용한 상황에 대해 잘 알아야 한다.
- 패턴은 절대적이지 않고 상황에 맞게 유연하게 변형이 가능하다.
- 패턴의 틀에 갇힌 사고방식은 효율성이 낮은 프로그램을 생산하게 된다.

[MVC 패턴(Model2)]

- javabeans를 사용하는 것이 Model1이다.
- MVC : Model View Controller
- view(보여짐) - 유저가 요청하거나 요청한 결과를 보여주는 화면 역할 (클라이언트 역할(JSP))
- controller(분배) - 요청한 내용을 확인하여 해당 업무를 모델에게 전달하는 역할(서버역할(java))
- model(일) - controller에서 받은 요청을 처리후 controller에게 반환하는 역할(서버역할(java))

[JSP와 MVC의 비교]

[Basic MVC Pattern]

[Controller]
//controller라고 명시해주는 뜻도 있고, 뒤에 "/"가 붙는 애들은 이 파일로 이동하게 된다.
@WebServlet("/")
public class MainController extends HttpServlet {	
  //serialize : Object -> 통신 가능한형태로 만드는것
  //네트워크 상에서는 어떤객체가 어떤 객체인지 헷갈릴수 있어서 고유번호를 준다.
  //안줘도 상관은없다.
  private static final long serialVersionUID = 1L;
  //method="get"로 요청이 왔을 경우 여기서 받는다.
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
	System.out.println("DO GET!!"); //get방식으로 들어오는경우 출력
	process(req,resp);//get방식으로 들어오는 경우 메서드 실행
	}
  //method="post"로 요청이 왔을 경우 여기서 받는다.
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
	System.out.println("DO POST!!"); //post방식으로 들어오는 경우 출력
	process(req,resp); //post방식으로 들어오는 경우 메서드 실행
  }
	
  private void process(HttpServletRequest req, HttpServletResponse resp)  
    throws ServletException, IOException {
	System.out.println("post로 오던지 get으로 오던지 모두 여기서 처리 가능");
	String param= req.getParameter("param");
	System.out.println("param:" +param); //param 출력
		
	//1. 파라메터에 따라서 담을 메시지 지정
        //(모델에서 하는 일이지만 간단해서 그냥 컨트롤러에서 처리)
	Object msg= null; //들어오는 타입이 둘 이상이니까 Object로 잡아준다.
	if(param == null) { //param이 null인경우
	    msg="Invalid Type"; //msg에 Invalid Type을 담는다.
	}else if(param.equals("greeting")) { //param이 greeting일 경우
	    msg="안녕하세요."; //msg에 안녕하세요.를 담는다.
	}else if(param.equals("date")) { //param이 date일경우
	    msg = new java.util.Date(); //현재 시간과 날짜를 담는다.
	}
		
	//2.담은 메시지를 View에 보내는 일
	//view에서는 ${result}로 값을 받아 볼 수 있다.
	//응답은 response인데? 왜 request에?
	//request에서는 forward를 사용 -> 특정 페이지로 보내는 역할 + 데이터도 담아보낸다.
	//내가 응답 받은거를 다른 페이지로 보내줄때는 request를 사용해야한다.
	//response에서는 sendRedirect를 이용해 단순 페이지 이동밖에 할 수없다.
	req.setAttribute("result", msg); //result라는 이름으로 데이터를 담기
        //RequestDispatcher에서 보낼 페이지 지정   
	RequestDispatcher dis = req.getRequestDispatcher("result.jsp");
        //원래 사용법이 req,resp을 다 원한다. forward를 해야 데이터도 보낼수 있다.
	dis.forward(req, resp); 
	}

}
- welcomelist에 등록된 이름의 파일이 있을경우 controller를 무시하고 해당 파일로 먼저 이동한다.
- welcomelist에 등록된 파일이 없는 경우에 controller로 오게 된다.
- 위 코드는 result.jsp밖에 없는 경우이기 떄문에 controller로 오게된다.
[result.jsp]
<body>
	<h3>result : ${result}</h3>
</body>
- controller에서 result.jsp로 데이터를 "result"라는 이름으로 보냈기 때문에 
  EL태그를 사용하여 result라는 이름으로 받을 수 있다.

[Multi URL]

[Controller]
// "/" 제외, /index와 /main으로 들어오는것만 여기로 온다.
@WebServlet(urlPatterns= {"/index","/main"}) 
public class MainController extends HttpServlet {
    @Override
    //method가 get방식으로 들어오는 경우
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
	process(req,resp);
    }

    @Override
    //method가 post방식으로 들어오는 경우
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
	process(req,resp);
    }
	
    private void process(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
	//들어오는 URL에서 요청 URI을 파악
	String uri = req.getRequestURI(); //프로젝트+파일경로를 가져온다.
	System.out.println(uri); // /02_MultiURL/index
		
	String context = req.getContextPath(); //프로젝트 경로만 가져온다.
	System.out.println(context);// /02_MultiURL
		
	//uri - context = request url 
	//전체에서 context.length()만큼 잘라내고 뒷내용만 추출한다.
        String subAddr = uri.substring(context.length());
	System.out.println(subAddr); // 추출한 내용 출력 (/index)
		
	//요청 URL에 따라서 다른 메시지를 view에 보낸다.
	String result = "";
		
	//실질적인 처리는 모델에서 하고 Controller에서는 위와 같이 분기만 해준다.
	switch(subAddr) { //1.7이하버전에서는 이 부분을 if문 처리 할것
	case"/index": //subAddr이 /index라면 실행 후 빠져나감
	    result="index.jsp는 아니지만 인덱스 페이지에 오신것을 환영합니다.";
	    break;
	case"/main": //subAddr이 /main이라면 실행 후 빠져나감
	    result="메인페이지에 오신것을 환영합니다.";
	    break;
	}
	//result라는 이름으로 데이터를 담는다. 
    	//view에서는 ${result}로 값을 받아 볼 수 있다.
	req.setAttribute("result", result); 
	RequestDispatcher dis = req.getRequestDispatcher("result.jsp"); 
	//response에서는 sendRedirect를 이용해 단순 페이지 이동밖에 할 수없다.
	//내가 응답 받은거를 다른 페이지로 보내줄때는 request를 사용해야한다.
    	//forward를 사용하기위해서 request를 사용, forward를 사용해야 데이터도 보낼수 있다.
	dis.forward(req, resp); 
	}
- 하나의 Controller 에서는 단일 url 또는 다수의 url 을 처리 할 수 있다.
- @WebServlet(urlPatterns= {"/","/index","/main"})
- "/"(root)는 최상위이기 때문에 앞에 "/"붙는 애들의 모든 요청을 다 받아드린다.
- 그래서 특정한 url만 받아들이기 위해서는 "/"를 제외해야한다.
- 하지만 "/"제외시 서버가 기동되는 첫화면에서 404오류가 발생하게된다.
- 이를 방지하기 위해서 우리는 일반적으로 첫 화면은 index.jsp로 만들어 준다.

[Calculator Service]

[index.jsp]
<body>
    <h2>계산기</h2>
    <hr />
    <!-- 컨트롤러에서 calc로 요청해라 -->
    <form action="calc" method="get">
	<input type="text" name="val1" /> 
	<select name="oper">
	    <option value="+">+</option>
	    <option value="-">-</option>
	    <option value="*">*</option>
	    <option value="/">/</option>
	</select> 
	<input type="text" name="val2" /> 
	<input type="submit" name="전송" />
    </form>
</body>
[Controller]
@WebServlet(urlPatterns= {"/calc"})
public class MainController extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    //method가 get방식으로 들어오는 경우
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
	process(req,resp);
    }

    @Override
    //method가 get방식으로 들어오는 경우
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
	process(req,resp);
    }
	
    private void process(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException  {
	int result = 0;
	//index.jsp에서 받아온 파라메터값을 변수에 넣어준다.
	int val1 = Integer.parseInt(req.getParameter("val1"));
	int val2 = Integer.parseInt(req.getParameter("val2"));
	String oper = req.getParameter("oper");
		
	switch(oper) {
	case"+":
	    result= val1+val2;
	    break;
	case"-":
	    result= val1-val2;
	    break;
	case"*":
	    result= val1*val2;
	    break;
	case"/":
	    result= val1/val2;
	    break;
	}

	req.setAttribute("result", result); 
	RequestDispatcher dis = req.getRequestDispatcher("result.jsp");
	dis.forward(req, resp); 
    }
}
- index.jsp에서 form의 action을 calc로 지정했기 때문에 이 컨트롤러로 값을 받아오도록 
  @WebServlet를 calc로 해준다.
- @WebServlet으로 인해 이 컨트롤러에서 index.jsp의 파라메터를 받아올 수 있다.
- 각각 값을 넣어 switch-case구문으로 연산을 통해 result의 해당 연산값이 담긴다.
- result.jsp에서 정상적으로 값을 받아오는 것을 확인할 수 있다.
profile
개발이좋아요

0개의 댓글