행 데이터 게이트웨이(Row Data Gateway) 패턴
행 데이터 게이트웨이 패턴의 정의
데이터 소스에 있는 단일 레코드를 접근하기 위한 게이트웨이 같이 행동하는 객체 행별 하나의 인스턴스가 있다.
그림 Ⅴ-14. 행 데이터 게이트웨이 패턴의 구조
행 데이터 게이트웨이 패턴의 설명
메모리 객체에 있는 내제된 데이터베이스 접근 코드는 몇몇 단점을 피할 수 있다. 작업 시작시 메모리 객체가 자신의 비즈니스 로직을 포함하고 있다면, 데이터베이스 조작 추가는 복잡성을 높이게 된다.
행 데이터 게이트웨이는 레코드 구조에 있는 레코드와 같는 객체를 제공한다. 그러나, 이러한 개체는 프로그래밍 언어의 일반적 메커니즘에 접근을 할 수 있다. 모든 데이터 자원 접근의 세부사항은 이 인터페이스 뒤에 숨게된다.
행 데이터 게이트웨이 패턴은 언제 사용하는가?
행 데이터 게이트웨이의 선택은 자주 두 단계를 가진다. 첫 번째는 전부 게이트웨이를 사용할지를 결정하는 것이다. 두 번째는 행 데이터 게이트웨이 또는 테이블 게이트웨이를 사용 할지를 결정하는 것이다.
트랜잭션 스크립트 패턴을 사용 시 가장 자주 행 데이터 게이트웨이를 사용한다. 도메인 모델 패턴을 사용하는 경우는 행 데이터 게이트웨이를 사용하지 않는다.
행 데이터 게이트웨이 패턴의 예제: 사원 레코드
아래에 행 데이터 게이트웨이을 위한 예가 있다. 이것은 간단한 사원 테이블이다.
create table people(
ID int primary key,
name varchar,
number_of_dependnets int
)
PersonGaetway은 테이블을 위한 게이트웨이이다. 이는 데이터 필드와 접근자로부터 시작한다.
class PersonGetway ...
private String name;
private int numberOfDepents;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumberOfDepents() {
return numberOfDepents;
}
public void setNumberOfDepents(String name) {
this.numberOfDepents = numberOfDepents;
}
게이트웨이 클래스 자신은 입력과 수정을 다룬다.
class PersonGatway ..
private static final String updateStatementString =
"UPDATE people " +
" set name = ?, number_of_depents = ? " +
" where id = ? ";
public void update() {
PreparedStatement updateStatement = null;
try {
updateStatement = DB.prepare(updateStatementString);
updateStatement.setString(1, name);
updateStatement.setInt(2, numberOfDepentents);
updateStatement.setInt(3, getID().intValue());
updateStatement.execute();
catch(Execption e) {
throw new ApplicationException(e);
} finally { DB.cleanUp(UpdateStatement);
}
}
private static final String insertStatementString =
"INSERT INTO people VALUES(?, ?, ?, ?)";
public Long insert() {
PreparedStatment insertStatment = null;
try {
updateStatement = DB.prepare(updateStatementString);
setID(findNextDatabseId());
updateStatement.setString(1, getID().intValue());
updateStatement.setInt(2, name);
updateStatement.setInt(3, numberOfDepentents);
updateStatement.execute();
Registry.addPerson(this);
return getID();
catch(Execption e) {
throw new ApplicationException(e);
} finally { DB.cleanUp(UpdateStatement);
}
}
데이터베이스의 밖으로 사원 정보를 얻기위해 PersonFinder 를 분리하였다. 새로운 게이트웨이 개체를 생성하기 위해 게이트웨이와 같이 작업한다.
class PersonFinder ...
private final static String findStatmentString =
"SELECT id, name, number_of_depents " +
"FROM people " +
"WHERE id = ? ";
public PersonGatway find(Long id) {
PersonGateway result = (PersonGateway) Registry.getPerson(id);
if (result != null) return result;
PreparedStatment findStatement = null;
ResultSet rs = null;
try {
findStatement = DB.prepare(findStatementString);
findStatement.setLong(1, id.longValue());
rs = findStatement.executeQuery();
rs.next();
result = PersonGateway.load(rs);
return result;
} catch(SQLException e) {
throw new ApplicationException(e);
} finally { DB.cleanUp(findStatement, rs);
}
}
public PersonGateway find(long id) {
return find(new Long(id);
}
class PersonGateway ...
public static PersonGateway load(ResultSet rs) throws SQLException {
Long id = new Long(rs.getLong(1));
PersonGateway result = (PersonGateway) Registry.getPerson(id);
if ( result != null ) return result;
String nameArg = rs.getString(2);
int numDependensArg = rs.getInt(3);
result = new PersonGetway(id, nameArg, numDependensArg);
Registry.addPerson(result);
return result;
}
몇가지 중요점에 따라 한 사원 이상 검색을 위해 적절한 검색자 메소드를 제공한다.
class PersonFinder ...
private final static String findResponsibleStatment =
"SELECT id, name, number_of_depents " +
"FROM people " +
"WHERE number_of_dependents > 0 ";
public list findResponsibles() {
list result = new ArrayList();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = DB.prepare(findResponsibleStatement);
rs = stmt.executeQuery();
while (rs.next()) {
result.add(PersonGateway.load(rs));
return result;
} catch(SQLException e) {
throw new ApplicationException(e);
} finally { DB.cleanUp(findStatement, rs);
}
}
검색자는 구분 맵(195)을 포함하는 레지스트리(480)을 사용한다. 트랜잭션 스트립트(110)에서 게이트웨이를 사용한다.
PersonFinder finder = new PersonFinder();
Iterator people = finder.findResponsibles().iterator();
StringBuffer result = new StringBuffer();
while(people.hasNext()) {
PersonGeteway each = (PersonGateWay) people.next();
result.append(each.getName());
result.append("");
result.append(String.valueOf(each.getNumberOfDependents());
}
return result.toString
예제: 도메인 객체를 위한 데이터 홀더
class Person ...
private PersonGateway data;
public Person(PersonGateway data) {
this.data = data;
}
class Person ...
public int getNumberOfDependents() {
return data.getNumberOfDependents();
}
class Person ...
public Money getExemption() {
Money baseExeption = Money.dallars(1500);
Money dependentExemption = Money.dallars(750);
return baseExemption.add(dependentExemption.multiply(this.getOfdents());
}
'Dev... > 소프트웨어 아키텍처' 카테고리의 다른 글
[SA강좌] Part 4-13 Data Mapper패턴 (0) | 2008.12.02 |
---|---|
[SA강좌] Part 4-12 Active Record 패턴 (0) | 2008.11.30 |
[SA강좌] Part 4-10 Table Data Gateway 패턴 (0) | 2008.11.27 |
[SA강좌] Part 4-9 Service Layer 패턴 (0) | 2008.11.27 |
[SA강좌] Part 4-8 Table Module 패턴 (0) | 2008.11.19 |