7. The Dispatcher View pattern
Dispatcher View디자인 패턴은 두 개의 서브 패턴(Front Controller와View Helper)을 합쳐 하나의Micro프레임 워크를 만든것이다.
Dispatcher View와Service-to-Worker디장니 패턴은 유사한 구조를 가지면서도 두 패턴은 서로 다른 참여 객체를 갖는다. ‘Dispatcher View’는 동적인 뷰가 만들어질 때까지 컨텐츠 검색을 지연하고,반면에‘Service-to-Worker’는 컨트롤러 앞에서 컨텐츠 검색을 지연시킨다.
구조
Dispatcher View pattern class diagram | |
Dispatcher View pattern sequence diagram |
Service-to-Worker에서는Controller에서Dispatcher로 요청이 전달 되기 전에Command와Helper역할자에게 먼저 요청이 전달 되지만Dispatcher View에서는Dispatcher로 요청이 전달 된 다음이 된다.
JSP와 같은 웹 어플리케이션에서는Service-to-Worker패턴으로 비즈니스 요청을 처리 한 후valueBean을HttpServletRequest에 담아View에게 전달 한다.하지만Dispatcher View는valueBean을view Helper패턴을 이용하여 가져온다.
두 패턴의 가장 큰 차이점이라면“비즈니스 메서드가 어디에서 호출 되는가?”이다.
역할
n Controller :
요청을 처리하고,요청/응답 처리를 중앙 제어하는 시작점이고,인증,권한 부여,그리고 권한 위임을 담당한다.
요청을 처리하고,요청/응답 처리를 중앙 제어하는 시작점이고,인증,권한 부여,그리고 권한 위임을 담당한다.
n Dispatcher :
뷰 관리와 내비게이션을 담당한다.도,다음 뷰에 권한을 위임한다.
뷰 관리와 내비게이션을 담당한다.도,다음 뷰에 권한을 위임한다.
n View :
클라이언트에 정보를 보여준다. ‘Dispatcher View’에서 뷰는‘View Helper’로 데이터를 데이터 소스로부터 가져온다.
클라이언트에 정보를 보여준다. ‘Dispatcher View’에서 뷰는‘View Helper’로 데이터를 데이터 소스로부터 가져온다.
n Helper :
뷰 또는 컨트롤러가 처리를 완성할 수 있도록 한다..
뷰 또는 컨트롤러가 처리를 완성할 수 있도록 한다..
n Value Bean :
헬퍼의 다른이름이다.
헬퍼의 다른이름이다.
n Business Service :
클라이언트가 접근하려는 서비스,비즈니스 티어에 접근하는 시작점이다.일반적으로‘비즈니스 위임’이라고 한다.
클라이언트가 접근하려는 서비스,비즈니스 티어에 접근하는 시작점이다.일반적으로‘비즈니스 위임’이라고 한다.
의도
Front Controller와View Helper패턴을 합쳐 장점만을 가진 프레임워크를 만든다.
결론
n 두개의 서브패턴‘Front Controller’와‘View Helper’를 합친것이다.
n 컨트롤러,디스패처,뷰 그리고 뷰 헬퍼로 이루어진다.
n 컨트롤러와 디스패처의 역할이덜 중요하다.
n 뷰는 동적 생성 시점에 비즈니스 티어로부터 건텐츠검색과 이 데이터의 출력을 담당한다.
n 뷰와 헬퍼 뒤에 로직과 행위를 많이 넣어 뷰를 가능한 한 복잡하게 만든다.일반적으로 스크립릿코드나 커스텀 태그가 컨트롤러에서 완성하지 못한 일을 완성시키는 데 필요하다.
예제소스
Service-to-Worker패턴을 사용한 예제를‘Dispatcher View’패턴 으로 변경해 본다.
Class
소스
package dispatcherView; import java.util.ArrayList; public class businessService { private static ArrayList array = new ArrayList(); public businessService() { } public static valueBean[] getMailList() { valueBean[] values = new valueBean[array.size()]; array.toArray(values); return values; } public static void addMail(valueBean value) { array.add(value); } public static void delMail(valueBean value) { for(int i=0; i<array.size(); i++) { if(((valueBean)array.get(i)).getName().equals(value.getName())) array.remove(i); } } } package dispatcherView; import javax.servlet.http.HttpServletRequest; public class AccountingHelper { private static valueBean[] getMailList() { return businessService.getMailList(); } private static valueBean[] addMail(valueBean value) { businessService.addMail(value); return getMailList(); } private static valueBean[] delMail(valueBean value) { businessService.delMail(value); return getMailList(); } public static valueBean[] exec(valueBean value) { if(value.getDelegate() == null) return getMailList(); else if(value.getDelegate().equals("add")) return addMail(value); else if(value.getDelegate().equals("remove")) return delMail(value); else return null; } } package dispatcherView; import java.io.Serializable; public class valueBean implements Serializable { private String name; private String email; private int age; private String delegate; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getDelegate() { return delegate; } public void setDelegate(String delegate) { this.delegate = delegate; } } package dispatcherView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RequestHelper { private HttpServletRequest request = null; private HttpServletResponse response = null; public RequestHelper() { } public static String getDispatcherURL(HttpServletRequest request) { if(getRequestURL(request).equals("/accountDetail")) return "/view.jsp"; else if(getRequestURL(request).equals("/accountAdd")) return "/view.jsp"; else if(getRequestURL(request).equals("/accountRemove")) return "/view.jsp"; else return null; } public static String getRequestURL(HttpServletRequest request) { return request .getServletPath() .substring(request.getServletPath().lastIndexOf("/"), request.getServletPath().lastIndexOf(".")); } } package dispatcherView; import javax.servlet.*; import javax.servlet.http.*; import java.io.PrintWriter; import java.io.IOException; public class Controller extends HttpServlet { private static final String CONTENT_TYPE = "text/html; charset=EUC-KR"; public void init(ServletConfig config) throws ServletException { super.init(config); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doProxy(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doProxy(request, response); } protected void doProxy(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { dispatch(request, response, RequestHelper.getDispatcherURL(request)); } protected void dispatch(HttpServletRequest request, HttpServletResponse response, String page) throws ServletException, IOException { RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(page); dispatcher.forward(request, response); } } view.jsp <%@ page contentType="text/html;charset=EUC-KR"%> <%@ page import="dispatcherView.*"%> <jsp:useBean id="valueObject" class="dispatcherView.valueBean" scope="request"/> <jsp:setProperty name="valueObject" property="*"/> <% valueBean[] va = AccountingHelper.exec(valueObject); %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR"> <title>Dispatcher View Pattern</title> <SCRIPT> function reCall(mode) { var ff = document.form; form.delegate.value=mode; if(mode == 'add') ff.action = '<%=request.getContextPath()%>/accountAdd.ctr'; else ff.action = '<%=request.getContextPath()%>/accountRemove.ctr'; ff.method = 'post'; ff.submit(); } </SCRIPT> </head> <body> <P> <STRONG><FONT size="6">Dispatcher View Pattern</FONT></STRONG> </P> <hr/> <P> Total Num(<%=va != null ? va.length : 0%>) <BR/> <STRONG>Mail List</STRONG> </P> <table cellspacing="2" cellpadding="3" border="1" width="100%"> <tr> <td bgcolor="#cccccc"> <DIV align="center">Name</DIV> </td> <td bgcolor="#cccccc"> <DIV align="center">EMail</DIV> </td> <td bgcolor="#cccccc"> <DIV align="center">Age</DIV> </td> </tr> <% if(va != null) { for( int i = 0; i < va.length; i++ ) {%> <tr> <td> <DIV align="left"><%=va[i].getName()%></DIV> </td> <td> <DIV align="left"><%=va[i].getEmail()%></DIV> </td> <td> <DIV align="left"><%=va[i].getAge()%></DIV> </td> </tr> <% } } %> </table> <P> </P> <P> <STRONG>Insert & Delete</STRONG> </P> <form name="form"> <input type="HIDDEN" name="delegate"> <table cellspacing="3" cellpadding="2" border="1" width="100%"> <tr> <td width="15%">Name</td> <td width="85%"> <input type="text" name="name"/> </td> </tr> <tr> <td width="15%">EMail</td> <td width="85%"> <input type="text" name="email"/> </td> </tr> <tr> <td width="15%">Age</td> <td width="85%"> <input type="text" name="age"/> </td> </tr> <tr> <td width="15%"> </td> <td width="85%"> <input type="BUTTON" name="addMail" value="Add Mail" omclick="reCall('add');"> <input type="BUTTON" name="delMail" value="Del Mail" omclick="reCall('remove');"> </td> </tr> </table> </form> <P> </P> </body> </html> |
'Programming > Design Pattern' 카테고리의 다른 글
[펌] The Data Access Object pattern (0) | 2006.01.21 |
---|---|
[펌] The Service-to-Worker pattern (0) | 2006.01.21 |
[펌] The Data Access Object pattern (0) | 2006.01.21 |
[펌] The Value Object(Transfer Object) pattern (0) | 2006.01.21 |
[펌] The Interception Filter Pattern (0) | 2006.01.21 |