난항의 프로젝트
앞선 포스트에서도 몇차례 언급했었지만 지난 프로젝트는 이런저런 요인들로 난항의 연속이었다. SI에 몸담고 개발자로서의 첫발을 디딘 후로 꽤나 많은 시간들을 보내면서 그동안 적지않은 프로젝트를 경험했지만, 스트레스의 강도로 따지자면 손가락 안에 꼽을 정도로 힘든 프로젝트가 진행되었다.
그래도 PM을 비롯하여 말단 개발자까지 합심하여, 프로젝트 기간내내 대부분의 주말도 반납하고 하루하루 밤늦도록 열성을 다하여 전력질주한 끝에 다소 불안정한 상태였지만 그럭저럭 서비스를 오픈할 수 있었다. 덕분에 지난 7월 오픈을 전후하여 나를 포함해 대부분의 투입 인력이 철수하였다. 하지만 아직까지도 몇몇 SM 인력들이 주어진 숙제를 안은채 서비스를 안정화하고 품질을 높이기 위해 불철주야 노력하고 있다.
난항을 겪는 프로젝트가 흔히 그렇듯이 상대적으로 할 일은 많은데 절대적인 시간이 부족했다. 어느정도의 리스크를 이미 전제조건으로 떠안고 시작한 프로젝트. 끊임없는 강행군으로 심신은 지쳐가고 다가오는 데드라인에 중압감은 쌓일대로 쌓여 프로젝트룸의 공기가 어느덧 숨이 턱턱 막힐 정도로 무거워진 무렵의 어는날엔, 말그대로 드라마에서 나올법한 "드라마틱한 사건"이 벌어지기도 했다. 돌이켜보건데, 다 사람 사는 일이라 벌이진 해프닝으로 치부할 수도 있으련만 프로젝트가 중후반에 이르면서 그만큼 다들 극도의 스트레스를 받고 있었다는 반증이 아닐 수 없다.
어려웠던 프로젝트는 이유가 있기 마련이다. 하지만 현재 시점에서 업무며 설계며, 커뮤니케이션니 협업이니 기타등등의 원초적인 부분에 대해 언급하고 싶지는 않다. 또 이들의 비중이 막대하지만 프로젝트의 성패를 좌우하는 전부가 되지는 못한다. 실제로 보다 복잡한 요인과 설명하기 어려운 요소들이 얼기설기 얽혀있기 마련이다.
단편적 회고
다만 기술적인 관점에 있어서 하나의 단편적인 부분을 언급해보고자 한다. 그러기 전에 먼저 프로젝트의 개발 환경에 대해 짧게 소개하자면, 시스템은 크게 Spring2.5을 기반으로 하여 Struts2와 iBATIS의 오픈소스 프레임워크의 조합과 기타 라이브러리들을 사용하여 구축되었다. 그리고 AJAX(Prototype 기반)와 DWR(Direct Web Remoting)을 사용하여 UI에서 발생하는 사용자 액션(이벤트)들을 처리하였다.
대강의 환경과 툴, 주요한 라이브러리를 정리해보았다.
Environments
-
JAVA: JSDK 1.5, J2EE 1.4+(Servlet 2.4, JavaServer Pages 2.0 JSTL 1.0 이상 지원 환경)
-
WAS: JEUS 6.0 (개발: Tomcat 6.0.18)
-
WEB: WebtoB 4.1
-
DB: Oracle 10g
IDE & Tools
-
IDE: Eclipse Ganymede 3.4.1
-
Reporting Tool: Report Designer
-
Version Control: Subversion 1.5.5
-
Code Generator: 단위업무에 필요한 JSPs(코드 템플릿), Java(Action/DAO/Model), 설정(Struts/iBATIS) 등의 파일 목록 자동 생성.
Open Source - Framework & Library
-
Java Libraries
-
Spring 2.5.6 (Base)
-
Spring Security 2.0.4 (Security)
-
Struts 2 (MVC)
-
iBATIS 2.3.4.726 (SQL Mapper)
-
Direct Web Remoting 2.0.5 (DWR)
-
SiteMesh 2.4 (Layout)
-
Quartz 1.6.4 (Scheduler)
-
JExcelApi 2.6.9 (MS Excel)
-
Log4J 1.2.15 + Jakarta Commons Logging(JCL) 1.1.1 (Logging)
-
Apache Commons - DBCP, BeanUtils, Collections, etc…
-
FCKeditor 2.4.1 (Rich Text Editor)
-
-
AJAX & Javascript Libs
-
Prototype JavaScript framework, version 1.6.0.2
-
The Yahoo! User Interface Library (YUI)
-
라이브러리와 여타 종속성이 있는 라이브러리들을 포함하다 보니, lib 디렉토리가 적잖게 비대해진 면이 있다.
이슈
라이브러리의 조합은 무척 일반적인데 비해, 구현 일정에 있어서 개개인의 노력도와 투자한 시간에 반하여 전반적으로 개발 퍼포먼스가 나지않는 것이 큰 이슈가 되었다. 표준과 개발 가이드가 미비하고 공통 관련 구현체 및 개발 구조의 완성도가 미흡한 상태에서 급하게 개발에 착수한 것이 역시 독이 되었다. 여기서 비롯된 구조적인 결함과 취약점들이 원인이 되어 개발자들에게 혼란을 초래하고 기술적인 진입장벽을 형성하였고 결국 개발 생산성과 효율이 극도로 저하되었다.
주목할 만한 것은 Spring 기반 위에서 Struts의 Action, 비즈니스를 수행하는 Service, DAO 및 iBATIS SqlMap, 그리고 Model을 아우르는 구현부와 설정들에 있어서는 비교적 손쉽고 안정적으로 개발이 진행된 반면, 상대적으로 UI 단을 개발함에 있어서 단연 부하가 심했다는 사실이다. 계층화된 아키텍처로 Presentation(UI) Layer, Service(Business Logic) Layer, Persistence(Data Access) Layer 등 크게 세 계층으로 구분할 때 개인적으로 판단해보건데, P/T Layer을 개발하는데 60% 이상의 공수가 걸리지 않았을까 싶을 정도다. 웹 개발의 특성상 UI에 잔손이 많이 가는 것은 어쩔 수 없는 부분이지만 이클립스에 업무 핵심인 비즈니스 로직과 관련 쿼리를 작성하기 위해 자바 소스나 XML 파일을 열어놓기 보다는 UI 코드를 작성하기 위해 JSP나 JS 파일을 띄워놓는 시간이 단연 많았다.
대부분의 UI 이벤트를 처리하기 위해서 Ajax 및 DWR이 사용되어 javascript에 대한 의존도가 높아진 반면, 개발자 대부분이 상대적으로 Ajax 및 객체지향적인 스크립트에 대한 경험이 취약한 상태였다. 게다가 개발 템플릿으로 만들어진 개별 페이지의 구조가 다소 일반적이지 않은 모양새였는데, 페이지 구조에 일관성을 부여하고 페이지에서 발생할 수 있는 대부분의 기능(script)를 공통화하여 개발 편의를 증대하고자 한 것이 결과적으로 득보다는 실을 가져다 준 셈이었다.
페이지의 구조에 대해서 좀더 자세히 얘기를 하자면 먼저 구현한 페이지의 형태에 대한 이해가 필요하다.
충분히 응용될 수 있지만 일반적이지는 않은 페이지 구조이다. Main이 되는 JSP에는 검색, 목록, 상세, 등록, 수정, 삭제 등과 관련한 각각의 UI 요소 및 Form들을 포함하기 위한 영역으로 정의된 Place Holder(DIV)들이 위치한다. 각 영역에는 목록, 상세, 등록, 수정 등의 JSP Fragment(*.jspf)들이 템플릿화 되어 삽입(include)되어진다. 이 형태를 기본 페이지 레이아웃으로 하여 각각의 단위업무 기능에 따라 첨삭이 가해졌다.
쉽게 얘기해서 목록 페이지 따로, 등록(수정) 페이지 따로가 아니라 메인 페이지가 검색, 목록, 상세, 등록, 수정, 삭제 등 각 기능별 템플릿들을 모두 미리 포함(로드)한 상태에서 사용자 액션(이벤트)에 따라 Place Holder 들에 대한 visible 속성 및 필요한 제어 로직을 갖는 구조이다. 사용자 액션에 의해 Request가 발생하면 비동기 방식으로 서비스를 호출(Ajax call)하게 되고, 서비스(Struts Action 및 비즈니스 수행부, DAO 등을 포괄)를 수행 후 result에 따라 XML 형태의 뷰(view) 페이지를 Ajax의 callback method에서 전달받아 jspf 템플릿에 데이터를 주입(치환)하는 방식이다. 완전히 일치하지는 않지만 기본적인 흐름은 다음 그림과 유사하다.
어쨌든 이러한 페이지 구조는 정형화되고 일반적인 패턴의 화면은 아주 쉽고 빠르게 구현할 수 있었지만, 화면의 복잡도가 증가하고 예외적인(다소 일반적이지 못한) UI 유형을 포함하게 될 때에는 처리가 복잡해지고 더불어 몇가지 제약사항을 야기시켰다. 결과적으로 개발자들은 주로 UI의 요소를 컨트롤하고 이벤트를 처리하기 위한 script block과 씨름하는 것에 대부분의 시간을 할애하게 되었다. 또한 Ajax 결과로 Struts에서 View로 넘어온 XML 데이터를 UI 템플릿의 대응하는 위치에 치환하는 작업도 개발자들이 어려워한 부분이었다. 특히 단건의 데이터가 아닌 복합적인 Collection의 형태로 넘어온 목록 데이터를 반복하여 보여주는 처리를 난감해 하였다. 이것은 XML 데이터를 템플릿상의 동일 ID항목으로 치환해주는 공통 script가 갖는 한계점도 있었고, Service, Action, Dao 등의 Base class들과 기타 관련 class 들의 구조, 그리고 Struts Value Stack에 대한 개발자들의 이해가 부족했던 것이 주요한 원인으로 작용하였다.
정리
최근 몇년간의 프로젝트에서는 직접 제반 개발 환경을 세팅하고, 프레임워크를 구현하고, 개발 구조를 정의하고, 개발을 가이드하는 등의 역할을 수행해왔다(프레임워크는 주로 오픈소스를 조합하여 구성). 그런데 이 프로젝트의 경우, 구현 일정이 워낙 촉박한 데다 업무의 특성을 고려하다보니 해당 업무를 전문으로 하는 업체에서 노하우가 녹아있는 완성도 있는 컴포넌트와 솔루션을 들고 들어와서 함께 구축하는 방향으로 급선회하게되었다.
그런데 이것이 애초의 기대한 바와는 다른 부분이 적지 않았다. 개발 사상적인 시각에서도 협력사의 개발자와 약간의 차이가 있었다. 이러한 부분을 극복하기 위해 개발과 병행하여 기본이 되는 코드와 구조를 꾸준히 리뷰하면서 개선할 점을 논의하고 반영해 나갔다. 그렇지만 근본 틀을 바꿀 수는 없는 상황이라 여전히 한계가 있었다. 문제가 된 페이지의 구조와 Ajax 위주의 개발 패턴 역시, 이미 많은 것들이 이들을 기반으로 맞물려 돌아가는 상황이라 들어낼 수는 없는지라 대안으로 복잡한 화면 처리를 위한 유형을 하나 더 패턴화시키는 정도로 처리하였다.
정리하자면, 필요에 따라 응용할 수 있는 페이지의 구조를 오히려 전체 페이지에 대한 표준으로 일반화시킨 것과 지나치게 Ajax 기반으로 처리하는 개발 패턴이 구현상의 가장 큰 오류가 아니었나 싶다. 프로젝트에서 철수하고 더더욱 확신이 드는 생각이 두가지 있다. 하나는 "일반적인 것이 좋은 개발 구조"라는 것이다. "일반적"이라는 것에 대한 정의가 모호해질 수 있겠지만, 어떤 개발자들이 붙더라도 쉽게 적응하고 응용할 수 있도록 진입장벽을 낮추고 잘 구조화 시켜야한다. 덧붙여 일반적이라는 것이 품질 또한 일반적일 것을 보장할 것이라 생각하지는 않는다. 확신의 또다른 한가지는 "과유불급". 지나친 것은 좋지 않다는 것이다. 이를테면 Ajax가 UI의 가능성과 유연성을 높이는데 도움이 되는 것은 사실이지만 이것이 전체 이벤트를 제어하는 메인 기술이 되어서는 안된다는 생각이 든다. 필요한 부분에 적절히 사용되어야 한다.
대강 정리를 해보았지만 한편으로는 프레임워크와 스트럭처를 조금더 보완하고, 개발 전에 아키텍처의 컨셉과 개발 절차 및 응용 단계에 대해서 개발자들과 충분히 공유할 수 있었다면, 몇가지 단점들을 충분히 상쇄(trade-off)할 수 있는 장점도 있지 않을까 싶기도 하다(이를 설명하자면 전체 개발 구조에 대해서 좀더 이해해야 할 내용들이 많아진다). 협력사의 인력들도 중고급 이상으로 구성된 상당한 고수들이었고, 고심해서 작업한 흔적이 전체적으로 역력했다. 적용한 프레임워크와 개발 구조에 대해서는 쉽게 평가하기 전에 좀더 고민해볼 부분 많을 것으로 생각한다. 다만 한가지 확실한 것은 시도는 좋았지만, 실험정신을 발휘하기엔 시기가 적절하지 않았다는 것이다.
P.S.
지난 프로젝트의 성패를 떠나서 여러가지 관점에서 시사하는 바가 적지않다. 경험이 쌓여가는 것과는 무관하게 여전히 배워야할 것도, 공부해야할 것들도 많다. 반성해야할 것도 많고 인간적으로도 좀더 성숙해야 되지 않을까 싶기도 하다. 개인적으로 그동안 개발 방법론적인 부분에 있어서도 부족함이 많았는데, Agile 개발 프로세스나 XP(Extreme Programming), TDD 등 연구하고 적용해볼 분야가 많음을 새삼 느껴본다.
뜨거운 청춘들과 가정이 있는 사람들이 개인사와 가족을 뒤로 하고 했던 고생들이 그저 고생으로 끝나고 남는것이 없지 않기를 바란다. 문제점이 없진 않았지만, 시행착오를 통해 나를 비롯해 다들 조금더 성숙한 개발자가 될 수 있는 계기가 될 수 있기를 진심으로 바란다.
후기랄 것도 없이 종료한 프로젝트에 대한 간단한 감상이나 적어보려고 했는데, 쓸데없이 글이 길어졌다. -_-
"Development Story" 카테고리의 다른 글
- WYSIWYG Web Editors (댓글 2개 / 트랙백 0개) 2009/12/16
- 개발자들도 헷갈리는 몇가지 용어들 (댓글 5개 / 트랙백 0개) 2009/10/27
- Maven 설치 요약 (Windows) (댓글 2개 / 트랙백 0개) 2009/10/27
- 프로젝트 후기 (댓글 2개 / 트랙백 0개) 2009/10/05
- Programming Fonts - 나눔고딕코딩 글꼴 등 (댓글 7개 / 트랙백 1개) 2009/09/18














Comments
정말 고생 많이 하셨습니다.
그만큼 뭔가 많은 것을 얻으신듯합니다.
많은 다양한 라이브러리들도 사용하시고...
java를 하지 않았던 저의 입장에선 참 많이 배워야 겠다는 생각이 드는군요~
(뭔소린지 잘 모르겠습니다... ㅋ)
상반기엔 다들 바뻤던 것 같아. ^^
이사 준비 잘 하시고, 집들이 언넝 해야쥐?! ㅋ~
참고로 이미 오래전부터...
Spring은 Spring.NET으로,
iBAITS는 iBATIS.NET으로,
Hibernate는 NHibernate로
포팅되어 있었네... :)