본문 바로가기

Dev.../소프트웨어 아키텍처

[SA강좌] Part 4-18 Dependent Mapping 패턴

의존 매핑(Dependent Mapping) 패턴

의존 매핑 패턴의 정의

의존 매핑 패턴은 자식 클래스를 위한 데이터베이스 매핑을 수행하는 하나의 클래스를 가진다.

그림 -24. 의존 매핑 패턴의 구조

 

의존 매핑 패턴의 설명

몇몇 개체들은 자연적으로 다른 개체의 컨텍스트에 나타난다. Album을 추적하면 album 진행시 적재되거나 저장될 때 적재되거나 저장된다. 데이터베이스에서 임의의 테이블에 의해서 참조되지 않는다면, 추적을 위한 매핑 수행을 하는 앨범 매퍼에 의해 매핑 절차를 단순화 할 수 있다. 의존 매핑은 매퍼로 처리한다.

의존 매핑 패턴은 언제 사용하는가?

다른 개체에 의해 참조되는 개체를 가지고 있으면 의존 매핑을 사용한다. 이경우 하나의 개체가 의존 집합을 가지고 있을 때 일반적으로 발생한다.

의존 매핑을 위한 사전 조건은 다음과 같다.

  • 의존은 반드시 한명의 소유자만 있어여 한다.
  • 의존을 위한 소유자 보다 임의 개체에서 참조가 없어야 한다.

의존 매핑 패턴의 예제: Album과 Tracks

아래의 그림과 같은 도메인 모델에서 Album은 Track들의 집합을 소유한다. 이 경우 간단한 애플리케이션은 Track를 참고하기 위한 어떤 것도 필요하지 않다. 의존 매핑을 위한 분명한 후보이다.

그림 -25. 의존 매핑 패턴의 예제

track은 단지 title만을 가진다. 아래에 클래스에 대한 정의가 있다.

 

class Track ...

 

private final String title;

public Track(String title) {

this.title = title;

}

 

public String getTitle() {

return title;

}

 

track들은 album 클래스 안에 포함된다.

 

class Album ...

 

private List tracks = new ArrayList();

public void addTrack(Track arg) {

tracks.add(arg);

}

public void removeTrack arg) {

tracks.remove(arg);

}

public void removeTrack(int i) {

tracks.remove(i);

}

public Track[] getTracks() {

return (Track[]) tracks.toArray(new Track[tracks.size()]);

}

앨범 매퍼 클래스는 트랙을 위한 모든 SQL를 조작하고, 트랙 테이블 접근을 하는 SQL 문을

저장한다.

 

class AlbumMapper ...

 

protected String findStatment() {

return

" SELECT ID, a.title, t.title as trackTitle" +

" FROM ablums a, tracks t " +

" WHERE a.ID = ? AND t.albumID = a.ID "+

" ORDER BY t.seq ";

트랙은 앨범이 적재될때 마다 앨범 안에 로딩된다.

 

class AlbumMapper ...

 

protected DomainObject doLoad(Long id, ResultSet rs) throws SQLException {

String title = rs.getString(2);

Album result = new Album(id, title);

loadTracks(result, rs);

return result;

}

public void loadTracks(Album arg, ResultSet rs) throws SQLException {

arg.addTrack(newTrack(rs));

while (rs.next()) {

arg.addTrack(newTrack(rs));

}

}

 

private Track newTrack(ResultSet rs) throws SQLException {

String title = rs.getString(3);

Track newTrack = new Track(title);

}

앨범이 모든 트랙이 업데이트 될때 삭제된다.

 

class AlbumMapper ...

 

public void update(DomainObject arg) {

PreparedStatment updateStatment = null;

try {

updateStatement = DB.prepare("UPDATE albums SET title = ? WHERE id = ?");

updateStatement.setLong(2, arg.getID().longValue();

Album album = (Album) arg;

updateStatement.setString(1, album.getTitle());

updateStatement.execute();

updateTracks(album);

} catch(SQLException e) {

throw new ApplicationException(e);

} finally { DB.cleanUp(updateStatement);

}

}

public void updateTracks(Album arg) throws SQLException {

PreparedStatement deleteTrackStatement = null;

try {

deleteTrackStatement = DB.prepare("DELETE from tracks WHERE albumID = ?");

deleteTrackStatement.setLong(1, arg.getID().longValue();

deleteTrackStatement.execute();

for (int i = 0; i < arg.getTacks().length; i++) {

Track track = arg.getTracks()[i];

insertTrack(track, i + 1, arg);

 

} catch(SQLException e) {

throw new ApplicationException(e);

} finally { DB.cleanUp(deleteTrackStatement);

}

}

public void insert(Track track, int seq, Album album) throws SQLException {

PreparedStatment insetTrackStatment = null;

try {

insetTrackStatment =

DB.prepare("INSERT INTO tracks(seq, albumID, title) VALUES(?,?,?)");

insetTrackStatment.setLong(1, seq);

insetTrackStatment.setLong(2, album.getID().longValue());

insetTrackStatment.setString(3, track.getTitle());

insetTrackStatment.exeute();

} catch(SQLException e) {

throw new ApplicationException(e);

} finally { DB.cleanUp(insetTrackStatment);

}

}