Clean Code that Works.

이전 포스팅에서 커스텀 컨버터를 등록 하는 방법을 알아 봤다.

하지만 이 경우는 <mvc:anontation-driven>을 사용할때만 가능 하다.
봄싹에서는 위 방식을 사용하지 않고, 수동으로 지정 하여 사용한다.

근데 내가 <mvc:anontation-driven>을 예전에 적용해 볼려고 하다가, 설정파일에 적어놓고 삭제하지 않고 commit 되어 봄싹 서버에도 올라가서 사용되고 있었다.
오마이갓. @_@;;;

하여 저것을 삭제 하고, 다시 컨버전 서비스를 적용할 방법을 생각해 봐야 했는데..
토비님 글을 보면 자세히 설명이 되어 있다. http://toby.epril.com/?p=989

글을 잘 읽어 보면...
<mvc:annotation-driven>이 등록해주는 빈이 한가지 더 있다. 바로 MappedInterceptor이다. 정확히 말하자면 모든 경로에 대해서 적용되는 ConversionServiceExposingInterceptor를 가진 MappedInterceptor이다.

그렇다. 봄싹에는 ConversionServiceExposingInterceptor가 등록 되어 있지 않아서, 커스텀 컨버터가 적용 되지 않고 있었던 것이다. 그럼 어디에다가 interceptor를 등록 해야 할 까?

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="0">
        <property name="interceptors">
            <list>
                <bean class="org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor" >
                    <constructor-arg ref="conversionService"/>
                </bean>
            </list>
        </property>
    </bean>

이런 형식으로 interceptor를 등록 하면 된다.
url 요청에 따라 인터셉터를 적용하고 싶으면 MappedInterceptro를 만들어서 DefaultAnnotationHandlerMapping의 프로퍼티로 해서 추가 하면 된다.


http://whiteship.me/?p=12671

봄싹 게시판 모듈에 들어갈 도메인 클래스 생성 방식에 대해서 생각해 보고,
구현하여 디비 테이블 까지 만들자!!!!

하이버네이트 클래스 상속 매핑 기법!!
  • 클래스 계층도 당 하나의 테이블
  • 클래스마다 하나의 테이블(by 찬욱님 블로그)
  • 인스턴스 생성이 가능한 클래스 마다 하나의 테이블

음... 최범균님 책인데 책이 오래되서 더 낳은 방법이 있을 수도 ...;;
하이버네이트 완벽 가이드 한번 사서 봐야 하는데..

1. 클래스 계층도 당 하나의 테이블
- 장점 : 매핑이 간단하다. 성능이 좋다.
- 단점 : 하위 클래스의 프로퍼티와 매핑될 칼럼은 기본적으로 null이어야 한다. 새로운 하위 클래스가 추가될 경우 테이블을 변경해야 한다.

2. 클래스마다 하나의 테이블
- 장점 : 데이터가 정규화 된다
- 단점 : 계층도가 복잡해질수록 성능이 나빠진다.

3. 인스턴스 생성이 가능한 클래스 마다 하나의 테이블
- 장점 : 하위 타입의 클래스를 조회할 경우 조인이 발생하지 않는다.
- 단점 : identity 생성기 등 키 값 사용에 제약을 받는다. 비 정규화 되어 있다.

대략 이렇게 장 단점이 있다.

봄싹 포스팅 모듈의 경우 부모클래스 한개와 각각 포스팅 타입에 따라 하위 클래스가 4개 있다고 보면 되고, 하위 클래스에 대한 명확한 설계는 하지 않았기 때문에 클래스에 대한 속성들이 확장될 가능 성이 있다.

구현하기에는 1번이 편하지만, 지금 설계에서 확장될 가능성이 크기 때문에 2번으로 해서 도메인 클래스 만들어야 겠다.
3번은.. 괜찮긴 한데 정규화가 안되있어서 DDD 스타일로 개발하기에도 좀 그렇다. 2번의 경우에는 계층도가 복잡해질수록 외부 조인에 따른 성능 저하가 있기는 하지만, 성능 저하를 많이 일으킬만큼 무거은 서비스가 아니기 때문에 문제가 되지는 않을 것 같다.


토비의 스프링3에 12장에 있는 내용.

가볍게 동작 과정을 간단히 정리 해 봅시다.
자세한건 꼭 책을 읽어 보세요.

(1) DispatcherServlet의 HTTP 요청 접수
 - DispatcherServlet의 매핑된 모든 요청에 대해서 공통적으로 진행해야 하는 전처리 작업이 있다면 이를 먼저 수행한다.(보안, 파라미터 조작, 한글 디코딩)

(2) DispatcherServlet에서 컨트롤러로 HTTP 요청 위임
 - URL이나 파라미터 정보, HTTP 명령 등을 참고해서 어떤 컨트롤러에 작업을 위임할지 결정.

(3) 컨트롤러의 모델 생성과 정보 등록
 - 모델을 생성하고 모델에 정보를 넣어 줌

(4) 컨트롤러 결과 리턴: 모델과 뷰
 - 모델과 뷰를 넘기고 컨트롤러의 책임은 끝

(5) DispatcherServer의 뷰 호출과 (6) 모델 참조
 - 뷰오브젝트에 모델 전달 후 클라이언트에게 돌려줄 최종 결과물 생성을 요청

(7) HTTP 응답 돌려주기
 - 뷰 생성까지 모든 작업을 마쳤으면 후처리기가 있는지 확인하고 작업후 최종 결과를 서블릿 컨테이너에게 돌려준다.


봄 부터 꾸준히 추진해 왔던 봄싹 사이트 개발 계획은 나름 순조롭게 진행중이다.
기선이 형이 개인 사정으로 인해서 당분간 봄싹에는 손을 안데시기로 해서.. 사이트 개발 쪽은 내가 좀 진행하기로 했다.
능력이 되시니가 잘 될꺼라 믿는다..
헉!!! 근데 난 잘 몰라!!! ;ㅁ;

이번주부터 매주 토요일(4주간인가?) 강남에서 기선이형이 진행하는 스프링 교육을 듣기로 했는데, 공부도 하면서 개발중에 이슈나 모르는 것은 거기서 물어봐야겠다.

후반기에 내가 해야 할 것은 게시판 모듈 개발 & 스터디 디자인 개선 인데..
지금까지 봄싹에서는 주로 리팩토링 및 잘잘한 기능 추가밖에 안해서,
이번에 추가될 게시판 모듈이 내가 개발한 것에서는 가장 큰 내용이 될 것같다.

열심히 개발해서 Clean Code That works. 하도록 해야지.
디자인은 베끼는 사이트...( 창작은 모방으로 부터 시작한다지..)에서 잘 참조해서 :)

게시판 개발에 대해서 어느정도 요구사항이 나오긴 했는데, 이것을 가지고 어떻게 개발할 지 고민중이다.
아직 디비 테이블도 안만들었는데.. 기본적인 요구 사항을 가지고 TDD 형식으로 진행 해 볼지(좀 익숙해 져야 TDD에도)
윤석군하고 좀 해봐야겠는데 ㅋㅋ

웁스.. 또 하고싶은것만 늘어나는것은 아닌지 걱정이구만.

프로퍼티 에디터 등등...

화면에서 값을 변경해서 보여줄 때는 <form:input>으로 사용하던지,
아니면 <spring:bind> 로 해서 보여줘야 한다. 웁스.

이게 폼에서 보여줄 때 이렇게 하면 되는데,

나는 뷰.... 목록으로 보여줄때 컨버팅을 하고 싶었다.
이렇게 저렇게도 해보고 고민해봤는데 도무지 이해가 안되서 KSUG에 질문을 올렸다.

http://groups.google.com/group/ksug/browse_thread/thread/6f4a94d4485de366

토비님 글에도 설명이 되어 있는데.
http://toby.epril.com/?p=989

<spring:eval> 태그를 사용하면 된다고 한다..conversionService를 사용해서
전체적인 설명은 토비님 블로그에 잘 설명이 되어 있고,
사용하는 방법은 아래와 같이 설정 해 주면된다.

<mvc:annotation-driven conversion-service="conversionService"/>


<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="springsprout.common.conversion.converter.TimeToWebStringConverter" />
            </list>
        </property>
</bean>

이렇게 설정 해 주면 화면 <spring:eval>은 ConversionServiceExposingInterceptor이녀석이 가로체서 컨버터를 적용 해 준다.

토비님 책 보면서 이쪽 부분은 아직 안 읽었었는데, Type-Conversion 부분이 폼에서 하는 부분과 리스트등 뷰에서 하는 부분이 햇갈려서 시간을 많이 잡아 먹었다. -_-;;;
그래도 덕분에 컨버터에 대해서 좀 볼 수 있었다. ..;;

참 jsp에서는 <spring:eval expression="meeting.openTime?:''"/>
이렇게 적어 주어야 한다.
spring el 에 대해서 잘 몰라서 .. The Elvis Operator라는 방식이라는데..
뭐 널이면 "" 공백 출력하라는거 같은데.. 이부분은 좀 더 살펴봐야겠다.

저 ConversionServiceExposingInterceptor 이게 어떻게 값 변환하는지 궁금하네.


어제는 제조업체 SM, 오늘은 솔루션 기업 면접을 봤다.

오랜만에 보는 면접이라 떨리기도 했고, 또 면접관이 4분씩 계셔서 힘들기도 했다.
면접을 잘 보지는 않았다. 100%중에 한 60~70%정도 마음에 들었을것 같다.

SM 면접은 아무래도 내가 조금 가볍게 생각했었다.
이력서를 작성할 때도 별 생각없이 기존에 이력서 작성하던데로 기술 위주로 작성을 했었는데,
사실 SM 이력서 작성할때는 운영에 대한 생각과 이력을 중심으로 기술해야 하는데 이를 인지 하지 못했다.
면접을 보고나서, 면접자리에 같이 있었던 퇴사 하시는 분(아마 이분 대신 일하게 될)이 지적을 해 주셨다.
나는 모르고 있는 내용이라서 대단히 감사 했다. ^^;

솔루션 기업 면접은 그 분야를 선도하는 기업이라서, 나름대로 준비도 하고 해서 면접을 진행했다.
기술 질문의 경우에는 딱히 꼭 집어서 특정 분야에 집중적으로 물어보시지 않고, 이력서에 있는 내용으로 질문을 하셨는데, 잘 대답 하지는 못했다. 조금 더 생각해보고 대답을 했어야 하는데. 약간 아쉽긴 했다.

인사 담당자의 질문은 사전에 양해를 구하고 다양한 질문을 하였다.
이직 사유에 관해서 질문을 했을때.
내가 이력서를 작성하고, 면접에 대답을 할 때도 약간 개인적인 욕구가 강하다고 보이는 것 같다.
이 것에 대해서는 어느정도 맞는 말이고 부정을 할 수는 없지만, 사실 이번 경우에는 아는 분의 아는분의 추천으로 지원을 하게 됬는데, 면접보는 회사에서도 개인적인 욕구에 맞지 않는 일을 시키면 퇴사할 것이냐 라고 질문을 하였다.

어느 회사가 개인적인 욕구에 100% 맞추어 일을 주고 하겠느냐, 그 받은 일을 최대한 열심히 하고, 그 곳에서 자기 계발의 기회를 찾아서 최대한 회사에 기여 하겠다. 이런 뉘앙스로 대답을 하였으나..
아마도 개인중심 적인 사람 이런 식으로 인식하신것 같다.

물론 인사담당자 입장에서는 사람 뽑을때 최대한 회사에 기여하고 오래있을 수 있는 사람을 뽑아야 겠지만, 구직자의 입장에서도 회사에 입사 하였을 때 자신의 업무에 정말로 맞지 않는 다면 이직하는게 당연하지 않을까 라는 생각이 들었다.
특히나 일반 업무도 아니고 개발자(지식노동자)라는 입장에서 자신의 지식을 활용할 수 있는 그런 포지션에서 최대한 일 할 수 있도록 해야지 최대한의 효율이 나올 수 있고, 업무에 맞지 않는 일을 시키면 소프트웨어의 품질이 잘 나올 수 있느냐 이런 생각이 든다. 물론 내 입장에서.. -_-;;;

인사 담당자의 생각도 맞다. 하지만 내 생각도 틀리지는 않는다고 생각한다.

아 그리고 블로그에 올려논 글들도 확인 했던데.
지금 다니고 있는 회사가 마음에 안든다는 내용이었다.
사람이 회사를 다니면서 비판도 못하나. -_-;;
사실 그 포스팅은 비공개 포스팅이 었는데 꿀릴.. 머 잘못말한것도 아니고. 회사 담당자가 봐도 그렇게 틀릴 말은 아닌..
그런 내용 이었다고 생각한다.

뭐 할말은 다 하고 살아야지.
-_-;;





토비의 스프링3 9장에 나오는 애플리케이션 정보 아키텍처에 대해서 읽고 있다.
책에 있는 내용을 조금 정리해 보았다.

이전에 어렴풋이 알고 있던 내용에 대해서 확실하게 알 수 있었다.

여기서 몇몇 아키텍처에 대한 내용이 나오는데.
애플리케이션에서 서로 흘러다니는 정보를 어떤 식으로 다루는 방식에 대한 아키텍처이다.
간단하게 엔터프라이즈 애플리케이션에 존재하는 정보를 데이터로 다루는 경우(주로 맵) 오브젝트로 다루는 경우(도메인 오브젝트)를 기준으로 구분할 수 있다.

  • DB/SQL 중심의 로직 구현방식
  • 거대한 서비스 계층 방식
  • 빈약한 도메인 오브젝트 방식
  • 풍성한 도메인 오브젝트 방식
각각 방식에 대해서는 책에 자세히 설명이 되어 있다.

실무에서는 어떻게 구성이 되어있는지 이야기를 해 보면,
지금 내가 진행하고 있는 프로젝트가 DB/SQL 중심의 로직 구현방식(90%), 거대한 서비스 계층 방식(10%)을 사용한다.

기선이 형한테 프로젝트 구성을 보여주면서 어떻게 스프링을 쓰면서 이렇게 쓰지? 하면서 성토를 했던 적이 있는데,
이게 바로 위의 두가지 구현방식을 사용한 것이었다.

정보 흐름을 살펴보면 DB/SQL을 통해서 맵으로 데이터를 가져오고(거의 가공하지 않고) 바로 맵을 통해서 뷰에 보여준다.
거대한 서비스 계층 방식은 DB/SQL을 통해서 뷰에 보여줄 데이터를 보여주기 어려운 경우(리포팅 같은 경우에는 리포팅에 맞게 데이터를 재 가공 해줘야 한다)에 사용을 한다. 일단 데이터를 가져온 다음 서비스 계층에서 이를 가공한다.( 토스3에 나온 내용처럼 서비스계층이 거대해 지기 때문에 거대한 서비스 계층 방식이라고 한다)

이 개발 방식의 장점은 업무별로 독립적인 개발이 가능하므로 초기 개발 속도가 빠르고, 개발자 사이에 간섭 없이 독립적인 개발이 가능하다. 하지만 객체지향적인 설계가 없고(적용하기 힘들고), 개발자 개개인의 코딩습관이나 실력에 따라서 서비스 로직의 구현 방식이 달라진다.(유지보수가 힘들어진다.)
가장 큰 단점으로는 처음에는 개발하기 편하지만 중복이 많아지기 쉽고 장기적으로 코드를 관리하고 발전시키기 힘들다.
(토스 3)

정말 공감하는 내용이다.
지금 하고 있는 프로젝트가 화면 하나당 각각 컨트롤러, 서비스가 존재한다.(엄청난 수의 컨트롤러와 서비스들) 이를 어떻게 관리할지 난감하다. 결국엔 나중에 가면 이전 서비스들은 버리고 다시 재 개발 해야 한다.

빈약한 도메인 오브젝트 방식은 이전에 내가 스터디 하면서 개발을 하던 방식이었다.
도메인 오브젝트가 존재 하긴 하지만 거의 VO 로만(getter/setter)로 만 구성되어 있고, 도메인 오브젝트에 다른 비즈니스로직이 들어 가 있지 않다. 이 방식은 이전 방식보다 낳기는 하지만 비즈니스 로직이 서비스에 집중되어 있기 때문에 서비스의 크기가 커지고 서비스에 비즈니스 로직이 들어가 있기 때문에 이를 다른 서비스에서 사용하기 위해서는 사용하려는 서비스에 DI 해 주어야 한다.
사실 이 방식밖에 몰랐다.(스프링 샘플 소스도 이 방식이다)

하지만 더 낳은 방식인 풍성한 도메인 오브젝트 방식이 있다!!
사실 이 방식은 봄싹에서 봤다. 처음 봤을 땐, 응? 왜 도메인 오브젝트에 비즈니스 로직이 섞여 있지?
라는 느낌이었는데, 이번에 책 보면이 이 방식의 장점을 알 수 있었다.
이 방식은 도메인 오브젝트안에 로직을 담아 두면 이 로직을 서비스 계층의 메소드에 따로 만드는 것 보다 응집도가 높다.
빈약한 도메인 오브젝트 방식에 비해서 서비스 계층의 코드가 간결해 지고 비즈니스 로직 코드도 훨씬 이해하기 쉬어진다.

더 발전된 방식으로 도메인 계층 방식이 있는데
이 부분은 토스 3를 참조 하세요 @_@

토비의 스프링 3
이일민 저
예스24 | 애드온2

http://wiki.springsprout.org/pages/viewpage.action?pageId=2883707

잊어 버리지 말자.
SOLID

이 밤에 끝을 잡고 ..ㅋ

부천으로 이사오기 전에 건대 입구에 있을 때는,
퇴근해서 라디오 들으면서 책 많이 읽었었는데..
(탱구의 친친, 타블로의.. 머였더라 )

이사 오면서 묘하게 책 읽는 리듬이 어긋나서 생각보다 좀 많이 못 읽었다.
사놓고 못 보고 있는 책이..
하둡(재미있다! 하지만 당장 필요한 기술이 아니다.), 멀티코어 프로그래밍(이놈은 그냥 훑어 봐야겠다)
기선형이 빌려준 자바 병렬 프로그래밍(어렵다! 책이 지루하다!)
뷰티풀 아키텍처(음?? -_-;;)

옆에 보니깐 대략 이정도??

지금까지 산 책이 헉 벌써 80권 정도내..

비율을 보면 API 레퍼런스 류가 약 40% 방법론 책이 30%(잼있어. 하드 코드나 실용주의 사고와 하급, 소프트웨어 컨플릭트
기타 디자인 및 패턴 책들

처음으로 책 사서 볼 때도 API에 너무 치중하지 말고 방법론 및 디자인 책도 사서 보자는 주의 였는데
나름 잘 지켜 지고 있다. 하하하핫.

아무튼.

목적은 집중해서 책 읽기!!!
하여, 복층에 있던 오디오를 1층으로 내렸다. 여름엔 1층에서 생활.
겨울 되면 다시 올라가지만 -ㅅ-;;;

요즘 7시 30분 퇴근이라 집에 오면 9시 가까이 되는데...(젝일 책 읽을 시간이 모잘라)
적어도 10시 전에 책 읽어서 11시(11시 예능은 본방 사수 -_-;;) 까지 읽는 습관을 다시 들여야겠다.

일단 책 읽을것들을 다 읽고(또 책 샀다, 자바 퍼포먼스 파운데이션, 이놈은 10월에나 보겠다.)
코딩은 잠시 급한것만 하고, 아니면 일 하면서 지루할때 짬짬이 하던가 해야겠다.

최근에 보고 싶은 책은... Spring receipes.. 인데, 원서 이다.
그래도 읽어 보고는 싶다. 담달에 봐서 사야지,
기선형이 번역한 하이버네이트도 보고싶고.

아 욕심은 많아.