크리에이티브 커먼즈 라이선스
Creative Commons License

빌드의 통합은 형상관리도구, 워크스페이스의 소스코드 관리 도구, 배포 바이너리 버전 관리 도구 등을 통해서 상당 부분 자동화를 시킬 수 있다. 빌드는 단순히 형상관리에 있는 소스 코드들을 모두 가지고 와서 실행 파일로 컴파일을 만들어주는 의미만 포함되는 것은 아니다. 물론, 이러한 자동화 역시 전체 소스 코드의 깨짐 현상을 방지할 수 있고, 이를 지속적으로 반복적으로 수행한다면 소스 코드 깨짐 현상에 대한 위험은 줄일 수 있을 것이다.


문제는 전체 소스 코드의 크기가 적고, 어느 정도 인내할 수 있는 시간 동안 빌드를 한다면 괜찮겠지만, 소스 크기가 상당하고 많은 사람들이 만들어내는 소스 코드 (심지어 서로 다른 지역에 있는 사람들이 만들어내는 소스 코드와 같이 빌드하는 경우) 라면 상황이 달라진다.


실제 약 20 ~ 30만 라인을 소스 체크아웃에서부터 약 3분 정도 소요되고(물론, 물리적인 환경에 따라 다르기는 하겠지만, 여기서는 동일 환경에서 빌드한 수치들로 상대적인 수치로 받아들이면 된다), 약 70 ~ 80 만 라인은 약 15분 정도가 소요되고, 120 ~ 130 만 라인 소스 빌드 시간은 약 30분 가량이 든다. 이와 같은 수치로 본다면, 소스 코드의 증가는 빌드 시간의 단순한 증가를 의미하는 것도 있겠지만, 그 수치로 봐서도 기하급수적인 수치로 늘어날 것으로 예상해볼 수 있다. 실제 약 50만 라인 정도를 빌드하는 시간이 4분 정도 소요되었는데, 7 ~ 80 만으로 늘어나는 경우에는 그 수치가 2배를 훨씬 넘어서는 기간이 걸렸다. (빌드 시간은 내부 코드의 복잡도도 영향을 미치기 때문에 서로 다른 성격의 애플리케이션이나 컴포넌트를 비교하는 경우에는 수치적으로는 다소 차이가 발생할 수도 있다.)



위의 그림에서 LOC의 증가 정도(기울기)와 그에 따른 빌드 시간의 증가 정도(기울기)의 차이가 점점 늘어나는 것으로 볼 수 있다. 즉, 한번에 빌드하는 LOC가 증가할수록 그에 따른 빌드 시간의 증가는 더 급격히 늘어난다고 볼 수 있다.


통합 빌드의 시간이 길어졌을 때 통합하는 시간이 걸리는 것은 당연하며, 특히 빌드 중에 빌드 에러가 나서 다시 빌드를 해야하는 경우의 수가 많아질수록 그 시간이 더 늘어난다는 것이다. 예를 들어, 30분에 걸쳐서 빌드하는 애플리케이션의 경우, 거의 빌드 막바지인 25분 경과 시점에 빌드 에러가 발생한다면, 이를 조치하고 다시 처음부터 빌드를 해야하기 때문에 그 시간은 거의 2배인 1시간 가량을 소비해야 한다. 이러한 시간 소비는 그 시간 동안 형상관리에 다시 새로운 코드를 커밋하는 과정에서 재반복이 될 우려가 있으며, 심지어는 몇시간 동안 빌드를 못하는 경우도 있다.


이러한 문제들에 대한 해결책은 빠른 빌드를 위해서 필요하며, 단순히 빌드 자동화만 도입한다고 해결되는 부분은 아니다. 빌드 자동화의 장점과 더불어서 원칙이 있는 각 모듈(컴포넌트)간의 관계를 형성하여 빌드 단위를 최소한을 나누어서 애플리케이션을 구성하도록 해야 한다.


빌드 단위의 정의


빌드 단위를 정의하려면, 최소한 아키텍처에서 배포 단위를 결정해야 한다. 통상 배포 단위는 하나의 컴포넌트 단위로 매핑하며, 이는 컴파일된 바이너리 파일들의 묶음이기도 하다. 이 배포 단위는 서로 의존관계를 형성하고, 그 의존관계들로 인해서 배포 단위는 빌드의 순서를 결정하게 된다. 즉, 컴포넌트는 해당 비즈니스 로직의 성격으로 분류되어야 하며, 이러한 컴포넌트 유형 간의 의존관계 원칙이 최소한 정의되어야 한다.


빌드 단위를 컴포넌트로 정하는 경우, 컴포넌트 유형별로 관리를 할 필요가 있으며, 각 유형을 묶어서 관리할 수 있는 체계가 필요하다. Maven을 사용하는 경우, 컴포넌트 유형을 관리하는 단위를 하나의 POM으로 묶어서 그 하위에 해당 컴포넌트들을 위치시켜 상위에서 빌드가 되면 동일한 유형의 컴포넌트들이 동시에 빌드할 수 있는 형태로 관리가 가능하다. 컴포넌트 유형은 크게 분류해보면 Business Data Type을 모아두는 형태, Utility 형태, Entity 형태, Process 형태 등으로 나눌 수 있다. 분류체계를 더 세분화시킬 수도 있지만, 기본적인 비즈니스 로직의 근간을 이루는 컴포넌트를 이와 같이 분류를 해볼 수 있다. 이 컴포넌트들은 한꺼번에 배포를 해도 되지만, 컴포넌트 유형 간의 의존관계 규칙을 강화시키거나 규정하면 해당 의존관계를 이루는 컴포넌트의 순서에 맞추어서 자동 빌드에 대한 프로세스를 나누어 볼 수 있다. 예를 들어, Process가 Entity나 Utility로의 의존관계만 형성되어 있다면, Entity나 Utility를 먼저 빌드/배포하고, Process를 그 후에 배포하도록 순서를 결정할 수 있다.


마찬가지로, 외부 시스템과 연결되는 부분을 모아두는 유형을 별도로 모아둘 수 있으며, UI와 연계되는 로직을 구성하는 UI 관련 컴포넌트를 별도의 유형으로 분류할 수도 있다. 이 경우에도 다른 컴포넌트 유형과의 의존관계를 고려해서 빌드 순서를 조정할 수도 있다.


빌드 프로세스 세팅


통상 빌드 자동화 도구(CI, Continuous Integration)를 사용하는 하나의 빌드 작업과 다른 빌드 작업을 연결시킬 수가 있으며, 이 빌드 작업은 여러개의 빌드 작업으로 분화(fork) 가능하다.


즉, 컴포넌트 유형의 빌드 순서가 A -> B -> (C | D | E) 라고 한다면, A의 빌드 작업이 종료함과 동시에 B의 빌드 작업을 연결해서 기동시킬 수 있으며, B의 빌드작업이 종료됨과 동시에 C, D, E의 빌드 작업이 동시에 수행하는 것이 가능하다.


이와 같이 하나의 애플리케이션을 구성하는 컴포넌트를 빌드하는데 빌드 프로세스 형태로 구성했을 때의 장점은 무엇보다 적은 코드의 빌드 작업이 수행되기 때문에 전체 코드를 빌드하는 것보다도 시간이 더 적게 걸릴 수 있으며, 중간에 빌드 에러가 발생되면, 멈춘 작업에서 에러를 수정하여 다시 이전에 수행된 작업을 다시 기동하지 않고 그 이후부터 다시 빌드를 시작할 수 있는 장점을 가진다.



위의 그림에서 위의 알파벳으로 표현된 부분은 제일 하단에 있는 하나의 애플리케이션을 구성하는 컴포넌트 유형을 분리하여 빌드 프로세스로 구성한 것이며, 그 순서는 오른쪽에 나타나 있다. 이들 각각의 빌드 작업들의 걸리는 시간의 총합은 총 10분 30초 정도가 되며, 전체를 하나의 빌드 작업으로 구성하는 경우에 약 14분 정도가 소요되었다. 즉, 약 1.5배의 시간이 더 걸리는 셈이다.


빌드를 이와 같이 애플리케이션 전체를 통합하여 하나의 작업을 만드는 것보다 가능하면 나누어서 빌드를 하도록 구성하는 편이 시간적인 비용 측면에서 크게 이익이 된다.


고려 사항(한계)


빌드를 자그마한 단위로 나누어서 작업을 만드는 경우, 도구의 지원에 따라서 분화(fork) 프로세스는 가능하지만, 병합(join) 프로세스를 지원을 하지 않는 경우가 있다. 위의 경우에도 H, J, L, N으로 나누어진 빌드 프로세스가 모두 O 작업으로 병합되지만, 실제로는 O가 4번 실행되는 형태로 빌드 작업으로 구성되어 있다. 하지만, 이렇다 하더라도 빌드 중간에 에러나는 부분에 있어서는 다시 A부터 실행하지 않아도 되기 때문에 큰 이익이 있으며, O가 4번 빌드된다고 하더라도 전체적으로 통합/빌드/배포 작업에 있어서 아무런 영향은 미치지는 않는다. 다만, 불필요한 작업이 발생할 뿐이다. CI 도구가 이러한 부분을 잘 지원해주거나, 혹은 내부적으로 플러그인이나 스크립트를 사용해서 이러한 불필요한 작업에 대해서는 여력이 된다면 보정을 해줄 수도 있을 것이다.


빌드 프로세스에 맞게 컴포넌트 유형 간의 의존관계가 형성되어 있어야 한다. 예를 들어, C 작업 후 D를 수행해야 하는데, C 유형의 컴포넌들이 D 작업 이후의 유형에 대해 의존관계를 형성한다면, 위의 빌드 프로세스는 조정을 해야 하거나 해당 의존관계를 다른 형태로 구성해야 한다. 이는 아키텍처 관점에서 컴포넌트 유형의 의존관계를 빌드를 통해서 규제하거나 강제하는 효과를 낳는다.


빌드 작업에 대한 인스턴스가 하나만 수행하도록 하는 경우에는 전체적인 시간에 대한 차이가 그리 크지는 않는다. 예를 들어, 위의 빌드 프로세스에서 H, J, L, N으로 나뉘어서 동시적으로 빌드 프로세스가 수행되지 않고, 하나의 빌드 작업만을 차례로 수행하게 한다면, 전체 빌드 시간은 차이가 얼마 나지 않을 수도 있다. 하지만, 이전에 언급했듯이 처음부터 다시 빌드하는 수고는 덜 수 있는 충분한 장점을 가진다.



빌드는 자동화시키려는 노력은 필요하며, 나름대로 원칙을 세워서 작은 단위로 빌드하려는 작업들이 필요하다. 또한, 빌드를 하는 시간을 빠르게 하면 할수록 개발자가 자신이 만든 코드에 대한 피드백을 빨리 받을 수 있는 장점을 가지게 된다. (실제로 에러 수정시 수정된 내용이 제대로 되었는지를 파악하는데 통합/빌드/배포의 긴 시간으로 아무런 진전을 못하는 경우도 많다)





저작자 표시 비영리 변경 금지
신고

'Homo Faber > Techniques' 카테고리의 다른 글

빌드 시간을 더 빠르게 하라  (0) 2012.05.12
신중하게 행동하라  (0) 2010.06.16
Spring의 AOP로 구현한 테스트 스파이(Spy)  (0) 2009.12.04
비즈니스 컴포넌트와 데이터 ownership  (4) 2009.10.05
m2eclipse 설치  (0) 2009.09.22
m2eclipse 소개  (0) 2009.09.22
크리에이티브 커먼즈 라이선스
Creative Commons License
올해 Jolt Awards의 The Best Books에서는 6권의 최고의 책을 선정했고, 그 중에서 Jez Humble과 David Farley가 쓴 Continuous Delivery를 가장 최고의 책(Excellent Book)으로 선정했다. [관련 기사] 기사에서도 말했듯이 이책은 기존 Continuous Integration에서 코드로부터 할 수 있는 모든 것을 자동화시키는 개념을 더 확장하여(응용하여) 가상화(virtualization) 개념을 도입해 배포로 인한 무중단 서비스를 가능하게 하는 방식을 이야기하고 있다. CD에서의 테스트는 오로지 단위테스트(unit test)를 말하고 있으며, 그 테스트 수행 속도 역시 빨라야 한다. 즉, 단위테스트를 하는 범위(coverage)를 최대한 독립적인 비즈니스 영역으로 제한하고, 다양한 Test Double을 통해서 최대한 빠른 시간안에 테스트를 수행하는 것이다. 또한, 통합이나 UI 테스트는 이 단위테스트 범주에 놓기에는 다양한 문제들이 발생하기 때문에 CD에서는 acceptance test 단계에서 수행하는 것으로 이야기하고 있다.

TDD와 비즈니스 컴포넌트
TDD(Test Driven Development)에서는 단위테스트에 대한 다양한 방식과 방법에 대해서 거론이 되었고 또한 여러 기법들이 다양한 패턴 형식으로 나와있기 때문에 구체적인 내용들은 생략한다. 여기서 한가지 생각해볼 문제는 단위테스트를 어떠한 기준과 어떠한 범위를 다룰 것인지(cover)는 결국 비즈니스 로직에 대한 크기의 분류 기준과도 관련이 있다. 테스트에 대한 접근 방식은 비즈니스 로직을 담는 아키텍처에 따라서 다양해진다. 비즈니스 로직은 분석/설계 시점까지도 영향을 받으면서 구현 단계에서는 구체적인 덩어리 형태를 띠는데 이러한 비즈니스 로직 덩어리들을 컴포넌트라는 이름으로 부를 수 있다. 즉, 컴포넌트를 어떠한 기준으로 설계를 할 것인가에 따라서 단위테스트의 크기가 달라질 수 밖에 없으며, CD의 입장에서 TDD는 이러한 독립된 비즈니스 덩어리를 TDD를 통해 어떻게 효과적으로 검증을 수행할 것인가에 대한 영역으로 볼 수 있을 것이다.

Acceptance Test 단계에서 TDD는 BDD(behavior driven development)로 확장되어서 비즈니스 관점의 검증을 수행하도록 자동화되며, 여기에서도 역시 TDD에서 사용했던 다양한 패턴과 기법들이 사용되어야 한다. UI 테스트의 경우에는 Stub이나 Driver들을 적절하게 사용해서 효과적으로 테스트할 수 있어야 한다.

CI와 서비스
CI(Continuous Integration)는 독립적인 단위인 각 컴포넌트들을 어떠한 방식으로 묶어서 서비스를 제공할 것인가에 초점을 맞추고 있으며, 이러한 프로세스를 자동화시키는 관점에서 접근하고 있다. 서비스를 제공하기 위한 각각의 컴포넌트는 해당 서비스의 품질(Quality of Service)에 따라서 통합하는 방식이나 배포 방식을 달라질 수 있으며, 이는 운영 환경과도 밀접하게 관련이 있다. TDD는 인프라나 운영 환경과는 독립적으로 수행할 수 있는 방식을 초점을 맞추기 때문에 컴포넌트들의 의존관계를 그리 크게 영향을 받지 않지만, CI에서는 의존관계에 따라서 통합 프로세스에 영향을 미친다. 예를 들어, 외부 시스템과의 연동을 위한 EAI 솔루션 등에 대한 설정의 영역이 CI 프로세스에서는 중요한 단계 중에 하나가 된다. CI는 궁극적으로 서비스를 만들어내는 자동화된 프로세스를 고려하기 때문에 전체 CI 프로세스를 몇개의 하위 CI 프로세스로 나눌 수도 있다.

TDD는 개발자가 직접 다루는 영역이지만, CI는 개발자가 다루는 환경과는 독립적으로 구성해서 프로세스를 실행한다. 즉, CI에서도 단위테스트의 수행 속도가 영향을 미친고. 인프라의 구성과 개발 환경 등이 CI 프로세스에 영향을 미친다. CI 도구의 동작 방식을 비교적 단순하지만, 확장성을 보장해야 한다. CI 도구 차원에서 해당 프로세스를 충족시키지 못하면 다른 확장된 형태로 특정 프로세스를 충족시키도록 커스터마이징이 가능해야 한다.

CD와 클라우딩
CD를 도입하려는 궁극적인 목적은 기존 서비스의 무중단이며, 해당 서비스의 변경(업그레이드)이 서비스의 중단을 초래해서는안된다는 개념이다. CD를 실현하려는 방식은 현재로써는 해당 시스템의 인프라의 구성에 따라 전혀 다른 접근 방식을 취하게 된다. 하지만, 가장 이상적인 CD의 접근 방식은 클라우드 서비스를 제공하는 시스템에서 클라우드 접근 방식으로 시스템을 배포하는 것이다. 가상화의 개념이 운영 시스템에 도입됨으로써 자원을 효율적으로 사용하는 장점이 있는 반면에 배포에 있어서 상당한 부담을 가지고 온 것이 사실이다. 즉, 클라우딩의 실현에는 바로 CD가 뒷받침되어야 이상적인 클라우딩 서비스를 제공할 수 있게 된다. Jez가 말한 CD는 책에서 클라우드 환경에서 구현된 내용은 아니지만, 지금의 클라우드 환경에서 이를 구현하는 노력은 충분히 가능할 수도 있다.

개발 환경을 구성하는 개발자는 클라우드에서 서비스되는 각 개발 도구들(스마트폰의 앱과 같은 형태)을 로컬 PC나 노트북에서 다운받아서 해당 비즈니스를 구현하고, 이를 다시 또 다른 도구를 통해서 테스트를 수행하고, 형상관리 서버로 커밋을 처리한다. 개발자의 손을 떠난 배포 가능한 비즈니스 구현체를 관리자는 그 실행 가능성을 점검해보고자 해당 기능에 대한 간단한 테스트를 수행해볼 수도 있다. 이 과정에서 내부적으로 프로세스는 실행되지만, 사용자의 복잡한 데이터 조작이나 개발 내부를 들여다보기 위한 노력을 없앨 수도 있다. 또 다른 도구는 개발자가 구현한 내용에 대해 품질 검사를 수행함으로써 일정 수준을 유지하는지를 점검해볼 수도 있다. 여러개의 측정치들을 종합하고, 실행가능 여부를 판단하여 관리자는 최종 승인을 하여 배포를 위한 프로세스를 계속 진행해볼 수 있다. CD가 개발에서 배포까지를 이어주는 프로세스를 자동화시킨다고 하더라도 실제 조직에서는 배포를 위한 결재 프로세스도 여기에 추가되어서 운영하는게 더 현실적이기 때문이다.

가상화 인프라는 서비스를 무중단 상태로 업그레이드 하기 위한 장치로 활용될 것이다. 만일 변경된 서비스가 잘못이 있다고 하더라도 전체 시스템을 셧다운하는 사태는 발생하지 않을 것이며, 다시 이전 서비스로 복원하려는 절차 역시 자동으로 수행되어 사용하는 사람으로 하여금 그러한 변화를 못느끼게 할 수 있을 것이다.

 
Jez는 CD에서 TDD에 대한 단계를 Commit Stage에 포함시켰다. Commit 단계에서는 형상관리도구로부터 소스를 얻어서 Compile, Unit Test, Assemble, Code Analysis를 하는 과정을 담고 있으며, 그 결과를 Artifact Repository에 보고서, 바이너리 파일, 메타데이터 등을 등록(commit)하는 것으로 보고 있다. TDD에 Acceptance Test를 포함시킨다면, CD의 이후 과정인 Automated Acceptance Test를 별도로 나누어서 프로세스를 잡을 필요는 없지만, 이와 같이 두가지 단계를 분리함으로써 얻는 잇점이 많다. 우선은 빠른 빌드를 통해서 배포 가능한 시스템을 언제든지 다시 만들어낼 수 있으며, 복잡한 비즈니스 흐름이나 처리에 대해서 최소화시켜 단계를 진행해볼 수 있다. 어찌되었든 간에 CD에는 TDD에 대한 개념이 같이 포함되어 있다는 것이고 이는 CD를 강력하게 요구할수록 TDD의 입지는 확고해질 수 밖에 없다는 의미이다.

TDD를 바라보는 입장에서 복잡한 비즈니스 로직에 대한 단위테스트로써의 효용가치를 말하는 경우가 있는데, 이는 단위테스트를 통해 얻는 이점을 먼저 개발자가 발견한다면 단위테스트의 필요는 충분하리라 본다. 궁극적으로는 시스템의 검증을 어떻게 효과적으로 할 수 있을 것인가의 측면에서 TDD를 강조하지 않을 수 없으며, 이에 필적할 만한 다른 대안을 찾아보기 힘든 것도 사실이다. 이에 더해, CI나 CD를 이상적인 실현이라고 말하기보다 현실적으로 개발자에게 그리고 프로젝트에 도움이 되는 실용적인 접근 방식으로 바라보는 지혜가 필요할 듯 싶다.
저작자 표시 비영리 동일 조건 변경 허락
신고

'Homo Faber > Concepts' 카테고리의 다른 글

TDD, CI, CD  (0) 2011.08.27
유스케이스의 상속  (0) 2010.02.10
"Less is More"  (0) 2009.02.24
유스케이스 드리븐 방식의 한계  (0) 2008.03.10
Abstract와 Interface  (1) 2008.03.04
자바에서 상속  (1) 2008.03.04
크리에이티브 커먼즈 라이선스
Creative Commons License
- Seb Rose

"무엇을 하든지 간에, 신중하게 행동하고 결과를 생각하라" Anon

어떠한 반복주기(iteration)든지 초반에는 일정이 편안하게 느끼게 됩니다. 하지만, 그렇다 할지라도 특정 시간에는 압박 상황을 피할 수는 없습니다. "올바르게 수행할 것"과 "빨리 수행할 것" 사이에서 선택하라고 하면 나중에 수행한 내용을 수정할 것이라는 생각에 "빨리 수행할 것"을 종종 선호하게 됩니다. 여러분 자신과 팀, 고객에게 지금 빨리 수행하고 이후에 수정할 것이라고 약속할 때에는 여러분은 분명 그러한 의도를 가지고 있습니다. 그러나 그 다음 반복주기에서는 새로운 문제가 나타나고 여러분은 이에 몰두하게 되는 일이 비일비재합니다. 이와 같이 지연된 작업과 같은 유형을 기술적인 빚(technical debt)이라 하며 여러분에게 좋은 친구는 아닙니다.특별히 마틴 파울러(Martin Fowler)는 기술적인 빚에 대한 용어 정의에서 이를 의도적인 기술적인 빚(deliberate technical debt)이라고 했으며, 이는 부주의한 기술적인 빚(inadvertent technical debt)과는 혼동해서는 안됩니다.

기술적인 빚은 대출과 비슷합니다. 여러분은 대출을 통해서 짧은 기간 동안에는 이익을 보게되지만, 이를 완전히 갚기 전까지 이자를 지불해야 합니다. 코드 상에서의 손쉬운 방법들은 기능을 추가하거나 리팩토링하는 것을 더 어렵게 만듭니다. 결함과 깨지기 쉬운 테스트 케이스를 증가시키는 원인입니다. 손쉬운 방법을 그대로 두는 시간이 길어질수록 상황이 더 악화됩니다. 여러분이 원래 코드를 수정하기 위해 작업을 수행하는 시점까지 원래의 문제 위에 코드를 리팩토링하고 수정하는 것을 더 어렵게 만드는 결코 바람직하지 못한 여러차례의 설계로 덧붙여진 덩어리가 만들어질 수 있습니다. 사실 실제로 기존 코드를 수정하려고 되돌아가는 일은 어떤 것이 매우 나빠져서 수정해야만 하는 시점인 경우가 대부분입니다. 그리고 그때까지도 코드를 수정하기 너무나 어려워서 정말로 시간이나 위험을 감수할 수 없는 경우가 종종 있습니다.

마감일정을 맞추거나 기능의 일부분을 구현하기 위해 기술적인 빚을 져야 하는 경우가 여러번 있습니다. 이러한 상황에 빠지지 않도록 하십시오. 하지만 만일 상황이 어쩔 수 없이 기술적인 빚을 지도록 한다면, 일단 그대로 진행하십시오. 그렇지만 (이 부분이 중요한 부분입니다) 기술적인 빚을 추적하고 빠른 시간 안에 이를 되갚거나 기능을 빠르게 완성하십시오.(번다운 차트에서 빠르게 기울기를 낮추십시오.) 빚을 지는 것에 대해 결정을 한 순간 이를 잊어버리지 않기 위해서 작업 카드를 작성하고 이슈 추적 시스템에 등록하십시오.

만일 그 다음 반복주기에서 빚에 대한 부분을 갚는 일정을 만들었다면, 비용을 줄어들 것입니다. 갚지 않은 빚을 그대로 둔다는 것은 이자가 증가하는 것이고 그 이자는 비용을 가시화시키도록 추적되어야 합니다. 이와 같이 함으로써 프로젝트의 기술적인 빚에 대한 비즈니스 가치에 대한 영향을 강조하게 되며 빚에 대한 변제의 적절한 우선순위를 가능하게 합니다. 빚을 계산하는 방법과 그에 대한 이자를 추적하는 방법은 특정 프로젝트에 따라 다르지만, 반드시 추적해야 합니다.

가능한 한 바로 기술적인 빚을 갚으십시오. 그렇지 않으면 경솔한 짓이 될 것입니다.


저작자 표시 비영리 변경 금지
신고

'Homo Faber > Techniques' 카테고리의 다른 글

빌드 시간을 더 빠르게 하라  (0) 2012.05.12
신중하게 행동하라  (0) 2010.06.16
Spring의 AOP로 구현한 테스트 스파이(Spy)  (0) 2009.12.04
비즈니스 컴포넌트와 데이터 ownership  (4) 2009.10.05
m2eclipse 설치  (0) 2009.09.22
m2eclipse 소개  (0) 2009.09.22

+ Recent posts

티스토리 툴바