검색결과 리스트
프레임워크에 해당되는 글 6건
- 2010/02/10 다른 관점의 프레임워크
- 2009/09/25 프레임워크 하위 호환성 검증 방법
- 2009/04/04 애플리케이션 프레임워크 설계 원칙과 리팩토링(하) (4)
- 2009/04/03 애플리케이션 프레임워크 설계 원칙과 리팩토링(중)
- 2009/04/02 애플리케이션 프레임워크 설계 원칙과 리팩토링(상)
- 2007/03/22 프레임워크의 인터페이스(API) (1)
글
다른 관점의 프레임워크
2010
2010/02/10 08:30
개념도 그릴 일이 생겨서 검색하다가 찾은 그림들... 평소 익숙한 애플리케이션 프레임워크 외에 조금 생소한 관점의 프레임워크 그림을 남겨본다. 새로운 것을 배우기 위해 가끔은 익숙지 않은 관점을 이해해야 한다.
감리 프레임워크(?)
출처: http://checkerslab.com/18

출처 미상인데, 방송통신쪽 서비스 프레임워크인 듯

출처: http://column.inews24.com/php/news_view.php?g_menu=041011&g_serial=90577
점차 친근한 녀석으로 바뀌지만... 그림이 이뻐서..
다시 생소한 프레임워크
기업내ㆍ기업간 가치사슬을 고려한 지원 정책 프레임워크
출처: http://mctwide.kmac.or.kr/c/portal/layout?p_l_id=PUB.1.982

매킨지 7S 프레임워크/모델
출처: http://ahntaehyuck.tistory.com/188
글
프레임워크 하위 호환성 검증 방법
2009 이야기
2009/09/25 20:44
예전 버전의 프레임워크로 개발 중인 사이트가 있다고 하자. 해당 프레임워크의 새로운 버전을 사용해도 문제가 없음을 즉, 하위 호환성을 검증할 방법은 무엇이 있을까?
흔히 사용하는 방법은 이미 개발한 애플리케이션에 프레임워크를 바꿔 넣고 기능이 잘 수행하는지 보는 일이다. 우선, 프로그래밍에 의한 API 불일치는 컴파일부터 문제가 생긴다. 그렇지만, 인터페이스는 같지만 다르게 작동하면 검출이 쉽지 않을 수 있다. 이럴 때 차곡차곡 모아둔 회귀 테스트는 보험으로 쓰일 수 있다. 물론, 효용성(coverage, test case 적합성 등)에 따라 효과는 크게 달라진다.
얼마 전 프레임워크 개발자와 프로젝트에 프레임워크를 적용하는 동료가 호환성에 문제가 없다고 한 이야기를 덜컥 믿어 버리는 우를 범했다. 만 하루도 지나지 않아 문제가 드러났다. 표면으로 드러나 현상은 화면 그리드에 특정 칼럼에만 데이터가 나타났다. 개발자는 코드를 고친 일이 없다. 데이터 역시 그대로다. 개발자가 판단하기엔 귀신이 곡할 노릇이다. 더구나 개발서버가 아닌 로컬PC에선 잘 돌아간다. 알고 보니 개발서버엔 테스트를 마친 새로운 버전의 프레임워크와 설정을 반영했고, 개발자PC에선 아직 저장소와 동기화를 하지 않은 상태였다.
원인을 찾아보니 암묵적인 API 호환성을 놓쳤다. 각기 다른 작명 지침(naming convention)을 쓰는 테이블 컬럼과 객체 속성을 바인딩할 때 약속한 바와 다르게 구현한 부분이 있었다. 다행히 개발 초기부터 자동화 테스트와 화면을 띄워 진행하는 기능 테스트를 병행하고 있어 개발팀에서 본의 아니게 빠르게 문제를 보고해주었다. 한편으로는 빠른 테스트의 효과를 실감할 수 있었지만, 하위 호환성에 대한 검증 방법을 돌아보게 했다.
툴킷 수준의 검증 도구까지는 아니더라도 점검 목록(check list)도 없이 프레임워크 하위 호환성을 검증한 일은 바람직한 절차는 아니다. 당장 뾰족한 묘안이 있지는 않지만, 담당자끼리는 상황 인식을 공유했다. 일 회로 그만두는 활동이 아니라면 다음번에는 더 나아져야 하기 때문이다.
이야기를 쓰다보니 얼마전 비즈니스 패키지 설치 검증 방안에 대해 협의했던 기억이 떠올랐다. 비즈니스 기능을 탑재한 솔루션의 정상적인 설치와 작동을 어떻게 보장할 수 있을까? 나아가 인수 담당자가 어떻게 안심하고 검수 사인을 할 수 있을까?
기억이 정확하지 않지만 아마도 협의 끝에 몇 가지 산출 값을 지표로 삼고, 특정 모듈과 테이블 존재 여부 등을 점검 항목으로 정리했다. 그리고 생각했다. 만일 해당 패키지에 회귀 테스트가 가능한 테스트 스위트가 있다면 훨씬 나았으리라 생각했다. 최소한 기능 작동까지는 아니더라도 설치 후에 테이블 존재 여부, 모듈 존재 여부, 초기 데이터 존재 상황 등은 쉽게 자동 확인이 가능하다.
흔히 사용하는 방법은 이미 개발한 애플리케이션에 프레임워크를 바꿔 넣고 기능이 잘 수행하는지 보는 일이다. 우선, 프로그래밍에 의한 API 불일치는 컴파일부터 문제가 생긴다. 그렇지만, 인터페이스는 같지만 다르게 작동하면 검출이 쉽지 않을 수 있다. 이럴 때 차곡차곡 모아둔 회귀 테스트는 보험으로 쓰일 수 있다. 물론, 효용성(coverage, test case 적합성 등)에 따라 효과는 크게 달라진다.
얼마 전 프레임워크 개발자와 프로젝트에 프레임워크를 적용하는 동료가 호환성에 문제가 없다고 한 이야기를 덜컥 믿어 버리는 우를 범했다. 만 하루도 지나지 않아 문제가 드러났다. 표면으로 드러나 현상은 화면 그리드에 특정 칼럼에만 데이터가 나타났다. 개발자는 코드를 고친 일이 없다. 데이터 역시 그대로다. 개발자가 판단하기엔 귀신이 곡할 노릇이다. 더구나 개발서버가 아닌 로컬PC에선 잘 돌아간다. 알고 보니 개발서버엔 테스트를 마친 새로운 버전의 프레임워크와 설정을 반영했고, 개발자PC에선 아직 저장소와 동기화를 하지 않은 상태였다.
원인을 찾아보니 암묵적인 API 호환성을 놓쳤다. 각기 다른 작명 지침(naming convention)을 쓰는 테이블 컬럼과 객체 속성을 바인딩할 때 약속한 바와 다르게 구현한 부분이 있었다. 다행히 개발 초기부터 자동화 테스트와 화면을 띄워 진행하는 기능 테스트를 병행하고 있어 개발팀에서 본의 아니게 빠르게 문제를 보고해주었다. 한편으로는 빠른 테스트의 효과를 실감할 수 있었지만, 하위 호환성에 대한 검증 방법을 돌아보게 했다.
툴킷 수준의 검증 도구까지는 아니더라도 점검 목록(check list)도 없이 프레임워크 하위 호환성을 검증한 일은 바람직한 절차는 아니다. 당장 뾰족한 묘안이 있지는 않지만, 담당자끼리는 상황 인식을 공유했다. 일 회로 그만두는 활동이 아니라면 다음번에는 더 나아져야 하기 때문이다.
이야기를 쓰다보니 얼마전 비즈니스 패키지 설치 검증 방안에 대해 협의했던 기억이 떠올랐다. 비즈니스 기능을 탑재한 솔루션의 정상적인 설치와 작동을 어떻게 보장할 수 있을까? 나아가 인수 담당자가 어떻게 안심하고 검수 사인을 할 수 있을까?
기억이 정확하지 않지만 아마도 협의 끝에 몇 가지 산출 값을 지표로 삼고, 특정 모듈과 테이블 존재 여부 등을 점검 항목으로 정리했다. 그리고 생각했다. 만일 해당 패키지에 회귀 테스트가 가능한 테스트 스위트가 있다면 훨씬 나았으리라 생각했다. 최소한 기능 작동까지는 아니더라도 설치 후에 테이블 존재 여부, 모듈 존재 여부, 초기 데이터 존재 상황 등은 쉽게 자동 확인이 가능하다.
글
애플리케이션 프레임워크 설계 원칙과 리팩토링(하)
2009 이야기
2009/04/04 11:30
리팩토링의 당위성
리팩토링은 분명 중요한 작업이지만, 관리자나 고객 입장에선 눈에 보이지 않는 작업이다. 구조적 개선은 가시적인 결과를 보여주기 힘들기 때문이다. 기능을 추가한다거나 버그를 수정한다면 누가 봐도 목적이 분명하다. 그러나 리팩토링의 경우는 부가적인 개선으로 보일 수 있다. 사실 기능적으로만 놓고 보면 리팩토링 전후에 차이가 없으므로 부가적이란 표현도 틀리지 않다. 사정이 그렇다 보니 리팩토링은 뒷전으로 밀릴 수 있다. 경우에 따라 코드 개선 활동으로 긴 작업 시간을 소비한다면 무능한 사람 취급할 수도 있다.
린 소프트웨어 개발(Lean Software Development)의 주요 원칙은 리팩토링의 중요성에 대해 시사하는 바가 크다. 품질을 내재화하라는 원칙을 설명하는 내용에서 다음과 같은 글을 발견할 수 있다.
그럼에도 불구하고 관리자의 인식이 다를 수 있다. 린 소프트웨어 개발에서 소개한 하버드 비즈니스 스쿨의 앨런 맥코맥(Alan MacComack)의 연구는 시사하는 바가 크다. 최적의 설계를 갖고 있었고 그렇게 만들어진 시스템이 초기 명세와 매우 가까운 ‘좋은’ 프로젝트와 개발팀이 시장의 변화를 이해하고 대응하기 위해 싸우는 동안 계속되는 변화를 겪은 ‘나쁜’ 프로젝트를 비교하는 연구인데, 놀랍게도 회사의 관리자들은 시장에 대해 계속해서 학습하고 시장을 만족시키는 제품을 만들어내는 프로젝트를 ‘나쁜’ 것으로 생각했다.
그렇지만, 무턱대고 관리자의 통념이 깨지기를 기다려서 리팩토링을 할 수는 없는 일이다. 필자가 만나본 어떤 조직에서는 새로운 기술 표준에 맞춰 대대적인 내부 솔루션 변경을 하는 경우에도 경영진을 설득하지 못해 실적으로 보고할 수도 없는 유령 작업을 하느라 고생한 일이 있다고 했다.
그림 6은 리팩토링을 통해 코드량을 줄인 성과를 도표로 나타낸 자료다. 종종 관리자와 경영진 설득을 위해 리팩토링 효과를 정량화 하는 노력이 필요하기도 하다.
전체를 최적화하라
다시 한번 린 소프트웨어 개발의 일부를 인용한다.
안타깝게도 아마 많은 국내 개발자에게도 익숙한 이야기로 들릴 듯하다. 빠른 기능 구현이 능사는 아니다. 만일 코드를 검증하지 않은 상태라면 더욱 그렇다. 설령 기능의 정상 작동은 모두 검증했다고 하더라도 리팩토링을 하지 않아 중복이 늘고, 복잡도가 높아지면 쉽게 버그를 유발할 수 있고, 수정을 어렵게 해 결과적으로 생산성을 악화시킨다.
변화는 자연의 법칙
XP의 대가 론 제프리스(Ron Jeffries)는 리팩토링이 필수냐는 질문에 단호하게 그렇다고 답한다.1 론 제프리스에 따르면 소프트웨어 진화가 곧 리팩토링을 통해 이뤄진다고 한다. 피할 수 없는 문제를 자꾸 막으려고 한다면 도태할 수 있다. 오히려 이를 적극적으로 수용하고, 변화에 빠르게 대처할 수 있도록 품질을 내재화 하는 길을 택한다면 리팩토링은 성공적인 도구로 쓰일 수 있다.
종종 코드 리팩토링을 우리의 일상 활동과 구분하다 보면 당연한 사실을 잊어버리곤 한다. 아래 그림은 모 프로젝트 초기 필자의 디렉토리 구성이다.

리팩토링은 분명 중요한 작업이지만, 관리자나 고객 입장에선 눈에 보이지 않는 작업이다. 구조적 개선은 가시적인 결과를 보여주기 힘들기 때문이다. 기능을 추가한다거나 버그를 수정한다면 누가 봐도 목적이 분명하다. 그러나 리팩토링의 경우는 부가적인 개선으로 보일 수 있다. 사실 기능적으로만 놓고 보면 리팩토링 전후에 차이가 없으므로 부가적이란 표현도 틀리지 않다. 사정이 그렇다 보니 리팩토링은 뒷전으로 밀릴 수 있다. 경우에 따라 코드 개선 활동으로 긴 작업 시간을 소비한다면 무능한 사람 취급할 수도 있다.
린 소프트웨어 개발(Lean Software Development)의 주요 원칙은 리팩토링의 중요성에 대해 시사하는 바가 크다. 품질을 내재화하라는 원칙을 설명하는 내용에서 다음과 같은 글을 발견할 수 있다.
소프트웨어 개발에서 낭비를 제거하는 최고의 방법을 다시 살펴보자. “코드를 더 적게 짜라.” 코드를 더 적게 짜기 위해서는 가치의 80%를 제공하는 20%의 코드를 발견하여 그것을 먼저 개발해야 한다. 이런 식으로 다음 기능을 추가하다가 기능 추가에 따른 비용보다 얻게 되는 가치가 더 적은 경우에 작업을 멈춘다. 기능을 추가할 때는 코드를 간결하게 하고 결함이 없게 유지해야 하며 그렇지 못하면 복잡도가 곧 여러분을 위협할만한 수준으로 높아질 것이다. 그래서 우리는 새로운 기능을 추가하기 위해 설계를 리팩토링하여 코드베이스를 간결하게 유지하고, 소프트웨어의 가장 큰 적인 ‘중복’을 제거한다. 이것은 기존 코드를 늘 수정해야 한다는 것을 의미한다.
린 소프트웨어 개발의 적용, 메리 포펜딕, 톰 포펜딕, 32p
린 소프트웨어 개발의 적용, 메리 포펜딕, 톰 포펜딕, 32p
그럼에도 불구하고 관리자의 인식이 다를 수 있다. 린 소프트웨어 개발에서 소개한 하버드 비즈니스 스쿨의 앨런 맥코맥(Alan MacComack)의 연구는 시사하는 바가 크다. 최적의 설계를 갖고 있었고 그렇게 만들어진 시스템이 초기 명세와 매우 가까운 ‘좋은’ 프로젝트와 개발팀이 시장의 변화를 이해하고 대응하기 위해 싸우는 동안 계속되는 변화를 겪은 ‘나쁜’ 프로젝트를 비교하는 연구인데, 놀랍게도 회사의 관리자들은 시장에 대해 계속해서 학습하고 시장을 만족시키는 제품을 만들어내는 프로젝트를 ‘나쁜’ 것으로 생각했다.
그렇지만, 무턱대고 관리자의 통념이 깨지기를 기다려서 리팩토링을 할 수는 없는 일이다. 필자가 만나본 어떤 조직에서는 새로운 기술 표준에 맞춰 대대적인 내부 솔루션 변경을 하는 경우에도 경영진을 설득하지 못해 실적으로 보고할 수도 없는 유령 작업을 하느라 고생한 일이 있다고 했다.
그림 6은 리팩토링을 통해 코드량을 줄인 성과를 도표로 나타낸 자료다. 종종 관리자와 경영진 설득을 위해 리팩토링 효과를 정량화 하는 노력이 필요하기도 하다.
전체를 최적화하라
다시 한번 린 소프트웨어 개발의 일부를 인용한다.
악순환 1번
린 소프트웨어 개발의 적용, 메리 포펜딕, 톰 포펜딕, 42~43p
고객이 ‘어제’ 느닷없이 새로운 기능을 이야기한다.
개발자에게 이렇게 전달된다. “비용이 얼마가 들더라도 빨리 끝내도록!”
결과: 코드베이스에 조잡한 변경이 가해진다.
결과: 코드베이스에 복잡도가 증가한다.
결과: 코드베이스에 결함수가 증가한다.
결과: 기능을 추가하는데 들어가는 시간이 기하급수적으로 증가한다.
개발자에게 이렇게 전달된다. “비용이 얼마가 들더라도 빨리 끝내도록!”
결과: 코드베이스에 조잡한 변경이 가해진다.
결과: 코드베이스에 복잡도가 증가한다.
결과: 코드베이스에 결함수가 증가한다.
결과: 기능을 추가하는데 들어가는 시간이 기하급수적으로 증가한다.
악순환 2번
테스팅 업무가 과중하다.
결과: 테스팅이 코딩보다 한참 뒤에 이뤄진다.
결과: 개발자가 피드백을 즉시 얻지 못한다.
결과: 개발자가 결함을 더 많이 발생시킨다.
결과: 테스팅 업무가 더 많아진다. 시스템에 결함이 더 많아진다.
결과: 피드백이 더 지연된다. 이것이 반복된다.
결과: 테스팅이 코딩보다 한참 뒤에 이뤄진다.
결과: 개발자가 피드백을 즉시 얻지 못한다.
결과: 개발자가 결함을 더 많이 발생시킨다.
결과: 테스팅 업무가 더 많아진다. 시스템에 결함이 더 많아진다.
결과: 피드백이 더 지연된다. 이것이 반복된다.
린 소프트웨어 개발의 적용, 메리 포펜딕, 톰 포펜딕, 42~43p
안타깝게도 아마 많은 국내 개발자에게도 익숙한 이야기로 들릴 듯하다. 빠른 기능 구현이 능사는 아니다. 만일 코드를 검증하지 않은 상태라면 더욱 그렇다. 설령 기능의 정상 작동은 모두 검증했다고 하더라도 리팩토링을 하지 않아 중복이 늘고, 복잡도가 높아지면 쉽게 버그를 유발할 수 있고, 수정을 어렵게 해 결과적으로 생산성을 악화시킨다.
변화는 자연의 법칙
XP의 대가 론 제프리스(Ron Jeffries)는 리팩토링이 필수냐는 질문에 단호하게 그렇다고 답한다.1 론 제프리스에 따르면 소프트웨어 진화가 곧 리팩토링을 통해 이뤄진다고 한다. 피할 수 없는 문제를 자꾸 막으려고 한다면 도태할 수 있다. 오히려 이를 적극적으로 수용하고, 변화에 빠르게 대처할 수 있도록 품질을 내재화 하는 길을 택한다면 리팩토링은 성공적인 도구로 쓰일 수 있다.
종종 코드 리팩토링을 우리의 일상 활동과 구분하다 보면 당연한 사실을 잊어버리곤 한다. 아래 그림은 모 프로젝트 초기 필자의 디렉토리 구성이다.
- http://xprogramming.com/blog/2009/02/06/why-is-refactoring-a-must/ [본문으로]
글
애플리케이션 프레임워크 설계 원칙과 리팩토링(중)
2009 이야기
2009/04/03 08:30
설계 원칙 강화에 효과적인 동료 검토
필자의 프레임워크 개발 프로젝트에서 초기에는 품질 보증 활동을 했으나, 프로젝트가 중반 이후로 접어들자 품질 보증은 점차 큰 부담이 되었다. 품질 보증 담당자가 다수의 개발자가 만드는 프레임워크 전체를 이해하고 코드가 적절한지 판단하기 힘들어졌다. 품질 검토를 누락한 부분은 이후에 고스란히 유지보수가 어려운 부분으로 남았다. 개발자가 유지보수 담당자와 같거나 같은 조직에 속하는 경우에는 덜하지만, 개발만 하고 빠지는 외주 개발에서 품질 보증이 소홀한 경우를 흔히 볼 수 있다. 예산과 납기라는 제약이 있기 때문에 어떤 프로젝트든 타협을 한다. 그렇기 때문에 품질 보증 수준과 미흡한 부분에 대한 향후 대책이 중요하다.
우리 팀은 프레임워크 배포 이후에 프레임워크를 적용하면서 새로운 요구사항에 수렴하면서 프레임워크를 진화시키는 프로젝트를 수주했다. 프로젝트 초기 우리가 가장 먼저 한 활동은 리팩토링이었다. 이미 프레임워크를 배포한 상태이므로 API 수정은 어려웠지만, 내부 개선에는 지장이 없었다. 코드가 간결해지고, 전체적으로 일관성이 높아졌다. 아쉽게도 앞선 프로젝트와 동일한 팀원으로만 구성할 수 없어서 다른 사람이 작성한 코드를 리팩토링 해야 할 때, 난이도가 높거나 별도 지식이 필요한 솔루션 연계를 다룬 경우라면 손을 대기 힘들거나 많은 시간을 요했다.
만일 타임머신을 타고 과거로 돌아간다면 프로젝트 관리자 혹은 팀장으로서 어떻게 조치할 수 있을까? 짝 프로그래밍(Pair Programming)을 시도해보고 싶다. 이전에도 시도는 했다. 그러나 10주 만에 고객에게 무언가 입증해내야 하는 부담이 있어 포기했다. 팀 문화를 바꾸는 일은 단기에 이룰 수 없다. 그렇다고 해도 짝 프로그래밍을 시도하면서 점차 팀에 어울리는 방법으로 바꿔갈 수 있을 것이다. 가령, 빈번한 동료 검토 수준으로 완화할 수도 있다. 분명한 점은 코드 수준에서라면 품질보증 담당자를 별도로 두는 방식보다는 단위 테스트 그리고 동료 검토가 효과적이란 사실이다. 협업을 강조하는 애자일, XP 진영에서는 짝 프로그래밍 이외에도 시도해 볼만한 많은 프랙티스를 제시한다.
인수인계를 활용한 체계 강화
인수인계시점은 설계 원칙 구현 정도를 점검하고, 강화할 수 있는 기회이기도 하다. 이 글은 주로 프레임워크 개발자와 유지보수 담당자 사이의 인수인계를 배경으로 하지만, 선임자와 후임자 사이에서도 크게 다르지 않다.
필자는 인수인계시점에 다음과 같은 3계층으로 우리가 만든 산출물을 분류해 인식하기로 했다. 어떤 내용은 프레임워크 사용자 수준에서 개략적인 논의를 하는데 도움이 된다. 가령, 제품 설명서 내용이나 가이드 서두의 개요 등이 여기에 해당한다. 프레임워크를 유지보수 하는 개발자나 프레임워크를 특정 상황에 맞게 수정하는 개발자라면 다른 정보를 필요로 한다. 어떤 API를 수정해야 하는지 정도는 필수 정보이고, 정상적으로 작동하도록 수정하기 위해서는 단순히 확장 지점에 대한 이해만으로 부족한 경우가 있다. 프레임워크가 구동하는 주요 메커니즘은 알아야 한다. 특정 부분 메커니즘에 대해서는 아주 세밀하게 알아야 할 수도 있다. 이를 위한 설계 방안과 구현 및 테스트 코드를 모든 기능마다 구비하고 정리해둘 수 있을까?
경제성을 고려하지 않는다면 가능하다고 하겠지만, 대개의 경우 실용적인 방법이 아니다. 우리는 먼저 코드를 논리적으로 적절히 나누어서 인수인계 일정을 수립했다. 그리고 코드 작성자가 주안점으로 삼을 사항을 기록하여 인수인계 받을 담당자에게 전달했다. 주안점을 중심으로 인수인계를 받으면서 코드를 이해하고, 향후 요구사항이 있을 경우 확장할 부분 그리고 확장 방안을 습득하게 했다. 설계 메커니즘 설명이나 확장 방안은 먼저 변수나 메소드 이름 수준에서 리팩토링을 수행해 가능한 코드 수준에서 이해할 수 있게 한다. 변수나 메소드 이름을 변경해도 난해한 부분 중에 하나 이상의 복잡한 문제를 함께 해결하려 하는 코드가 있다면 하나의 역할만 하도록 변경한다. 이쯤에서 머리도 식힐 겸 쉬운 비유를 하나 들어보겠다. 영화감상을 통해 영어공부를 하는 방식은 효과적일까? 대개는 그렇지 않은데, 그 이유는 다음 그림에서 보는 바와 같다.

시작은 영어 공부로 했어도 영화에 빠져 영어 듣기는 뒷전이 될 수 있다. 자칫 여배우의 외모에 혹해 아예 영어 공부는 안중에도 없어질 수 있다. 비유가 프레임워크와 너무 동떨어져있다고 생각하는가? 그렇다면 위 그림에 대입할 수 있는 코드 예제를 떠올려보자. 만일 XML 파일과 함께 HTTP요청을 수신하는 서버 클래스 로직을 생각해보자. 요청을 수신한 클래스1에서 요청 내용을 확인해 적절한 클래스로 보내는 작업을 하는데 XML 파일을 읽어 데이터를 적절한 형태로 변경하는 로직까지 담당한다면 어떨까? 엄청나게 긴 코드로 인해 해당 클래스의 역할에 대해 인지하기도 힘들고, 그에 따라 수정 역시 어려워진다. 리팩토링을 통해 하나의 클래스에 하나의 역할만 부여했다고 해도 복잡한 선택에 따라 if-else 코드를 피할 수 없는 경우가 발생한다. 이 경우는 조건에 따라 달라지는 내용에 대해 API 설명(javadoc 주석)으로 설명하게 하고, 여러 객체에 걸쳐서 설명할 부분이라면 그때 비로소 설계 가이드 혹은 확장 가이드에 설명하도록 했다. 기계적인 표준화에 따라 작성하는 경우 종종 불필요하거나 중요하지 않은 내용마저도 많은 분량의 가이드로 남는다. 종종 이는 유지보수 부담을 준다. 게다가 내용이 지나치게 많으면 중요한 내용을 찾는데 방해가 되기도 한다. 이와 같이 체계 수립은 별도의 소수의 인력 위주로 진행하기 보다는 체계를 유지해야 할 사람이 직접 참여하는 것이 효과적이다.
필자의 프레임워크 개발 프로젝트에서 초기에는 품질 보증 활동을 했으나, 프로젝트가 중반 이후로 접어들자 품질 보증은 점차 큰 부담이 되었다. 품질 보증 담당자가 다수의 개발자가 만드는 프레임워크 전체를 이해하고 코드가 적절한지 판단하기 힘들어졌다. 품질 검토를 누락한 부분은 이후에 고스란히 유지보수가 어려운 부분으로 남았다. 개발자가 유지보수 담당자와 같거나 같은 조직에 속하는 경우에는 덜하지만, 개발만 하고 빠지는 외주 개발에서 품질 보증이 소홀한 경우를 흔히 볼 수 있다. 예산과 납기라는 제약이 있기 때문에 어떤 프로젝트든 타협을 한다. 그렇기 때문에 품질 보증 수준과 미흡한 부분에 대한 향후 대책이 중요하다.
우리 팀은 프레임워크 배포 이후에 프레임워크를 적용하면서 새로운 요구사항에 수렴하면서 프레임워크를 진화시키는 프로젝트를 수주했다. 프로젝트 초기 우리가 가장 먼저 한 활동은 리팩토링이었다. 이미 프레임워크를 배포한 상태이므로 API 수정은 어려웠지만, 내부 개선에는 지장이 없었다. 코드가 간결해지고, 전체적으로 일관성이 높아졌다. 아쉽게도 앞선 프로젝트와 동일한 팀원으로만 구성할 수 없어서 다른 사람이 작성한 코드를 리팩토링 해야 할 때, 난이도가 높거나 별도 지식이 필요한 솔루션 연계를 다룬 경우라면 손을 대기 힘들거나 많은 시간을 요했다.
만일 타임머신을 타고 과거로 돌아간다면 프로젝트 관리자 혹은 팀장으로서 어떻게 조치할 수 있을까? 짝 프로그래밍(Pair Programming)을 시도해보고 싶다. 이전에도 시도는 했다. 그러나 10주 만에 고객에게 무언가 입증해내야 하는 부담이 있어 포기했다. 팀 문화를 바꾸는 일은 단기에 이룰 수 없다. 그렇다고 해도 짝 프로그래밍을 시도하면서 점차 팀에 어울리는 방법으로 바꿔갈 수 있을 것이다. 가령, 빈번한 동료 검토 수준으로 완화할 수도 있다. 분명한 점은 코드 수준에서라면 품질보증 담당자를 별도로 두는 방식보다는 단위 테스트 그리고 동료 검토가 효과적이란 사실이다. 협업을 강조하는 애자일, XP 진영에서는 짝 프로그래밍 이외에도 시도해 볼만한 많은 프랙티스를 제시한다.
인수인계를 활용한 체계 강화
인수인계시점은 설계 원칙 구현 정도를 점검하고, 강화할 수 있는 기회이기도 하다. 이 글은 주로 프레임워크 개발자와 유지보수 담당자 사이의 인수인계를 배경으로 하지만, 선임자와 후임자 사이에서도 크게 다르지 않다.
필자는 인수인계시점에 다음과 같은 3계층으로 우리가 만든 산출물을 분류해 인식하기로 했다. 어떤 내용은 프레임워크 사용자 수준에서 개략적인 논의를 하는데 도움이 된다. 가령, 제품 설명서 내용이나 가이드 서두의 개요 등이 여기에 해당한다. 프레임워크를 유지보수 하는 개발자나 프레임워크를 특정 상황에 맞게 수정하는 개발자라면 다른 정보를 필요로 한다. 어떤 API를 수정해야 하는지 정도는 필수 정보이고, 정상적으로 작동하도록 수정하기 위해서는 단순히 확장 지점에 대한 이해만으로 부족한 경우가 있다. 프레임워크가 구동하는 주요 메커니즘은 알아야 한다. 특정 부분 메커니즘에 대해서는 아주 세밀하게 알아야 할 수도 있다. 이를 위한 설계 방안과 구현 및 테스트 코드를 모든 기능마다 구비하고 정리해둘 수 있을까?
경제성을 고려하지 않는다면 가능하다고 하겠지만, 대개의 경우 실용적인 방법이 아니다. 우리는 먼저 코드를 논리적으로 적절히 나누어서 인수인계 일정을 수립했다. 그리고 코드 작성자가 주안점으로 삼을 사항을 기록하여 인수인계 받을 담당자에게 전달했다. 주안점을 중심으로 인수인계를 받으면서 코드를 이해하고, 향후 요구사항이 있을 경우 확장할 부분 그리고 확장 방안을 습득하게 했다. 설계 메커니즘 설명이나 확장 방안은 먼저 변수나 메소드 이름 수준에서 리팩토링을 수행해 가능한 코드 수준에서 이해할 수 있게 한다. 변수나 메소드 이름을 변경해도 난해한 부분 중에 하나 이상의 복잡한 문제를 함께 해결하려 하는 코드가 있다면 하나의 역할만 하도록 변경한다. 이쯤에서 머리도 식힐 겸 쉬운 비유를 하나 들어보겠다. 영화감상을 통해 영어공부를 하는 방식은 효과적일까? 대개는 그렇지 않은데, 그 이유는 다음 그림에서 보는 바와 같다.
그림 5. 영어공부와 영화감상을 같이 하기
시작은 영어 공부로 했어도 영화에 빠져 영어 듣기는 뒷전이 될 수 있다. 자칫 여배우의 외모에 혹해 아예 영어 공부는 안중에도 없어질 수 있다. 비유가 프레임워크와 너무 동떨어져있다고 생각하는가? 그렇다면 위 그림에 대입할 수 있는 코드 예제를 떠올려보자. 만일 XML 파일과 함께 HTTP요청을 수신하는 서버 클래스 로직을 생각해보자. 요청을 수신한 클래스1에서 요청 내용을 확인해 적절한 클래스로 보내는 작업을 하는데 XML 파일을 읽어 데이터를 적절한 형태로 변경하는 로직까지 담당한다면 어떨까? 엄청나게 긴 코드로 인해 해당 클래스의 역할에 대해 인지하기도 힘들고, 그에 따라 수정 역시 어려워진다. 리팩토링을 통해 하나의 클래스에 하나의 역할만 부여했다고 해도 복잡한 선택에 따라 if-else 코드를 피할 수 없는 경우가 발생한다. 이 경우는 조건에 따라 달라지는 내용에 대해 API 설명(javadoc 주석)으로 설명하게 하고, 여러 객체에 걸쳐서 설명할 부분이라면 그때 비로소 설계 가이드 혹은 확장 가이드에 설명하도록 했다. 기계적인 표준화에 따라 작성하는 경우 종종 불필요하거나 중요하지 않은 내용마저도 많은 분량의 가이드로 남는다. 종종 이는 유지보수 부담을 준다. 게다가 내용이 지나치게 많으면 중요한 내용을 찾는데 방해가 되기도 한다. 이와 같이 체계 수립은 별도의 소수의 인력 위주로 진행하기 보다는 체계를 유지해야 할 사람이 직접 참여하는 것이 효과적이다.
- J2EE 패턴에서 Front Controller라고 한다. [본문으로]
글
애플리케이션 프레임워크 설계 원칙과 리팩토링(상)
2009 이야기
2009/04/02 08:57
본 내용은 월간 마소에 기고했던 내용이며, 월간 마소의 동의하에 공유합니다.
이 글은 애플리케이션 프레임워크 설계 원칙과 이를 확립하려는 방안, 그리고 그 목적으로 리팩토링을 이야기한다. 프레임워크를 쓰는 코드를 의인화해서 사용자로 본다면, 사용자마다 각자의 이해에 따라 프레임워크를 다르게 사용하기를 원할 수 있다. 프레임워크가 보다 유용하려면 이러한 다른 요구를 수용하면서 일관성과 유지보수 용이성을 확보해야 한다. 복잡한 요건과 잦은 변화가 필연적인 현재 업무 환경을 고려하면 설계 원칙을 유지하는 데 있어 리팩토링은 꼭 필요하다. 앞서 다른 글에서 리팩토링에 대해 많은 이야기가 있었기 때문에 현장에서 간과할 수 있는 내용을 담도록 하겠다.
애플리케이션 프레임워크설계 원칙
지인의 블로그 포스트 ‘Application Framework 개발의 원칙’을 읽은 시점은 프레임워크 개발 프로젝트를 시작해서 3개월쯤 지난 때였다. 그렇지 않아도 프레임워크의 정체성에 대해 고민하던 차였기에 시사점이 컸다. 주요 내용을 발췌하면 다음과 같다.
애플리케이션 프레임워크 개발에는 분명한 목적과 철학이 있어야 한다. 이 프레임워크의 원칙이 무엇인지, 그래서 무슨 목표를 지향하고 있고, 그러기 위해서 어떤 전략을 구사했는가를 명확하게 설명할 수 있어야 한다. 그것이 비록 맨땅에서 만들어온 것이 아니고, 일부 유명 프레임워크를 조합하고 그 위에 얇은 레이어를 하나 얹었든, 그저 사용가이드 수준의 스택-업을 했든 상관없이 말이다. 만약 프레임워크 개발자라면 자신에게 5분의 시간이 주어졌을 때 그 프레임워크의 장점이 무엇이고 무슨 철학을 가지고 있는지 명확히 설명할 수 있어야 한다. 물론 듣는 사람이 적어도 그 목적을 명확이 이해할 수 있도록 말이다.
프로젝트 발주 시점에 고객은 프레임워크 개발의 타당성을 경영진에게 입증하여 자사의 지갑을 열고, 필요한 인력을 구성하는 과정에서 분명한 목적을 제시했다. 외주 개발 형태였기 때문에 프로젝트 제안을 하면서 개발팀은 고객이 기대하는 효과를 만들어내기 위해 프레임워크가 제공할 가치를 제시했다.
확장성 및 범용성
고성능
아키텍처 가변성 지원
개발 생산성 향상
설정 편의성
시스템 통합 일관성
테스트 용이성
정책 가변성 지원
이와 같은 가치는 원칙 수준이라 할만하다. 과연 원칙수준의 추상적인 가치는 어떻게 구현할 수 있을까? 돌아보면 원칙 수준으로 정의한 프레임워크 제공 가치는 설계 과정에서 주요 체크 리스트로 쓰였다. 프레임워크의 기능, API 혹은 사용자 인터페이스를 정의하는 과정에서 설계 결정을 내려야 할 때마다 체크 리스트 역할을 했다. 한 가지 예를 들면, 금융권에서 주로 요구하는 ‘선, 후행 처리 지원’ 기능 구현을 예로 들어보자. 우리[footnote]우리라 함은 필자의 개발팀을 지칭한다.[/
<aop:aspect id="beforeExample" ref="aBean">
<aop:before
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>
...
</aop:aspect>
<aop:before
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>
...
</aop:aspect>
국내에서 흔히 쓰이는 선, 후행 처리 방식이나 기존 프레임워크 제품이 채용한 메커니즘을 개선한 근거는 위에 열거한 제공 가치였다. 정책 가변성 지원이라는 다소 모호한 내용에 대해서도 하나의 예를 들어 보겠다. 오류 로그를 남기는데 있어서 시스템 혹은 운영 조직마다 차이가 있기 마련이다. 어떤 경우는 오류 로그에 대해 간단한 데이터 형식만 정의할 수도 있다. 오류 로그를 체계적으로 관리했던 조직은 오류 로그에 대해 명확한 지침을 갖고 있기도 하다. 처음에는 오류에 대한 지침이 없다가 향후에 이를 반영하고자 할 경우도 있다. 다음 그림은 이러한 상황 모두를 배려하기 위해 각각의 사용 사례를 파악한 그림이다.
이와 같은 식으로 대응하면 프레임워크의 각각의 기능에 대해 하나 이상의 가치를 대응시킬 수 있다. 이는 그리 어려운 방법은 아니다. 그런데 만일 앞서 인용한 ‘Application Framework 개발의 원칙’에서 주장한 것처럼 듣는 사람이 분명하게 이해할 수 있도록 이를 설명할 수 있을까? 더 나아가서 프레임워크가 추구하는 가치와 설계 원칙을 한 마디로 설명할 수 있을까? 포스트를 읽을 당시 필자는 분명한 답을 내지 못했다. 사실 답을 내지 않았다는 말이 더 적절할지도 모른다. 프로젝트 착수 이후 3개월이 지난 시점이었고, 고객이 요구한 방대한 기능을 구현하는 부담은 원칙을 확고하게 하는 일보다 우선했다. 글을 쓰는 지금은 그로부터 8개월이 더 지난 시점이다. 지금은 프레임워크가 추구하는 바에 대해 설명해야 할 대상에 따라 적절한 답을 할 수 있다고 자신한다. 반면에 위에 나열한 가치가 고스란히 지켜졌는지는 의문이다. 더구나 각각을 동등하게 취급하지는 않았으며 처음에 부여한 우선순위가 지금은 변했다고 생각한다. 우리가 초기에 수립한 가치는 작업 과정에서 고객과 우리가 문제를 더 잘 이해함에 따라 정제 작업을 거치게 되었다.
설계 원칙과 코드의 일관성
프로젝트 후반에 개발팀이 작성한 코드를 살펴보니 개개인의 특성을 발견할 수 있었다. 흥미롭기는 했지만, 감상하고 넘어갈 내용은 아니다. 설계 원칙은 코드 속에 살아있어야 의미를 지닌다. 그렇지 않으면 단순히 경구에 지나지 않는다. 코드가 작성자마다 개성을 담고 있다면 원칙이 없다는 반증이다. 흔히 찾을 수 있는 개성 중에서 코딩 표준과 같은 지침으로 쉽게 개선할 수 있는 내용은 다음과 같다.
클래스, 메소드 및 변수 작명 스타일
코드 내 주석 작성 스타일
단위 테스트 작성 단위
반면 아래 사항은 단순한 지침만으로는 해결이 어려운 내용이다.
클래스, 메소드 크기 및 로직 구현 방식
API 주석 수준 및 코드와 주석의 균형
단위 테스트 작성 방식 및 테스트 표본 선정
작성자의 능력에 따라 차이가 발생하는 내용이다. 능력이 비슷하다고 해도 문제가 발생할 수 있다. 가령, 동일한 문제를 해결하는 설계 패턴이 두 가지라고 해보자. 개발자 A가 특정 디자인 패턴을 써서 자신의 코드를 모두 작성하여 저장소에 반영했다. 개발자 B가 다른 기능을 추가하면서 A가 만든 코드 중에 일부를 다른 디자인 패턴을 써서 바꾸었다. 단순히 코딩 스타일이라면 쉽게 드러나 일관성을 확보할 수 있지만, 여러 파일에 걸쳐 존재하는 디자인 패턴 등의 일관성 결여는 확연히 눈에 띄지 않는다.
‘닭이 먼저냐? 달걀이 먼저냐?’와 비슷하게 설계 원칙 수립이 코드 일관성을 향상시키기도 하지만, 코드 일관성을 확보하는 과정에서 설계 원칙이 분명해지기도 한다. 어떤 방법이 더 좋다라고 말하기는 어렵다. 여기서는 리팩토링을 다루고 있기 때문에 후자의 방식을 주로 설명하겠다.
글
프레임워크의 인터페이스(API)
2007/소프트웨어 설계
2007/03/22 11:42
Spring 프레임워크1가 자주 공격받는 것중에 하나는 너무 복잡하다는 것이다. 그런 이야기의 대부분은 정황(Context)을 무시하고 복잡도 자체만을 문제 삼는다. 이는 Spring의 인기를 부정적인 방식으로 이용하려는 시도로 의심되는 논쟁일 뿐이다. 안타깝게도 프레임워크에 대한 이해가 깊지 않은 분들에게 Spring의 API2의 복잡성이 결코 복잡한(?) 것이 아니라는 사실을 설명하기란 무척 어려운 일이다. 메타포를 활용해서 갑자기 설명해보고자 하는 충동에 글을 쓴다.
간결한 인터페이스의 위력에서 예로 들었던 이미지를 보자.

스티브 잡스가 iPod/iMac을 홍보하는 영상에서 iMac 리모컨과 경쟁 제품의 리모컨을 대비한 일이 있다. 사용자 인터페이스에 있어서는 애플이 한가닥한다. 최종 사용자 입장에서는 보편적으로, 어디까지나 보편적으로만 본다면 간결한 것이 최고다.
그러나, 최종 사용자를 위한 것이 아니라면 어떤가? 저러한 기기들의 기판도 단순한 인터페이스를 제공해야 하는가? 리모컨의 기판은 생소하니까 데스크탑의 메인보드를 떠올려보자. USB 포트가 하나라면 간결해서 좋은가? 슬롯은? 각종 포트는? 베이는?

이미지 출처: www.da-view.com/product-sogae/mb885.htm
Spring과 같은 프레임워크가 비슷한 인상을 주는 그림이다. 아래 그림과 대비해서 보면 더욱 그렇다.

확장성이 별로 없는 프레임워크가 무슨 가치가 있는가? 시키는대로 안하면 별로 할 수 있는 것이 없는 프레임워크라면, 프레임워크를 비켜가는 코드를 양산할 가능성이 높다.
Spring이 매력적인 이유는 그럼에도 불구하고 Spring은 충분히 심플하다는 점이다.(물론, 주관적인 척도에 근거한 판단이지만)
간결한 인터페이스의 위력에서 예로 들었던 이미지를 보자.

스티브 잡스가 iPod/iMac을 홍보하는 영상에서 iMac 리모컨과 경쟁 제품의 리모컨을 대비한 일이 있다. 사용자 인터페이스에 있어서는 애플이 한가닥한다. 최종 사용자 입장에서는 보편적으로, 어디까지나 보편적으로만 본다면 간결한 것이 최고다.
그러나, 최종 사용자를 위한 것이 아니라면 어떤가? 저러한 기기들의 기판도 단순한 인터페이스를 제공해야 하는가? 리모컨의 기판은 생소하니까 데스크탑의 메인보드를 떠올려보자. USB 포트가 하나라면 간결해서 좋은가? 슬롯은? 각종 포트는? 베이는?

이미지 출처: www.da-view.com/
Spring과 같은 프레임워크가 비슷한 인상을 주는 그림이다. 아래 그림과 대비해서 보면 더욱 그렇다.

확장성이 별로 없는 프레임워크가 무슨 가치가 있는가? 시키는대로 안하면 별로 할 수 있는 것이 없는 프레임워크라면, 프레임워크를 비켜가는 코드를 양산할 가능성이 높다.
Spring이 매력적인 이유는 그럼에도 불구하고 Spring은 충분히 심플하다는 점이다.(물론, 주관적인 척도에 근거한 판단이지만)