[번역] 도메인 로직과 SQL

원본 글은 http://martinfowler.com/articles/dblogic.html 에 있습니다.

최종 주요 갱신: 2003년 2월

우리는 지난 20여 년 이상 데이터베이스 지향 소프트웨어 개발자와 메모리에서 처리하는 애플리케이션 소프트웨어 개발자 간의 간격이 커지는 것을 봐왔습니다. 이 때문에 SQL이나 저장 프로시듀어 같은 데이터베 이스의 기능을 어떻게 이용할지에 대한 논의가 생겨났습니다. 이 글에서 전 업무 로직을 SQL 질의문 안에 둘 것인지 아니면 메모리에 있는 코드 안에 둘 것인지에 대한 문제를 주로 성능과 유지보수성의 관점에서 단순한 -그러나 SQL 충분히 활용한 - 예제를 사용해 살펴보려고 합니다.



이어지는 내용

by 박성철 | 2008/06/13 21:03 | 프로그래밍 이야기 | 트랙백(3) | 핑백(1) | 덧글(0)

수채화를 잘 그리는 10가지 비법

요즘 마나님께서 수채화를 배우기 시작하셔서 집안 구석구석에 화구와 관련 서적이 널려 있습니다. 아침에 회장님 뵈러 가면서 하나 집어든 책이 김충원 교수의 "수채화 쉽게 하기"라는 책이더군요. 대충 훑어만 봤는데도 왠지 그림을 그려보고 싶다는 생각이 들었습니다.

그 책 앞부분에 수채화를 잘 그리는 10가지 비법이 나오는데 비록 수채화 뿐 아니라 두루 적용할 만한 내용 같아서 따로 뽑아봅니다. 특히 프로그래머로서 동감이 되는 부분이 많더군요. 프로그래밍이 또 한 아~ㄹ트 하지 않겠습니까? ㅎㅎ

1.수채화에 관한 어두운 기억은 모두 잊습니다.

과거에 어설프게 시도했다가 실패했던 기억 때문에 늘 한계를 긋고 그 안에서 머물려는 사람들이 많습니다. 솔직히 제가 프로그래밍을 배울 때에 비해 요즘 서점에 가면 좋은 프로그래머가 되는데 도움이 되는 책들이 참 많습니다. 하지만 그런 책들은 당장 눈에 보이는 성과를 얻기 어렵지요. 반면에 입에만 달고 실력 향상에 별 도움이 안 되는 어설픈 입문서들은 어찌나 많은지...

2. '잘 그린 '그림'에 대한 고정관념을 없앱니다.

프로그래밍은 그림과 달리 객관적인 평가가 가능하기에 이 항목은 직접 적용하기에 무리가 있을지 모르지만 너무 타인과 자신을 비교하지 말라는 쪽으로 정리되더군요. 프로그래머 중에는 정말 4차원에서 온듯한 천재들이 많습니다. 그 사람들과 비교하기 시작하면 인생 끝나는 거죠. 너무 큰 것을 바라지 말고 작게 작게 프로그래밍 자체를 즐기면서 꾸준히 하는 것이 옳은 듯합니다.

3. 간단하고 쉬운 그림부터 시작합니다..

요즘은 사용자 환경이 복잡해서 단순한 프로그램 짜는 것이 힘들지만 가능하면 쉬운 것부터 시작하는 것이 중요합니다. '했더니 되더라'는 경험은 자신감을 줍니다. 전 프로그래머로 성장하는 과정이 RPG 게임과 비슷하다고 생각합니다. 도전, 탐험, 성취... 그리고 득템;;

4. 먼저 수채화의 특성을 파악합니다.

개발자의 입장에서는 자신의 개발 환경에 익숙해지라 것이겠네요. 일단 에디터는 손이 기억하게 해야겠죠? 사용하는 언어와 프레임웍도 충분히 숙지해야 하고요. Think in Java라는 책을 첨 알았을 때에 얼마나 제목에 감동을 받았는지... 영어를 잘하려면 영어로 생각해야 하는 것처럼 Java를 잘하려면 Java로 생각해야 합니다. 괜히 C++에는 있는데 왜 Java에는 없느냐고 투덜거리지 말고...

5. 흉내 내는 것부터 시작합니다.

개발자와 디자이너들에게 공통으로 부족한 게 흉내 내기입니다. 이제 막 대학을 졸업해 놓고는 백지에서 시작하려고 하는 그 고집은 정말 대책이 없습니다. (물론 저도 그랬지만 말입니다. ^^);;

반면에 음악을 하는 사람들은 배울 때에 따라하기를 늘 합니다. '딴다'고 말하죠. 고수를 따라하는 것을 결코 창피한 일이 아닙니다. 특히 요즘은 훌륭한 오픈소스 프로젝트들이 많습니다. 그냥 다운 받아서 압축을 풀면 바로 볼 수 있지요. Java 같은 경우는 Java API 소스 중 단순한 것부터 보면 많이 도움이 됩니다. 내가 사용하는 이 객체가 어떻게 돌아가는지 보면 이해도 깊어지고 좋더군요.
API 문서를 봐도 잘 이해가 안 되는 게 많기도 하고요.

6. 스케치로 기초를 다집니다.

밑그림이 잘못되면 아무리 예쁜 색을 칠해도 좋은 그림이 될 수 없는 것 처럼 좋은 프로그램은 충분한 생각에서 나옵니다. 생각을 돕는 원칙, 격언, 기술들이 많습니다.

7. 즐기면서 그립니다.

달리 말이 필요할까요? 프로그래밍은 정말 재미있습니다. 전 재미 없는 것을 억지로 하는 재주가 없는 사람이지만 첨 입문한 중학생 때부터 지금까지 20년 넘게 프로그래밍을 계속하고 있고 늘 잘하려고 노력합니다. 프로그래밍은 정말 중독성이 있습니다.

8. 누군가와 함께 그립니다.

전 프로그래밍을 하는 초기에 좋은 친구들이 있었습니다. 서로 격려해주고 도움을 주고 감탄해주는 친구 덕분에 더 신나서 프로그래밍을 할 수 있었습니다. 뭘 했느냐가 아닌 어떻게 했느냐에 관심을 갖어주는 친구나 동료들은 소중한 자산입니다.

9. 실패를 두려워하지 않습니다.

소프트웨어는 정말 소프트합니다. 전문 프로그래머가 되면 자신의 작업에 책임을 져야 하지만 다른 분야들에 비하면 실수를 만회할 기회는 많습니다. 디버깅, 리팩토링 할 수 있는 다른 분야가 뭐가 있나요?

10. 서두르지 않습니다.

프로그래밍은 늘 새롭습니다. 제가 배웠던 기술 중에는 더 이상 사용하지 않는 것들이 대부분입니다. 배워야 할 것들은 많고요. 너무 성급하게 달려들지 말고 평생 배우고 익히겠다는 생각으로 사는게 좋습니다. 어느날 스스로 프로그래밍을 할 줄 아는 컴퓨터가 나와서 프로그래머를 패기 처분하기 전까지 말입니다.

그냥 목록만 쓰려고 했었는데 좀 심심해서 한두 줄 제 생각을 붙인 다는 게 사족처럼 되어버렸네요. 여기에서 미리보기를 하시면 원문을 보실 수 있습니다.

by 박성철 | 2008/03/25 03:44 | 프로그래밍 이야기 | 트랙백 | 덧글(9)

Commons Configuration을 사용한 스프링 운영 환경 설정값 지정

스프링 설정 파일과 운영 환경 설정값

Spring framwork의 IoC 컨테이너 XML 설정 파일을 사용하면 애플리케이션을 유연하게 구성할 수 있습니다. 배포 후에도 지역 상황에 맞춰서 컴포넌트를 다른 것으로 바꾼다거나 운영 설정 값을 바꾸거나 하는 일이 무척 쉽지요.  하지만, 이 파일에는 가볍게 다루기에는 너무 중요한 정보들이 들어 있습니다. 사실 객체 생성 로직이 들어 있는 코드라고 볼 수도 있습니다.

중요한 정보를 가진 파일에 환경에 따라서 자주 변경되는 런타임 설정값들은 같이 두는 것은 적당하지 않습니다. 자주 변경할 것 같은 값들을 컨테이너 설정 파일 외부로 빼서 별도 파일로 관리하는 것이 좋겠지요. spring에 이 용도로 제공하는 후처리기가 두 가지 있는데 하나는 PropertyPlaceholderConfigurer이고 또 하나는 PropertyOverrideConfigurer입니다.

PropertyPlaceholderConfigurer는 컨테이너 설정 파일의 빈들을 만들기 전에 설정 파일 중에 있는 임시표기(Placeholder를 우리말로 뭐라고 해야 할지...ㅡ.ㅡ)를 Properties 파일에 등록한 설정값으로 바꿔줍니다. PropertyOverrideConfigurer는 반대로 빈들을 다 만들고 DI까지 다 완료한 이후에 Properties 파일에 지정한 빈 이름과 필드명에 지정된 값들로 덮어씁니다.

전자는 property 이름을 빈의 구현과 관계없이 논리적으로 정할 수 있는 대신 컨테이너 설정 파일의 설정값이 들어가야 할 위치에 property 이름으로 임시표식을 삽입해줘야 합니다. 후자는 컨테이너 설정 파일을 전혀 손대지 않고도 기본으로 지정된 값을 배치된 운영 환경에 맞는 값으로 덮어쓸 수 있습니다. 하지만 property 이름이 빈 이름에 종속됩니다.

제약

이 두 가지 후처리기를 사용하면 운영 환경에 따라 바뀌는 값을 외부로 뺄 수 있지만 여전히 제약이 남아있습니다. 둘 다 외부 설정 파일로 Properties 파일만 사용할 수 있다는 것이지요. Properties 파일로도 큰 문제 없이 설정을 할 수 있지만 이런 요구가 있을 수 있습니다.
  • Poperties 파일 대신 XML 파일을 쓰고 싶다.
  • DB에 들어 있는 설정 값들로 객체를 만들고 싶다.
  • DB와 XML, Properties 파일을 다 쓰고 싶다.
  • JNDI Tree에 설정값을 넣고 싶다.
  • Windows의 ini 파일이나 Mac의 PropertyList 파일을 쓰고 싶다.
저는 인코딩 문제도 있고 읽기도 좋아서 Properties 보다는 XML을 선호합니다. 그리고 몇몇 설정값은 사용자에게 인터페이스를 제공해서 DB의 값을 조작하게 해야 하는 경우가 있습니다.


Apache Commons Configuration

애플리케이션 운영 환경 설정에 제가 주로 사용하는 기술이 Apache commons 프로젝트 중 한 컴포넌트인 Configuration 입니다.  홈페이지에 의하면 Commons Configuration은 일반화된 설정 인터페이스를 제공함으로써 자바 애플리케이션이 다양한 소스에서 설정을 읽을 수 있도록 해준다고 설명하고 있습니다.

열거하고 있는 소스는 다음과 같습니다.
  • Properties 파일
  • XML 문서
  • Windows INI 파일
  • Property list 파일 (plist)
  • JNDI
  • JDBC Datasource
  • System properties
  • Applet parameters
  • Servlet parameters
Commons Configuration은 이렇게 여러 소스에서 설정값을 읽어오는 기능 외에도 복잡한 XML을 효율적으로 다룰 수 있고  Properties 파일도 기본 API보다 훨씬 다양한 기능을 제공하고 있으며 다양한 타입 접근자를 가지고 있고 여러 소스의 설정값을 통합할 수 있습니다. 자세한 것은 사용자 설명서가 잘 되어 있으니 참고하십시오.

CommonConfigurationFactoryBean

Spring modules 프로젝트를 보면 Apache Commons의 여러 컴포넌트들 중 Configuration, Lang, Chain, Validator의 스프링 통합 컴포넌트들이 있습니다. 그중 Configuration 스프링 통합 컴포넌트가 CommonConfigurationFactoryBean 입니다. 이 빈은 아답터의 일종인데 PropertyPlaceholderConfigurer 같이 PropertyResourceConfigurer를 상속한 빈들에 Commons Configuration의 각종 configuration 객체를 붙일 수 있도록 해줍니다.

CommonConfigurationFactoryBean에 하나 이상의 소스에서 설정값을 읽은 Configuration을 등록한 후 PropertyPlaceholderConfigurer나 PropertyOverrideConfigurer의 properties 필드에 대입을 해주면 CommonConfigurationFactoryBean는 등록된 configuration들에 담겨있는 설정값들을 Properties로 변환해서 전달해줍니다.

사실 CommonConfigurationFactoryBean은 내부적으로 Configuration의 CompositeConfiguration를 가지고 있어서 여러 소스의 Configuration을 합 할 수 있습니다.

myconfig.xml이라는 XML 설정 파일을 사용해서 PropertyPlaceholderConfigurer를 등록하는 스프링 설정은 이렇습니다.

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="properties">
            <bean class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
                <property name="configurations">
                    <list>
                        <bean class="org.apache.commons.configuration.XMLConfiguration">
                            <constructor-arg type="java.lang.String">
                                <value>myconfig.xml</value>
                            </constructor-arg>
                        </bean>
                    </list>
                </property>
            </bean>
        </property>
    </bean>   

단순한 설정인데도 좀 복잡하게 나왔습니다.  보시면 PropertyPlaceholderConfigurer와 CommonsConfigurationFactoryBean와 XMLConfiguration 세 가지 객체가 만들어집니다.

PropertyPlaceholderConfigurer는 위에 설명한 것처럼 스프링 설정에 환경 설정값을 넣어주는 후처리기입니다. XMLConfiguration은 생성자에 지정한 XML 파일을 읽어서 설정값을 담은 Commons Configuration의 configuration 객체 중 하나입니다. CommonsConfigurationFactoryBean는 XMLConfiguration을 받아서 설정값을 Properties로 변환한 후 PropertyPlaceholderConfigurer에게 전달하는 역할을 합니다.

기본값과 로컬 설정의 분리

별도 운영 설정 파일을 만들더라도 모든 설정을 해줄 필요 없이 변경이 필요한 한두 설정값만  변경하고 나머지는 기본값이 대응되도록 하는 것이 운영하는데 도움이 됩니다. 다음과 같이 local_config.xml과 default_config.xml을 만들어서 각각 로컬 설정과 기본 설정 값을 넣도록 합니다.

local_config.xml

<config>
<smtp>
  <host>mail.abc.co.kr</smtp_host>
</smtp>
</config>

default_config.xml

<config>
<smtp>
  <host>mail.myhost.co.kr</smtp_host>
  <port>25</port>
</smtp>
</config>

그리고 이 두 파일을 사동하도록 설정합니다.

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="properties">
            <bean class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
                <property name="configurations">
                    <list>
                        <bean class="org.apache.commons.configuration.XMLConfiguration">
                            <constructor-arg type="java.lang.String">
                                <value>local_config.xml</value>
                            </constructor-arg>
                        </bean>
                        <bean class="org.apache.commons.configuration.XMLConfiguration">
                            <constructor-arg type="java.lang.String">
                                <value>default_config.xml</value>
                            </constructor-arg>
                        </bean>
                    </list>
                </property>
            </bean>
        </property>
    </bean>

   <bean id="mailService" class=".....">
        <property name="host" value="${smtp.host}"/>
        <property name="port" value="${smtp.port}"/>
   </bean>

이렇게 local_config.xml을 먼저 등록하고 default_config.xml을 나중에 등록하면 먼저 local_config.xml의 설정값을 먼저 찾고 만약 이 파일에 찾으려는 설정값이 없으면 그다음 configration인 default_config.xml에서 찾는다.

Configuration을 직접 사용

Commons Configuration은 Properties로 변환해서 컨테이너 설정 파일의 설정값을 지정하는 용도 외에도 복잡한 애플리케이션 설정값을 표현하는 능력이 있습니다. 이런 Configuration의 기능을 직접 쓰고 싶은 경우를 위해서 설정을 분리하고 필요한 객체에서 참조할 수 있도록 하면 유용합니다.

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="properties">
            <bean class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
               <property name="configurations">
                    <list>
                         <ref bean="configuration"/>
                    </list>
                </property>
            </bean>
        </property>
    </bean>
   
    <bean id="configuration" class="org.apache.commons.configuration.CompositeConfiguration">
        <constructor-arg>
            <list>
                <bean class="org.apache.commons.configuration.XMLConfiguration">
                    <constructor-arg type="java.lang.String">
                        <value>user-config.xml</value>
                    </constructor-arg>
                </bean>
                <bean class="org.apache.commons.configuration.XMLConfiguration">
                    <constructor-arg type="java.lang.String">
                        <value>default-config.xml</value>
                    </constructor-arg>
                </bean>
            </list>
        </constructor-arg>
    </bean>

   <bean id="mailService" class=".....">
        <property name="host" value="${smtp.host}"/>
        <property name="port" value="${smtp.port}"/>
   </bean>

   <bean id="anotherService" class=".....">
        <property name="configuration" ref="configuration"/>
   </bean>

anotherService는 직접 Configuration 객체를 받아서 그 안에 담겨있는 설정값들을 Commons Configuration이 제공하는 다양한 방법으로 읽어서 작동할 때에 참고할 수 있습니다.



by 박성철 | 2008/02/29 15:16 | 프로그래밍 이야기 | 트랙백 | 핑백(1) | 덧글(2)

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