태그 : java

자바용 Active Record 기획안

설  연휴 전날 몇몇 회사 동료와 야근을 하려고 식사를 하던 중 그냥 일찍(?) 나가서 얘기나 하다 집에 가기로 의기투합하여 회사를 나왔다. 2차까지 가며 (1차는 별다방, 2차는 덩킨도넛... 꼭 알콜이 있어야 한다는 편견은 버리삼) 이런 저런 얘기를 하던 중 평소 궁금했던 것을 물어봤다.

"자바용 Active Record를 만들면 좋을지 모르겠는데 어떻게 생각해?"

한동안 이 문제로 고민을 해왔다. 이미 iBatis와 Hibernate같은 유명 인사가 있고 이 외에도 수많은 ORM 도구와 추상화 솔루션이 있는 상황에서, 그리고 우리의 완소 JDBCTemplate가 든든하게 뒷받침을 하고 있는데 Active Record를 따로 만드는 것이 의미 있는지 판단이 잘 서지 않았다. 아무리 Dynamic Proxy를 쓴다고 해도 최소한 인터페이스는 일일이 만들어 만들어줘야 하는 자바에서  생산성을 어느 정도 높일 수 있을지도 의문이었고 어떻게 보면 ORM을 사용하면서 도메인을 DB Table과 1:1로 대응하게 하면 그것에 곧 Active Record와 다를 바 없는 것 아닌가 생각되었기 때문이다.

그런데 동료들은 꼭 필요하다며 이런저런 이유를 늘어놓더니 결국 내 마음에 불을 질러 놓았다. 집에 오며 한 시간 넘게 생각을 해보니 대략 윤곽이 떠올라서 간단히 기획안을 적어본다.

배경

왜 Active Record가 필요할까? 솔직히 말하면 내가 필요하기 때문이다. 난 아직도 ORM을 쓰지 않는다. 더 정확히 말하면 도메인 모델링을 하지 않는다. 도메인 객체가 있기는 하지만 DB 구조를 반영해서 만들어진다. 여전히 모델링 단계에서 DB 설계를 먼저 하고 있고 DBMS의 고유 기능을 사용하는데 익숙하며 두꺼운 추상화 레이어를 두는 것에 막연한 두려움을 느끼고 있다.

무엇보다 프로젝트를 하다 보면 필연적으로 프리렌서와 함께 일을 하게 되는데 배우는데 비용이 많이 드는 기술 때문에 프로젝트에 엄청난 피해를 봤던 경험이 너무 많다. 반면에 롤을 세분화 하기에는 프로젝트 규모가 작다. 대부분 개발자 2-5명이 2-3개월 안에 완료해야 한다. 신입사원 교육 비용도 만만하지 않다.

모 은행 개발 프로젝트에 잠시 투입되었었는데 그 은행에서는 DB 추상화 레이어로 ORM과 SQL Mapper를 준비해 두었다고 한다. 권고하는 것은 ORM이지만 ORM으로 개발하도록 요구했더니 개발자들이 진행을 하지 못해서 결국 SQL Mapper를 추가로 제공할 수 밖에 없었고 대부분 어플리케이션이 SQL Mapper를 사용해서 개발이 되었다고 한다. (나는 iBatis와 jdbcTemplate는 개발 비용이 비슷하고 디버깅은 jdbcTemplate이 쉽다고 생각한다. 적절한 Query Object를 사용하면 동적 SQL 문제도 해결된다.)

마틴 파울러는 개발자들이 SQL을 어려워하고 DB보다 객체 다루기를 더 쉽게 생각하고 있다면서 Domain model과 ORM을 추천하지만 우리나라 개발자들은 DB와 SQL에 친숙한 것 같다. 아직 OOD로 넘어오지 못한 것 같다는 생각이다. 결국 DB를 원본으로 하고 DB와 1:1 구조를 가지고 있으면서 비즈니스 로직을 객체에 분산시키는 Active Record가 필요하다고 판단이 된다.

이런 이유로 프로젝트 이름을 'Last exit for the DB believers'라고 하면 어떨까 생각도 해보았다. (물론 농담이다. ㅡ.ㅡ);

목표 사양
  • Spring jdbcTemplate와 함께 사용한다. (ActiveRowMapper 지원)
  • CoC에 따라 table과 class를 맵핑하되 애노테이션으로 설정할 수 있다.
  • Relationship 지원 belong to, has many (many-to-many 포함) 지원
  • DB schema 자동인식
  • lazy load 지원
  • paging 지원
  • clob/blob 지원
  • criteria 지원
  • 필드 변경 여부 자동인식
아직 생각하지 않는 것
  • join
  • aggregation
  • data cache
  • cascade

by 박성철 | 2008/02/07 13:33 | 프로그래밍 이야기 | 트랙백(1) | 덧글(14)

Spring Dynamic Module 1.0 발표를 환영하며...

미국 시간 2008년 1월 25일 11시 25분에 스프링 프레임웍 홈페이지에 Spring Dynamic Module(지금까지 Spring OSGi라고 부르던 프로젝트의 정식 명칭) 1.0 발표 공지가 올라왔습니다. 매우 관심이 많이 가는 프로젝트입니다. 제가 보수적인 성향이 있어 보통 버전이 2.0 이상은 되야 겨우 검토하는 편이지만 이 프로젝트는 빨리 적용해보고 싶네요.

저는 스프링 프레임워크를 쓰기 전에 아파치 프로젝트 중 하나인 아발론 프레임워크를 사용했었습니다. 지금은 프로젝트가 중단되었고 Excalibur라는 후계자에 의해 명맥을 유지하고 있습니다.

제가 아발론을 사용했던 이유는 아파치의 Java Mail Server 프로젝트인 James를 기반으로 작업 할 일이 있었는데 이 James가 아발론을 사용해서 만들어졌기 때문입니다. 지금 제 작업물에는 James가 이제 남아 있지 않고 최근에는 아발론도 스프링프레임워크로 교체하고 있습니다. 아발론 프로젝트가 더는 진행 되고 있지 않는 문제도 있고 이 코드를 다른 개발자들과 함께 유지 보수하려면 스프링 프레임워크가 더 유리할 것 같기 때문입니다. 제가 스프링을 쓰고 싶기도 하구요. (사실 James 메일링 리스트에서도 한동안 스프링으로 James를 포팅하는 건에 대한 논의가 있었습니다. 아발론을 계속 쓰는 것으로 결론이 나기는 했지만 불씨는 여전히 남아 있다고 생각합니다.)

그런데 아발론과 스프링은 둘 다 IOC 컨테이너라고 분류될 수 있으면서도 개념이 아주 다른 프레임워크입니다. 물론 이 시점에서 스프링이 단순한 IOC 컨테이너가 아니라는 것은 알고 있다고 한마디 하고 넘어가야 할 것 같네요. 아발론도 단순한 IOC 컨테이너만은 아닙니다만... ㅎㅎ

아발론과 스프링의 차이점을 전부 비교할 생각은 없습니다. 제가 말하고 싶은 부분은 하나인데요. 아발론은 컴포넌트 수준에서의 IOC를 생각하고 만들어졌습니다. 반면에 스프링은 컴포넌트와 객체의 구별이 없습니다. 메뉴얼에서도 컴포넌트, 빈, 객체라는 서로 다른 용어가 섞여서 사용되는듯 합니다. 그래서 아발론을 먼저 사용했던 저는 처음에 스프링을 접하면서 어떤 수준에서 스프링 컨테이너에 객체 관리를 위임해야 할지 결정하기 참 어려웠습니다. 너무 많은 것을 스프링에 등록하는 것 아닌지 걱정도 들었구요.

그럼 객체와 컴포넌트는 어떻게 다른 것일까요? 아발론에서는 컴포넌트를 PC 슬롯에 설치하는 Add-On 보드로 비유합니다. VGA 카드나 사운드 카드 같은 확장 보드 말이죠. 반면에 객체는 그 보드를 만드는 데 사용된 칩이나 전자 부픔으로 얘기합니다. 즉 하나 이상의 객체가 모여서 어떤 기능을 하는 단위 모듈을 만들게 되면 그것을 컴포넌트라고 부르는 것이죠. 아발론에서는 객체들을 어떻게 구성해서 블럭(아발론에서 컴포넌트를 블럭이라고 함)를 만드는지는 관여하지 않습니다. 다만 이 블럭(컴포넌트)들을 관리해 줄 뿐이죠.

잠시 딴 얘기를 해보면... 제 생각에 요즘은 Java Bean이 실행 시 관리 유용성 때문에 필요 이상으로 많이 사용되는 것 아닌가... 그래서 자바 개발자들이 컴포넌트라는 개념을 잘 못 이해하고 있는 것 아닌가... 하는 생각을 하게 됩니다. 그래서 자바 바이트 코드 조작을 통한 객체 관리 방식이 자바 빈을 사용한 것보다 좋게 생각되구요. 좌우간....

다시 아발론을 정리를 하면 아발론은 컴포넌트(블럭)들을 관리하는 IOC 컨테이너로써 컴포넌트들의 라이프사이클을 관리하고 이 컴포넌트가 제공하는 서비스를 기반으로 통합 운영 환경을 제공합니다. 어떤 컴포넌트를 등록하면서 이 컴포넌트가 어떤 버전의 서비스에 종속되어 있는지 표기를 하면 그 서비스를 제공하는 컴포넌트를 찾아서 알려줌으로써 컴포넌트끼리 서로를 찾아서 한 시스템으로 운영되도록 해주는 것입니다.

아마 OSGi에 관심이 있는 분이라면 방금 제가 한 아발론의 설명이 친숙하다고 생각되실 것입니다. OSGi가 제공하는 환경이 바로 컴포넌트 기반의 서비스 지향 환경이기 때문입니다. Spring Dynamic Module을 사용하면 각각 독립된 Spring Application Context를 가지고 있는 모듈들을 한 OSGi 플랫폼 위에 설치하고 이 모듈들이 서로 자기가 필요한 서비스를 제공하는 다른 모듈들을 찾아서 사용할 수 있게 됩니다. HiveMind가 스프링에 비해서 장점이라고 얘기하던 부분이 이렇게 여러 어플리케이션을 한 프레임워크 위해서 동시에 운영할 수 있다는 것이었는데 OSGi를 통해서 스프링도 대규모 서비스 지향의 시스템을 구성할 수 있게 된 것입니다. 더 뛰어난 환경에서 말입니다.

어떤 분은 Application Context를 계층화해서 모듈은 자신만의 자식 Application Context을 개별적으로 구성하고 부모 Application Context로 이들을 통합하면 되지 않겠냐고 하실텐데 저도 그렇게 구성하려고 생각하고 보니 자식 Application Context에 등록되어 있는 빈들은 다른 자식 Application Context의 빈들을 찾지 못하더군요. 그래서 일종의 서비스 저장소 같은 공간을 따로 만들어서 그 곳에 각 모듈들이 자신의 서비스와 리퍼런스를 등록하고 자신이 필요로 하는 서비스가 있으면 이곳에서 직접 찾아서 가지고 가도록 해야만 했습니다. 결국 나중에는 자식 Application Context들을 다 하나로 통합해서 한 Application Context로 만들고 DI를 하도록 바꾸었구요.

솔직히 일반적인 웹 어플리케이션을 개발하면서 OSGi를 쓸 일이 얼마나 있을지는 모르겠습니다. 금융권처럼 일부 비지니스적으로 민감한 경우가 아니라면 말이죠. 하지만 저처럼 서버 프로그램을 개발하는 입장에서는 무척이나 반가운 선물입니다. 물론 당장은 제 업무에 이 이쁜 놈을 적용하지 못하겠지만 하루 빨리 써보고 싶은 마음이 간절합니다. 원래 이것이 없었으면 Jboss의 JMX 기반 서비스 지향 아키텍쳐를 써 볼 생각도 했었거든요.

이번 JCO 자바 개발자 컨퍼런스에서 가장 기대되는 부분 역시 Epril 대표 이일민님의 Spring OSGi 세션입니다.

참고로 제 코드처럼 아발론을 썼다가 최근에 스프링프레임워크로 바꾸는 프로젝트가 있습니다. 아실만한 분은 다 아실 아파치 Cocoon 입니다. 아마 OSGi를 사용하지 않을 것으로 보이지만 혹시 스프링을 사용해서 컴포넌트 기반의 시스템을 어떻게 개발하는지 관심이 있으시다면 대충 살펴보는 것도 좋을 듯싶습니다. 저는 너무 많이 포팅 작업을 진행했기 때문에 이 프로젝트에서 도둑질 할 것이 얼마 없을 것 같네요. 좀 일찍 알았으면 도움이 되었을 듯 한데 말이죠. 쩝.

by 박성철 | 2008/01/29 04:57 | 프로그래밍 이야기 | 트랙백(2) | 덧글(4)

Allman 식 이클립스 Java 코딩 스타일 프로파일

어떤 자바 코딩 스타일을 쓰시고 계신가요?

특별히 선호하는 스타일이 없으시다면 아마도 자바 코딩 규약을 따르시겠죠?

코딩 스타일이라고 하면 여러 가지가 고려할 것들이 있습니다. 들여쓰기를 어떻게 하는지, 블럭 지정은 어떻게 하는지, 언제 줄을 나눌 것인지, 띄어쓰기, 코멘트, 배열 초기화, 심지어 이름 정하는 규칙까지......

이런 여러 요소가 있지만 보통 코딩 스타일을 분류할 때에는 들여쓰기와 블럭 표현 방법을 주로 봅니다. 아마도 이 두 가지가 코딩 스타일의 외형에 가장 큰 영향을 주기 때문인 듯합니다. 몇몇 대표적인 블럭 표현 방법에는 따로 부르는 이름까지 붙어 있지요.

제가 프로그래밍을 배우기 시작할 때에는 베이식, 어셈블리, 포트란, 코볼 같은 언어들을 주로 사용했기 때문에 요즘과는 다른 코딩 스타일을 썼었습니다. 언어 구조가 좀 다르니까요. 제가 배운 베이식은 서브루틴 같은 것도 없었거든요. ^^

처음으로 배운 구조적 언어는 Pascal입니다. Apple II에서 돌아가는 UCSD Pascal이 있었는데 p-System이라는 가상 머쉰 위에서 p Code라는 중간 코드로 컴파일 되는 언어입니다. 지금 우리가 쓰는 자바 가상 머쉰과 비슷한 놈이었죠. 좀 다른 것은 JVM은 OS 위에서 돌아갔지만 p-System은 OS까지 포함하고 있습니다. 그다음에는 CP/M이라는 OS에서 Turbo Pascal로 프로그래밍을 했었고요.

좌우간 이런 이유로 Pascal처럼 블럭의 시작과 끝이 명시적인 Allman 스타일의 블럭 표현 방법을 선호하게 되었나 봅니다. K&R 스타일은 블럭의 시작 기호와 끝 기호를 신경 써서 주목하지 않으면 찾기가 힘들더라고요. 물론 요즘은 IDE를 쓰기 때문에 자동으로 찾아주기는 하지만 최근까지 VI로 개발했었기 때문에 이 스타일이 아니면 코드를 전혀 보지 못하는 지경입니다.

대표 Indent Style

말을 시작했으니 대표적인 코딩 스타일을 몇 가지 적어볼까요? 마침 위키 백과에 잘 정리가 되어 있군요.

K&R 방식

for (int i = 0; i < 10; i++) {
    s = s + i;
    if (s > 10) {
         ......
    } else {
         ......
}

자바 코딩 규약에서 사용하는 방식입니다. 우리나라에서는 이것이 가장 일반적인 듯합니다. C를 만든 커닝핸과 리치씨의 "The C Programming language"라는 책에 사용된 코딩 스타일이지요. 이 책 한 권씩 안 사본 사람이 없을 듯한데 요즘은 모르겠군요. 제가 처음으로 산 원서 같기도 하고...... 들여쓰기는 원래 8칸이지만 요즘은 4칸을 주로 씁니다.

이것의 변형으로 BSD KNF Style이 있다네요. 보통 kernel style이라고 부르는 놈입니다. 저는 이것과 K&R이 같은 것인 줄 알았는테 텝이 조금 다르군요. 하드 탭(탭문자)는 8칸으로 보이게 설정하고 소프트 탭(어이지는 공백 여러개로 탭을 표현)은 공백 4개로 설정합니다. 밑에 제 스크린샷 중 첫번째에서 Tab Policy를 Mixed로 하고 Use tabs only for leading indentations를 체크한 후에 블럭 들여쓰기 할 때에 tab을 두번 치면 비슷해질 듯 하네요.

이렇게 탭을 설정하고는 블럭을 들여쓸 때에는 하드탭으로 이어지는 줄을 들여쓸 때에는 소프트탭으로 처리한다고 합니다.

Allman 방식

for (int i = 0; i < 10; i++)
{
    s = s + i;
    if (s > 10)
    {
         ......
    }
    else
    {
         ......
    }
}

Sendmail과 많은 BSD 유틸리티들을 만든 Eric Allman의 코딩 스타일입니다. BSD Style이라고도 불렀었습니다. 원래는 들여쓰기를 공백 8칸으로 하는데 요즘은 4칸으로 합니다.

보시면 알겠지만 블럭의 시작과 끝이 명확합니다. 가독성이 높지요. 코드 한 줄씩 정확히 볼 수 있습니다. 단 한 화면에 보이는 코드 양이 많지 않아서 스크롤을 더 해야 하는 단점도 있습니다. 그래서 Cut & Paste 방식의 프로그래밍을 방해해서 저는 좋은데 다른 분들은 모르겠군요.

C에서는 가장 많이 사용하는 방식이라고 합니다.

Whitesmith 방식

for (int i = 0; i < 10; i++)
    {
    s = s + i;
    if (s > 10)
        {
         ......
        }
    else
        {
         ......
        }
    }


Whitesmith C라고 한참 잘 팔리던 C 컴파일러의 코딩 방식입니다. 저는 이 방식으로 코딩하는 사람을 한 번도 못 봤지만 Whitesmith C로 장난질을할 때에 잠깐 접해 보기는 했습니다. 어떻게 보이시나요? Allman 방식에 눈이 익어서 처음에는 적응하기 어렵지만 금방 적응이 되더군요.
이 방식 역시 원래 8칸이었지만 요즘은 4칸을 씁니다.
Allman 방식과 거의 비슷한 수준으로 많이 쓴다고 합니다.

GNU 방식

for (int i = 0; i < 10; i++)
  {
    s = s + i;
    if (s > 10)
      {
         ......
      }
    else
      {
         ......
      }
 }

GNU에서 사용하는 방식입니다. 아마도 리처드 스톨만의 방식이겠죠? Allman과 Whitesmith의 중간형으로 보입니다. 나름의 이유가 분명히 있겠지만 솔직히 전 이 방식을 별로 좋아하지 않습니다.  이렇게 작은 들여쓰기가 반복되면 가독성이 떨어지더군요. 눈이 어지럽습니다. 보통 2칸씩 두 번 들여씁니다.

위키 백과에는 pico 방식과 banner 방식도 설명하고 있는데 이것들은 그렇게 많이 쓰이지 않으므로 넘어가겠습니다.

이클립스 자바 코드 스타일 프로파일

좌우간 제가 이 글을 쓴 이유는 이런 방식 중에 제가 쓰는 allman 방식의 이클립스용 코딩 스타일 프로파일을 공개(?)하려는 것입니다.
혹시 allman 방식을 좋아하시는 분이 있다면 받아서 쓰세요. 제가 쓰던 것을 약간 손 봐서 올립니다.

allman.zip

이 파일을 내려 받아 압축을 푼 후에 이클립스의 자바 코드 스타일 프로파일로 등록 하십시오.

Window > Preferences > Java > Code Style > Formatter 에서 Import 하시면 됩니다.

설정 내용


간단히 설정 화면 갈무리한 것을 올려보겠습니다.

들여쓰기

들여쓰기는 공백 4칸입니다. 탭을 4칸으로 표시되도록 하는 방식은 다른 에디터에서 보면 다르게 보이기 때문에 탭은 8칸으로 보이게 했습니다.
저는 에디터를 고를 때에 들여쓰기를 탭 문자가 아닌 공백으로 처리할 수 있는지를 꼭 확인합니다.

대괄호

이 부분에서 Allman 방식의 대표 특징을 부여합니다.

빈 줄 삽입

널찍널찍한 코드가 가독성이 좋지요. ^^
가독성이 떨어지면 코드를 통제하기 힘들어지고 버그도 많이 생깁니다. cut & paste 해 놓고 "잘 돌아가던 코드인데 왜 안 돌아가지?" 하는 사람 많이 봤지요. 프로그래머는 코드 한 줄에 책임을 져야 하는 거라고 생각합니다. "네가 만들어 놓은 코드를 가져다 썼는데 작동 안 되니 네가 책임져"라고 말하는 프로그래머 보면 참 답답합니다. 자기가 제다이인 줄 알고 감으로 프로그래밍하죠.

줄 나누기

자바 코딩 규약과 비슷합니다. (아마도... ㅡ.ㅡ);


제어 코드

이 부분도 기본은 널찍널찍...


긴 줄 나누기

80칸에 맞춰서 긴 줄을 나누게 설정했습니다. 요즘은 화면이 넓으니 화면 가득한 크기로 에디터를 키우고 프로그래밍하는 사람들이 많습니다. 요즘 같은 시대에 누가 터미널을 쓴다고 80칸에 맞추느냐고 말하는 분들 많지요. 자바 코딩 규약에 쓰여 있는 것처럼 다양한 환경에서도 같은 모습을 유지하려면 80 칸에 맞추는 관례를 지키는 것이 좋기는 하지요.
저는 조금 다른 이유로 여전히 80칸에 맞춰서 코딩합니다. 가로로 길게 늘여 놓으면 눈에 잘 안 들어오기 때문입니다. 눈알을 이리저리 계속 굴려야 하거든요. 제가 노안이라서 그런가요? :-)
한번 해보세요. 진짜 코드에 대한 장악력이 높아집니다. 제 생각에 80칸 규칙을 에디터가 제한하도록 설정하는 것은 별로 좋은 것 같지는 않습니다. 어떤 줄은 이름이 너무 길다거나 해서 80칸을 넘는 것이 오히려 나을 수도 있으니까요. 그냥 기준선만 표시하고 프로그래머가 그런 습관을 지키도록 하는 것이 좋다고 생각되는데 일단 이 프로파일에서는 강제로 줄 나누기 하도록 했습니다.


주석 처리

이 부분은 그냥 제가 좋은 쪽으로 했는데 뭘 고쳤는지 모르겠네요.  ㅡ.ㅡ;


따~라 라~라 랄랄랄라 랄랄랄라~
따라라 라~라~ 라~



감사합니다. 혹시 문제가 있으면 리플 달아주세요.


by 박성철 | 2008/01/18 16:04 | 프로그래밍 이야기 | 트랙백(19) | 핑백(2) | 덧글(18)

◀ 이전 페이지다음 페이지 ▶