MVC
JSP 모델1
JSP 모델2
디자인 패턴
이 그림은 사용자의 요청이 처리되는 순서로 생각하면서 위에서부터 아래로 보면 된다. 가장 윗 부분은 프리젠테이션 티어이고, 중간 부분은 비즈니스 티어, 하단 부분은 인테그레이션 티어이다. 위에 갈수록 화면에 가깝고, 아래로 갈수록 DB와 같은 저장소에 가깝다고 생각하면 된다. 각 패턴의 특징을 간단히 알아보면 다음과 같다.
여기서 Service to Worker 패턴과 Dispatcher View 패턴이 의미가 비슷하여 혼동될 수 있는데, 클래스 다이어그램을 보면 다음과 같은 차이가 있다.
위의 다이어그램을 보면, Dispatcher View 패턴은 Helper 클래스를 직접 컨트롤하지 않는다는 차이가 있다.
위에 명시된 패턴 중 성능과 관련된 패턴은 무엇일까? 패턴은 모두 직간접적으로 성능과 관려이 있는데, J2EE 패턴 중 성능과 가장 밀접한 패턴은 Service Locator 패턴이다. 그리고 성능에 직접적으로 많은 영향을 미치지는 않지만, 애플리케이션 개발 시 반드시 사용해야 하는 Transfer Object 패턴도 짚고 넘어가야 한다.
적어도 위 패턴에서 Business Delegate, Session Facade, Data Access Obejct, Service Locator, Transfer Object 패턴에 대해서 알아야 한다. 이 중 성능과 관련이 있는 Tranfer Object, Service Locator 패턴에 대해서 알아보자.
Value Object라고 불리는 Transfer Object는 데이터를 전송하기 위한 객체에 대한 패턴이다. 먼저 Tranfer Object 예제 소스 코드를 보자.
package com.perf.pattern;
import java.io.Serializable;
public class EmployeeTO implements Serializable {
private String empName;
private String empID;
private String empPhone;
public EmployeeTO() {
super();
}
public EmployeeTO(String empName, String empID, String empPhone) {
this.empName = empName;
this.empID = empID;
this.empPhone = empPhone;
}
public String getEmpName() {
if(empName==null) return "";
else return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpID() {
return empID;
}
public void setEmpID(String empID) {
this.empID = empID;
}
public String getEmpPhone() {
return empPhone;
}
public void setEmpPhone(String empPhone) {
this.empPhone = empPhone;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("empName=").append(empName).append("empID=").append(empID)
.append( " empPhone=").append(empPhone);
return sb.toString();
}
}
그렇다면 이 Transfer Obejct를 사용한다고 성능이 좋아질까? 이 패턴을 사용한다고 애플리케이션에 엄청난 성능 개선 효과가 발생하는 것은 아니다. 하지만 하나의 객체에 결과 값을 담아올 수 있어 두 번, 세 번씩 요청을 하는 일이 발생하는 것을 줄여주므로, 이 패턴을 사용하기를 권장한다.
package com.perf.pattern;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.naming.InitialContext;
public class ServiceLocator {
private InitialContext ic;
private Map cache;
private static ServiceLocator me;
static {
me = new ServiceLocator();
}
private ServiceLocator() {
cache = Collections.synchronizedMap(new HashMap());
}
public InitialContext getInitialContext() throws Exception {
try {
if (ic == null) {
ic = new InitialContext();
}
} catch (Exception e) {
throw e;
}
return ic;
}
public static ServiceLocator getInstance() {
return me;
}
// ... 지면상 생략
}
Service Locator 패턴은 예전에 많이 사용되었던 EJB의 Home 객체와 DB의 DataSource를 찾을 때(lookup 할 때) 소요되는 응답 속도를 감소시키기 위해서 사용된다. 위의 소스를 간단히 보면, cache라는 Map 객체에 home 객체를 찾은 결과를 보관하고 있다가, 누군가 그 객체를 필요로 할 때 메모리에서 찾아서 제공하도록 되어 있다. 만약 해당 객체가 cache라는 맵에 없으면 메모리에서 찾는다.
참고