Framework/Database2009. 2. 20. 15:59

실험실 코드와 비실험실 코드를 분리한 후 가장 지켜야 할 원칙은 절대로 비실험실은 실험실 코드는 서로 관련이 없어야 한다는 것이다. (양방향성이다.)

이를 조금 더 확대하면 DB라는건 하나의 서비스이고 개발자가 만드는 제품도 하나의 서비스 이기 때문에 개발자가 만드는 제품은 DB를 개체로서의 DB가 아니라 개념으로서의 DB로 다루어야 한다.

추상적으로 A서비스와 B서비스가 있다고 할때 A서비스는 B서비스로 request를 하고 B 서비스는 A 서비스로 response를 한다. 이때 request와 response는 중립적인 메시지 형태가 되어야 하며 A.request는 B의 내부에 대해서 몰라야 하며 B.response는 A의 내부에 대해서 모르며 동시에 자기의 정체를 상세히 알려줘서는 안된다.

첫번째 A.request가 중립적인 메시지가 되기 위해서는 그리고 B가 개념으로서의 DB로 다루어질려면 request에는 개체로서 다루게 되는 select 문이나 clob 혹은 PrepareStatement 같은게 나와서는 안된다. 이야기가 다소 혼란이 있을지 모르므로 다시 앞에서 말한 "블랙박스처럼 DB를 다뤄라"와 비교를 해보자

먼저 객체지향의 개념과 개체의 구분을 해보자. 살고 있는 집에서 조금 떨어진 거리에 가끔 나가서 사먹는 붕어빵 파는 아저씨가 있다. 이때의 붕어빵은 개념이고 지금 밖에서 나가서 사온 지금 내 손에 들고 있는 따끈따근한 붕어빵은 개체다. Class와 Instance는 객체지향의 기본이니 별로 새삼스러울것도 없겠지만 이를 서비스에 적용해 보자.

블랙박스로서의 DB가 잘못됐다고 하는 이유는 DB를 개체로 다루되 개체의 특성- 이를테면 Procedure등을 사용하지 말고 Ansi SQL을 사용하라 - 을 무시하라가 그 주장이기 때문이다. 그러나 개념으로서의 DB 접근은 좀더 본질적이다.

비실험실인 서비스 코드에서 Select * From emp와 같은 SQL 문장이 나와서는 안되는 이유는 바로 Select문 자체가 개체로서의 DB에 접근하기 때문이다. 개념으로서의 DB는 데이타 저장 시스템일뿐이어야 하는데 위 간단한 SQL은 emp라는 테이블이 있는 바로 지금 옆에 설치되어 있는 DB 개체로 인식하고 있다.

프레임워크인 실험실 코드가 해야 할 일은 그래서 명백하다. A.request와 B.response의 중립적인 개념 코드(응?)를 해석해 주는 중간 레이어의 역할이다. 사실 컴퓨터 자체가 해석기관이고 랭귀지도 사람과 컴퓨터간의 해석 기관이라는 재귀적 관점에서 보면 프레임워크란 추상화 정도를 줄인 해석기관이라고 간주해도 크게 벗어나지 않는다.

package com.bleujin.framework.db.procedure;

import com.bleujin.framework.DBTestCase ;
import 
com.bleujin.framework.db.DBController;
import com.bleujin.framework.db.Rows;

public class TestLobTest extends DBTestCase{
  
  public void testDefault() throws Exception {
    // example 1
    
IUserProcedure u1 = dc.createUserProcedure("emp@add(?,?)";
    u1.addParam(110).addParam("bleujin";
    dc.execUpdate(u1;

    // example 2
    IUserProcedure u2 = dc.createUserProcedure("emp@list()";
    Rows rows = dc.getRows(u2;
    while(rows.next()){
       rows.getString("name";
    }
  }
}


위 코드는 DBFramework를 사용한 전형적인 예제이다. 먼저 A.request는 emp@add(?,?) 등의 중립적인 String으로 전달되고 있다. emp@add(?,?)를 어떻게 해석하는가는 실험실 코드인 DBManager 이하에서 결정할 문제일뿐 현재 서비스코드에서는 그에 대해 알 필요가 없다. 단지 실험실 바깥의 서비스 코드에서는 인자 2개를 셋팅한 UserProcedure를 호출했을 뿐이다.

두번째 예제에서 response인 Rows를 보면 JDBC의 ResultSet하고 닮긴 했지만 인터페이스만 공유할뿐 close를 호출해줘야 한다든가 예외처리를 해줘야 하는 책임이 없다. 사실 그냥 내부구조는 Map 형태의 일반 객체이기 때문이다. 일반적으로 JDBC의 ResultSet은 예외 처리와 적절한 시점에 close의 호출에 신경을 써야 하기 때문에 중립적인 메시지라고 보기 어렵다.

여기서는 DB를 순수 개념으로서의 Repository Service로서만 다룰뿐 실제의 개체는 모두 숨겨져 있다. 실제 개체로서의 DB는 바깥의 서비스에서는 알필요가 없는 것이다.


'Framework > Database' 카테고리의 다른 글

Framework (DBManager)  (0) 2009.03.04
Framework (구조적 중복 제거)  (0) 2009.02.21
Framework (개요)  (0) 2009.02.20
Framework (블랙박스 증후군)  (0) 2009.02.07
Framework (커서)  (0) 2009.01.12
Posted by bleujin