· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Enhanced PreferencesAPI


1. EnhancedPreferences API

Java 1.4 버전부터 포함된 java.util.prefs 유틸리티의 데이터 저장 공간을 유닉스의 디렉토리나 윈도우의 레지스트리가 아닌 다른 것으로 대체하기 위한 패키지 입니다.

2. 배경 지식


2.1. Preferences API


preferences의 사전적 의미는 다음과 같습니다.
when you like something or someone more than another person or thing
an advantage which is given to a person or a group of people

자바에는 데이터 저장을 위해 사용하는 여러가지 API들이 있습니다. 그중에 프로그램의 설정정보를 어딘가에 저장하려고 할때 사용할 수 있는 클래스는 Properties 클래스입니다. 이후 JDK 1.4에서는 Properties로 처리하기에는 불편한 계층형 데이터 구조를 다루기 위해서 Preferences API를 추가하였습니다. 다음 설명부분은 javadoc에 있는 설명을 제 나름대로 의역하면서 해석한 내용입니다. 한국말로 옮기기에 자연스럽지 못한 부분은 전부 의역처리 했습니다.

2.1.1. 자바에서 Preferences는?

속성데이터를 계층 구조로 저장하기 위해 사용하는 패키지입니다. 이 클래스를 이용해서 응용 프로그램의 설정 정보나 시스템의 속성을 저장할 수 있고 다시 가져올 수 있습니다. 이러한 데이터는 저장장치에 따라 다른 형태로 저장됩니다. 일반적으로 파일, OS의 레지스트리, 디렉토리 서비스, 데이터베이스를 이용하게 되지만 사실 프로그래머는 그런 저장장치에 대해서 알 필요가 없습니다.

Preferences에는 데이터를 저장하는 공간이 두가지로 나뉩니다. 하나는 사용자에 대한 정보로 구성된 트리이며, 다른 하나는 시스템에 대한 정보에 대한 트리입니다. 보통은 시스템에 대한 정보는 모든 사용자가 공유하게 사용자에 대한 정보는 사용자에 해당하는 데이터를 저장하는데 사용합니다. 여기서 사용자에 대한 공간을 해당 사용자만이 사용한다라고 이야기하지 않는 이유는 Preferences 클래스에서 "사용자"와 "시스템"을 어떻게 구현하고 구분하느냐에 따라 달라지기 때문입니다. 일반적으로 사용자 속성 트리에는 폰트, 색상, 윈도우 위치, 윈도우 사이즈 등의 정보를 저장하며, 시스템 속성에는 응용프로그램의 설치에 관련된 정보를 저장하게 됩니다.

Preferences의 트리에서 Node는 파일시스템의 디렉토리와 유사한 개념입니다. Preferences 트리의 각 Node는 노드의 이름과 절대 경로, 상대 경로의 정보를 가지고 있습니다. 절대 경로는 Preferences 를 사용하는 시스템 내에서 유일해야하지만 노드의 이름은 그럴 필요는 없습니다. Preferences의 노드를 구성하기 위한 제약 조건은 다음과 같습니다.

  • 루트 노드의 이름은 공백문자이다.
  • 루트 노드가 아닌 다른 노드는 반드시 이름을 가지고 있어야 한다.
  • 노드의 이름에는 공백문자나 슬래시("/")가 포함되어서는 안된다.

  • 루트 노드의 절대 경로는 "/" 이다.
  • 절대 경로는 항상 "/"로 시작한다.
  • 상대 경로는 "/"로 시작하지 않는다.
  • 노드의 자기 자신을 가리키는 상대경로는 ""이다. (즉 아무것도 안쓰면 자기자신입니다.)

  • 슬래시가 중복되는 경로는 존재해서는 안된다.
  • 루트 노드를 표현할때를 제외하고 슬래시를 경로의 끝에 붙이면 안된다.
  • 노드 이름으로는 슬래시와 공백문자가 아닌 어떠한 문자도 사용가능하다.

2.1.2. 왜 Preferences를 쓰나요? - 시나리오

글쎄요. 저도 잘 모르겠습니다. 왜 쓰냐는 질문보다는 "어디에" 쓰느냐가 더 맞는 질문인 것으로 생각됩니다. 이러한 질문에 답하기 위해 Preferences를 쓰게 되는 시나리오를 생각해보기로 했습니다.


사용자 정보를 저장하려고 합니다. 사용자 정보는 이름, 아이디, 전화번호, 주소, 전자우편 주소, ... 등등 여러가지 정보가 있습니다. 이를 데이터베이스에 넣으려고 합니다. 그렇다면 저장이 필요한 데이터의 종류를 파악해야합니다. 다음과 같은 데이터를 저장하기로 결정했다고 가정해봅시다.

  • 이름
  • 아이디
  • 전자우편
  • 주소

이제 프로그래머는 이름, 아이디, 전자우편, 주소의 데이터를 넣을 수 있는 데이터베이스 필드를 만들것입니다. 자 이제 프로그램을 전부 완성했습니다. 그런데 프로그램의 요구사항이 바뀌어서 전자우편을 3개까지 받아야한다고 하면, 이제부터 미치는 겁니다. 프로그램은 완성되었는데 데이터베이스를 바꾸다니..... 프로그래머는 이제 툴툴 대면서 전자우편 관련 필드를 3개로 늘려서 완성했습니다. 그런데 이번엔 주소를 직장 주소와 집 주소로 나누어 달라는군요. 어쩌겠습니까? 갑이 까라면 까야죠. 주소 관련 필드도 주소1, 주소2로 나누어서 고쳤습니다. 이런식으로 자꾸 수정하다보니까 데이터베이스 필드는 대부분의 사용자들에 대한 정보가 NULL인 필드로 구성되어 버렸습니다. SELECT한 결과가 뭐 대충 다음과 같겠지요.

이름 아이디 전자우편1 전자우편2 전자우편3 주소1 주소2 연봉 소유 차종
아무개1 AAA nospam@nospam.com NULL NULL 지구 NULL NULL NULL
아무개2 BBB spam@nospam.com spam@nospam.co.kr NULL 수성 화성 200원 녹차
아무개3 CCC NULL NULL NULL NULL 화성 190원 그랜다이져

계획없이 수정된 데이터베이스 필드는 이토록 처참하게 NULL로 구멍이 숭숭 뚫려버리고 더이상 손대기 싫어졌습니다. 그래서 프로그래머는 유지보수 하자는 말이 나오기전에 회사를 옮깁니다. -_-;

위의 시나리오가 정확한 묘사는 아니지만 이러한 경우에 Preferences가 힘을 발휘합니다. 입력하는 데이터가 항상 동일한 경우가 아니라 가변적인 경우라는 시나리오를 적어보았는데 정확하게 와닿지를 않는군요. 어쨌든 "아무개1"씨의 정보를 살펴본다면 전자우편 정보는 1개 주소도 1개 그외의 정보는 입력하지 않았습니다. "아무개2"씨는 전자우편 2개, 주소 2개, 연봉, 차종 이렇게 입력을 했습니다. 항상 데이터가 일정하게 입력하는 것이 아니라 사용자에 따라서 입력하는 정보의 갯수가 다르다는 것을 의미합니다.

위의 데이터베이스 설계는 철저하게 데이터베이스 관점에서 시작된 설계입니다. (이건 어디까지나 제 주장입니다.) 객체 지향 프로그래머의 관점에서 본다면 모든 데이터는 객체인데 데이터베이스에 입력할땐 객체가 아니라 펼쳐놓은 데이터베이스 구조이니 자꾸 지저분해질 수 밖에 없습니다. 시각을 조금만 달리한다면 위의 데이터는 다음과 같은 트리 형태로 바꿀 수 있을 것입니다.

prefs-structure.png
[PNG image (15.57 KB)]

 / --+ 아무개1 --+ 전자우편 --+ 전자우편1(nospam@nospam.com)
                 + 주소 --+ 주소1(...)              

     + 아무개2 --+ 전자우편 --+ 전자우편1(...)
                              + 전자우편2(...)
                 + 주소 --+ 주소1(...)
                          + 주소2(...)
                 + 연봉(...)
                 + 차종 --+ 차1 (...)
     + 아무개3  ......

  • 아무개3의 표현은 귀찮아서 생략합니다 (-_-);

평면 도화지위에 펼쳐놓았던 데이터가 트리로 바뀌면서 프로그램이 조금더 깔끔해질 것 같다는 생각이 듭니다. 데이터 저장 공간을 이렇게 생각해보자는 것이 Preferences 입니다.

2.1.3. Preferences의 한계

Preferences를 이용하여 저장하고 가져오는 방법은 편리하겠지만 문제는 선의 JDK 1.4에 있는 Preferences 클래스의 구현 상태입니다. 하필이면 데이터를 윈도우의 경우에는 레지스트리에 저장을 하고, 유닉스의 경우에는 말도안되는 디렉토리에 저장한다고 해서 디렉토리 퍼미션 문제를 일으키도록 구현되어있다는 것입니다. 사실 그 어떤 프로그래머가 윈도우 레지스트리에 방대한 정보를 담으려고 하겠습니까? 그리고 유닉스에서 자바로 만든 데몬을 구동하면서 root로 접근 가능한 디렉토리를 데몬 사용자 권한으로 읽고 쓰기가 가능하도록 허락할까요? 이부분이 JDK 1.4에서 이해가 되지 않는 부분입니다. JDK에 정식으로 집어넣었으면서 겨우 레퍼런스 수준의 API라니...

이것이 제가 생각하는 Preferences API의 한계입니다.

2.1.4. 한계의 극복

데이터를 제마음대로 저장하고 싶었습니다. 데이터베이스, XML, LDAP, 일반 텍스트 파일 등등 그 어떤 포맷이라고 상관없이 저장하고 가져오고, 그리고 각 데이터 포맷 끼리의 변환까지도 가능한 그런 API라면 매우 유용할 것이라고 생각했기 때문에 JDK 1.4에 포함된 클래스의 또 다른 구현 패키지를 만들어 그 한계를 극복하려고 합니다.


2.2. EnhancedPreferences API


2.2.1. 사용 기술

EnhancedPreferences API를 구현하기 위해서 사용하는 오픈소스 프레임워크는 다음과 같습니다.

  • jakarta commons-logging
  • hibernate 2
  • picocontainer

로깅 프레임워크는 너무나 유명하기 때문에 설명을 생략합니다. 물론 하이버네이트와 피코 컨테이너도 유명하지만 이 프로젝트의 진행 향을 이야기하는데 있어서 약간의 설명이 필요하여 하이버네이트와 피코 컨테이너에 대해서 이야기 하려고 합니다.

2.2.2. 하이버네이트

유명한 객체 관계 매핑 프레임워크입니다. 아파치 데이터베이스 프로젝트의 OJB와 같은 노선을 걷고 있는 프레임워크 입니다. 두가지를 다 사용해보았을때 OJB가 훨씬 복잡하다는 느낌이었습니다. 그래서 이 프로젝트의 첫번째 구현은 ORM(Object Relational Mapping) 프레임워크 중 하이버네이트를 사용하자라고 결정하게 되었습니다.

하지만 보수적인 프로그래머들은 ORM 프레임워크의 강력함을 인정하려고 하는 것 같지 않습니다. ORM 프레임워크는 객체에 따른 데이터베이스 쿼리를 자동 생성하여 사용합니다. 그렇기 때문에 이것이 직접 쿼리를 만들어 사용하는 것보다 성능이 나쁘다고 생각하는 경우가 많습니다. 예를 들어 대용량 데이터베이스에서 정렬과 같은 일을 인덱스와 hint 절로 처리하는 것이 성능을 극대화하는 것이라고 주장합니다. 하지만 전 생각이 다릅니다. 그렇게 데이터베이스 시스템에 의존적으로 성능향상을 해야하는 경우 보다는 프로그램의 로직을 개선하는데 노력을 들인다면 훨씬 더 좋은 효과를 거둘 수 있을 것이라고 생각합니다. 만약 ORM을 이용했고 더이상 로직의 개선 여지가 없다고 하였을때에는 DBA의 도움을 받아 데이터베이스 View를 생성하고 그것을 다시 ORM으로 매핑하면 됩니다. 이것이 객체지향적 프로그래머의 해법이 아닐까 생각합니다.

2.2.3. 피코컨테이너


2.2.4. 버전 넘버링에 관해


3. EnhancedPreferences API


3.1. 간단하게 사용해보기


3.2. 앞으로 할일


4. 질문과 답변

궁금하신 사항은 여기에 물어봐주세요 ^^

ID
Password
Join
You will step on the soil of many countries.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2004-12-19 23:46:01
Processing time 0.0073 sec