2019. 10. 31. 17:12ㆍ책, 1년에 100권
코딩의 기술을 높여보고자 선택한 책. 이책은 유지보수성 관점에서 이를 높이기 위한 코딩 기술에 대해서 설명하고 있다. 200페이지 정도의 가벼운 책으로 편하게 들고다니며 어렵지 않게 읽을 수 있는 책이다고 본다.
이 책은 소프트웨어 유지보수를 수비고 효과적으로 할수 있도록, 개발자들이 지켜야할 간단하고 뻔한(?) 10가지 원칙에 대해 서술한 책이다. 좀더 자세히 설명하면, 소프트웨어 제품 품질에 관한 국제 표준 ISO 25010에 때란 표준화 검증 서비스를 하고 있는 소프트웨어 관리 컨설팅 전문 회사인 SIG(Software Improvement Group)의 컨설턴트 들이 2000년부터 소프트웨어 품질 평가 및 컨설팅을 하며 축적한 지식과 노하우를 집대성한 책이라고 한다.
책 내용 정리
국제 표준 규격 ISO/IEC 25010에 따른 소프트웨어 품질의 특성 8가지
- 유지보수성(maintainability)
- 호환성 (compatibility)
- 기능안정성 (functional suitability)
- 성능 효율성(performance efficiency)
- 사용성(usability)
- 믿음성(신뢰성) (reliability)
- 보안성(security)
- 휴대성(portability)
이중에서 이 책은 유지 보수성에 대한 얘기이다.
유지보수성이 좋다는 말은 버그를 줄이는 수정 작업을 효율적이고 효과적으로 수행할 수 있다는 의미
소프트웨어 유지 보수의 유형 4가지
- 교정형 유지보수 : 버그를 발견하고 고친다
- 적응형 유지보수 : 운영환경의 변화에 따라 시스템을 변경
- 완료형 유지보수 : 시스템 사용자의 신규/변경 요건을 반영
- 예방형 유지보수 : 품질을 높이고 앞으로 닥칠 버그를 방지할 방안을 모색
독립적으로 관리 및 실행을 할 수 있는 최소한의 코드 그룹을 단위(unit)라고 한다. 자바에서는 메서드나 생성자가 단위이다.
모듈은 자바와 같은 객체 지향 언어의 클래스에 해당한다.
'코드베이스(codebase)'는 하나의 리파지터리에 저장된 소스코드 뭉치로 컴파일 및 배포를 독립적으로 수행하는 단위이다. 시스템은 적어도 하나 이상의 코드베이스를 포함한다.
복잡도를 객관적으로 산출하는 가장 일반적인 방법은 코드 조각을 지나는 가능한 경로수를 세어보는 것이다. 코드 조각을 지나가는 경로가 많을 수록 복잡도는 증가한다. 분기점 개수를 세어 보면 경로 수를 명확히 밝혀 낼 수 있다.
분기점이란 한가지 이상의 방향으로 실행 흐름을 나누어 진행하는 조건문을 말한다. 자바에서 분기점에 해당하는 문과 연산자는 아래와 같다
- if
- case
- ?
- &&, ||
- while
- for
- catch
맥캐브 복잡도(Mccabe complexcity, = 순환복잡도) : 분기점 개수 + 1 (출구가 하나뿐일 경우)
모든 독립적인 단위의 실행 경로를 커버하기 위해 필요한 최소한의 테스트 갯수는 분기점 갯수 + 1이다.
'결합(coupling)' 이란 시스템을 고쳐야 할 때 서로 다른 두 파트가 어느 정도 연결되어 있음을 의미하나. 직접 호출, 설정파일, DB 구조, 심지어는 자체적으로 내린 어떤 가정을 통해서도 클래스는 결합 될수 있다.
결합은 소스코드의 클래스 수준에서 일어난다. 강한 결합으로 인해 실제로 유지보수에 어떤 문제가 생길지는 클래스의 '크기'와 '호출 빈도'에 따라 달라진다.
테스트 스크립트나 프로그램 코드에 포함된 단언(assertion)은 테스트 할 시스템의 올바른 작동 방식을 기술한다.
단위 테스트를 충분히 작성 했는지는 단위 테스트 커버리지(coverage)라는 지표로 판단한다. 커버리지(정확히는 line coverage)는 단위 테스트를 전부 다 실행하면 코드베이스에서 실제로 실행되는 코드 라인 수의 비율을 의미. 라인 커버리지는 적어도 80% 이상을 목표로 충분한 단위 테스트 작성하는 것이 좋다.
유지보수성을 위한 10가지 가이드라인
1. 코드 단위를 짧게 하라
- 단위 (메서드, 생성자)는 짧을 수록 이해, 분석, 테스트, 재사용하기가 좋다.
- 목표: 코드 단위는 15라인을 넘어가지 않게 작성한다.
- 실천: 단위는 15라인을 넘지 않게 하고, 이보다 큰 단위는 15라인 이하의 작은 단위로 나눈다.
- 적용 가이드
- 리팩터링 기법: 메서드 추출
- 리팩터링 기법: 메서드를 메서드 객체로 대체
2. 코드 단위는 간략하게 짜라
- 결정 포인트가 적을 수록 단위를 분석/테스트하기가 쉽다.
- 목표: 단위당 분기점은 4개로 제한한다 (맥케브 복잡도 5이하)
- 실천: 복잡한 단위는 더 잘게 나누고 서로 뭉쳐 있지 않게 한다.
- 적용가이드
- 조건문 체인일 경우, 리팩터링 기법: '조건을 다형성으로 대체'. 자바언어의 다형성 개념을 응용
- 주첩일 경우, 리팩터링 기법: "중첩문을 보호절로 대체"
3. 코드는 한번만 자성하라
- 소스코드 중복은 무조건 피해야 한다. 중복은 회귀 버그를 일으키는 원인이 되기도 한다.
- 목표: 코드를 복사하지 않는다
- 실천: 코드를 재사용 가능한 일반적인 형태로 작성하거나 기존 메서드를 대신 호출한다.
- 적용가이드
- 리팩터링 기법: 메서드 추출
- 리팩터링 기법: 상위 클래스 추출. 메서드가 아닌 원 클래스의 상위 클래스로 생성하여 추출하는 기법
4. 단위 인터페이스를 작게하라
- 파라미터가 적은 단위는 테스트, 재사용하기 편하다.
- 목표: 단위 파라미터 개수는 4개 이하로 제한
- 실천: 파라미터를 파라미터 객체로 추출한다.
- 적용가이드
- 리팩터링 기법: 메서드를 메서드 객체로 대체
- 파라미터를 모아 객체로 묶는다. 이러한 객체를 전송 객체, 또는 파라미터 객체라고 한다.
5. 관심사를 모듈로 분리하라
- 느슨하게 결합된 모듈(클래스)이 고치기가 쉽고 시스템을 더욱 모듈화하는 방향으로 이끈다.
- 목표: 모듈 간 결합을 느슨하게 하기 위해 큰 모듈은 삼가한다.
- 실천: 개별 모듈로 나누어 일을 시키고 구현 상세는 인터페이스 안으로 감춘다.
- 적용가이드
- 클래스를 나누어 관심사를 분리한다
- 특정 구현부는 인터페이스 안에 숨긴다
- 커스텀 코드를 서드파티 라이브러리/프레임워크로 대체한다
6. 아키텍처 컴포넌트를 느슨하게 결합하라
- 느슨하게 결합된 최상위 시스템 컴포넌트가 수정하기 더 쉽고 시스템을 모듈화 할 여지가 많다
- 목표: 최상위 수준의 컴포넌트 간 결합도를 낮춘다. 컴포넌트 독립성을 높인다.
- 실천: 다른 컴포넌트 모듈에 호출을 받는 형태로 공개된 모듈 내부의 상대적인 코드량을 최소화한다
- 적용가이드
- 컴포넌트의 인터페이스에 해당하는 모듈의 크기를 제한한다
- 상위 수준에서 컴포넌트 인터페이스를 추상화 한다. ex. '추상 팩토리' 디자인 패턴 이용
- 스루풋 코드는 기능 테스트에 좋지않은 영향을 미치므로 쓰지 않는다.
7. 아키텍처 컴포넌트의 균형을 잡아라
- 컴포넌트가 넘치거나 모자라지 않게 크기를 거의 비슷하게 균형을 맞춰 모듈화한 아키텍처는 관심사를 분리할 수 있고 고치기가 쉽다.
- 목표: 최상위 수준의 컴포넌트 개수와 상대적 크기를 균형 잡는다
- 실천: 컴포넌트 개수가 9개(6~12개 사이) 정도 되도록 소스코드를 조직화 하고 컴포넌트 크기를 대략 균등하게 맞춘다.
- 적용가이드
- 최상위 수준의 시스템 컴포넌트는 9개가 가장 좋고, 6~12개 사이로 하는 편이 좋다
- 컨포넌트 크기(소스 코드량)는 대체로 비슷하게 맞춘다
8. 코드베이스를 작게하라
- 덩치 큰 시스템은 분석, 수정, 테스트 할 때 코드가 더 많이 필요해서 유지보수가 쉽지 않고 작은 시스템에 비하면 코드 라인당 유지보수 생산성도 떨어진다
- 목표: 코드베이스를 가능한 작게 한다.
- 실천: 코드베이스가 커지는걸 막고 시스템 크기를 적극적으로 줄인다
- 적용가이드
- 기능적 조치: 범위 추가에 맞서라(추가 기능 구현), 기능을 표준화(프로그램 로직과 움직임의 일관성) 하라.
- 기술적 조치: 코드 복사 후 붙여넣기를 하지 않는다. 기존 코드를 리팩터링한다. 서드파티 라이브러리/프레임워크를 사용한다.
9. 테스트를 자동화 하라
- 테스트를 자동화하면 수정한 결과를 거의 실시간으로 피드백 받을 수 있다. 그리고 테스트를 확장하기도 쉽다
- 목표: 테스트를 자동화한다
- 실천: 테스트 프레임워크로 자동화 한 데스트를 작성한다
- 적용가이드
- 제이유닛 테스트 길들이기
10. 클린 코드를 작성하라
- 코드베이스에서 TODO나 죽은 코드 같은 무의미한 아티팩트를 늘어 놓으면 생산적으로 근무하기가 어렵다 결국, 유지보수는 비효율적으로 이루어진다.
- 목표: 클린코드를 작성한다
- 실천: 개발 이후 코드 악취를 남기지 않는다
- 적용가이드
- 단위 수준의 코드 악취를 남기지 말라
- 나쁜 주석을 남기지 말라
- 주석 안에 코드를 남기지 말라
- 죽은 코드를 남기지 말라 - 닿을 수 없는 메서드 코드, 사용하지 않는 프라이빗 메서드, 주석 안에 있는 코드
- 긴 식별자 이름을 감기지 말라
- 매직 상수를 남기지 말라 - 매직상수란 의미가 불분명한 숫자나 리터럴 값이 코드에 포함된 것
- 제대로 처리 안한 예외를 남기지 말라 - catch 블록을 비워두지 마라. 구체적인 예외 메세지를 사용자에게 노출시키지마라(내부 로직 노출로 인한 보안상의 문제가 될수도 있다)
소개되는 툴
- 클론 감지툴
소스 분석툴 PME (http://pdm.github.io/) 에 CDC가 잘 알려진 클론 감지 툴이다. 메이븐(Maven) 또는 이클립스(Eclipse)에서도 실행 할 수 있다.
- 오픈 유틸리티 라이브러리
아파치 커먼스(Apache Commons)
구글 구아바(Google Guava)
- 서트파티 라이브러리/프레임워크
- 테스트 프레임워크
단위 테스트 : 제이 유닛( jUnit, http://junit.org/ ) - 자바 프레임워크
종단 테스트 : 셀레늄(Selenium, http://www.seleniumhq.org) - 웹개발 전용 프레임워크
통합 테스트 : SoapUI (https://www.soapui.org/) - 웹서비스, 메시징 미들웨어에 특화된 프레임워크
제이미터(Apache jMeter, http://jmeter.apache.org/ - 잦바 애플리케이션에 과도한 부하를 걸어 성능 테스트하는 프레임워크
단위 테스트시에, 스텁과 목 객체를 자동으로 생성하고, 옥 객체의 메서드 호출 여부와 인자값 여부를 테스트하는 메서드를 제공하는 프레임워크
모키토(Mockito, http://site.mockito.org/)
이지목(EasyMock, http://easymock.org/)
- 코드 커버리지 툴
'책, 1년에 100권' 카테고리의 다른 글
클루지(Kluge) (0) | 2020.01.04 |
---|---|
오픈데이토피아 (0) | 2019.11.05 |
자바로 배우는 핵심 자료구조와 알고리즘 (0) | 2019.10.08 |
지식 제로부터 배우는 소프트웨어 테스트 (0) | 2019.09.24 |
월급보다 내사업 (0) | 2019.08.21 |