목적: Software engineering의 이해
2장. 실용주의 접근법A PRAGMATIC APPROACH
2.1. 중복의 해악
소프트웨어를 신뢰성 높게 개발하고, 개발을 이해하고 유지보수하기 쉽게 만드는 유일한 길은 우리가 DRY 원칙이라고 부르는 것을 따르는 것뿐이라고 생각한다. DRY 원칙이란 모든 지식은 시스템 내에서 단일하고, 애매하지 않고, 정말로 믿을만한 표현 양식을 가져야 한다라는 것이다.
11. DRY – 반복하지 마라Don’t Repeat Yourself
어떻게 중복이 생기는가?
- 강요된impose 중복: 개발자들은 다른 선택이 없다고 느낀다. 환경이 중복을 요구하는 것처럼 보인다.
- 부주의한 중복: 개발자들은 자신들이 정보를 중복하고 있다는 것을 깨닫지 못한다.
- 참을성 없는 중복: 중복이 쉬워 보이기 때문에 개발자들이 게을러져서 중복을 하게 된다.
- 개발자간의 중복: 한 팀에 있는(혹은 다른 팀에 있는) 여러 사람들이 동일한 정보를 중복한다.
강요된 중복
코드내의 문서화 프로그래머는 훌륭한 코드에는 주석이 많다고 배운다. 불행이도 그들은 코드에 왜 주석이 필요한지 배우지 않는다. 나쁜 코드야말로 많은 주석을 필요로 한다.
DRY 원칙은 낮은 차원의 지식은 그것이 속하는 코드에 놔두고, 주석은 다른 높은 차원의 설명을 위해 아껴두라고 한다.
부주의한 중복
복수의 상호의존적 데이터 요소들이 있을 경우 생기는, 약간은 덜 분명한 종류의 비정규화된 데이터가 있다. 선을 대표하는 클래스를 한번 보도록 하자.
class Line { public: Point start; Point end; Double length; };
첫눈에는 이 클래스가 그럴싸해 보일 것이다. 하나의 선에는 분명히 시작과 끝이 있고, 언제나 길이가 있다. 하지만 여기엔 중복이 있다. 길이는 시작과 끝 점으로 정의된다. 그 점 중 하나라도 바꾸게 되면 길이 역시 변한다. 길이는 계산되는 필드로 만드는 것이 낫다.
class Line { public: Point start; Point end; Double length() { return start.distanceTo(end); } };
이 개발 과정에서 나중에는 성능상의 이유로 DRY 원칙을 위배할 수도 있을 것이다. 이것은 비용이 많이 드는 연산을 피하기 위해 데이터를 캐싱해야 하는 경우를 종종 발생한다. 요령은 국소화하는 것이다.
class Line { private: bool changed; double length; Point start; Point end; public: void setStart(Point p) { start = p; changed = true; } void setEnd(Point p) { end = p; changed = true; } Point getStart(void) { return start; } Point getEnd(void) { return end; } Double getLength() { If (changed) { length = start.distanceTo(end); changed = false; } } }
이 예는 자바나 C++ 같은 객체지향 언어의 중요한 문제를 한 가지 보여준다. 가능한 곳에서는 언제나 객체의 속성을 읽고 쓸 수 있는 액세스 함수를 사용하라
12. 재사용하기 쉽게 만들라
2.2. 직교성Orthogonality(결합도 줄이기)
직교성은 일종의 독립성independence이나, 결합도 줄이기decoupling를 의미한다.
13. 관련 없는 것들 간에 서로 영향이 없도록 하라
주(註): 이 책 자체가 그렇지만 이 장은 더 이상 요약할 것이 없습니다. 따라서 개념만 옮깁니다. 보다 자세한 내용은 책을 이용해 보세요.
2.3. 가역성可逆性(유연한 아키텍처를 구현하라)
가역성(다시 본디의 상태로 돌이킬 수 있음)
프로젝트 초기에 특정 벤더의 관계형 데이터베이스를 사용하기로 결정했다고 가정해보자. 한참 후 성능 테스트를 하면서 데이터베이스가 너무 느리다는 것을 발견했고, B사의 객체형 데이터베이스가 더 빠르다는 것을 알게 되었다. 대부분의 전형적인 프로젝트라면 운이 없다 할 수밖에 없을 것이다. 특정 벤더의 제품을 이용하는 코드가 전반에 퍼져 있을 것이기 때문이다. 하지만 데이터베이스에 대한 아이디어를 올바르게 추상화하여 어떤 하나의 지점이 영속 서비스persistence service를 제공하도록 만들었다면 도중에 말을 갈아 탈 수 있는 유연성을 갖게 될 것이다.
14. 최정 결정이란 없다
유연한 아키텍처(돌발적인 가역성을 대비한)
보통 특정 벤더 제품에 대한 의존도 등은 잘 정의하고 추상화한 인터페이스를 통해 감출 수 있다. 만약 벤더 의존적인 코드를 깨끗하게 분리하지 않으면 어떻게 될까? 벤더 의존적인 수행문들이 코드 전반에 흩어져 있을 것이고, 이는 유지보수성, 유연성을 극도로 떨어뜨리게 된다. 요구사항을 메타데이터에 넣고, 필요한 수행문을 코드에 넣을 때 애스펙트aspect나 펄perl 등을 이용하여 메커니즘을 자동화시켜라. 그리고 어떤 메커니즘을 이용하든 이를 자동으로 되돌릴 수 있도록 하라.
2.4. 예광탄(점진적 접근 방법)
전에 만들어진 적이 없는 전혀 새로운 것을 만들고 있다면, 기관총 사수와 마찬가지로 어둠 속에서 목표물을 맞추어야 한다. 사용자들이 이전에 그런 시스템을 한 번도 본 적이 없기 때문에 요구사항이 막연할지도 모른다.
시스템을 돌아갈 때까지 세세히 명세화하는 것이 이런 상황에서의 전형적인 반응이다. 모든 불확실한 점을 잡아메고, 환경 조건을 제약하고, 모든 요구사항을 일일이 항목으로 만들어서 명세서를 만든다. 상당한 양의 계산을 우선 하고 나서, 그 다음엔 발사하고, 맞기를 비는 것이다. (일종의 거대 공학적 접근 방법) 이것은 실용적이지 못하다.
어둠 속에서 빛을 내는 코드
예광탄 코드에도 상용 코드와 마찬가지로 모든 에러 검사, 구조화, 문서화, 자기 검사가 포함된다. 단지 예광탕 코드에는 아직 완전한 기능이 들어 있지 않을 뿐이다. 하지만 시스템을 구성하는 요소를 모두 연결해 놓은 후라면 목표물에 얼마나 가까이 다가섰는지 확인할 수 있으며, 필요하다면 조정도 할 수 있다. 그렇게 해서 일단 목표물을 맞춘다면 기능을 추가하는 일은 쉽다. (점진적 접근 방법)
15. 목표물을 찾기 위해 예광탄을 써라
예광탄 코드 접근 방법의 장점
- 사용자들은 뭔가 작동되는 것을 일찍부터 보게된다.
- 개발자들은 들어가서 일할 수 있는 구조를 얻는다.
- 통합작업을 수행할 기반이 생긴다: 시스템의 요소들이 모두 연결된 다음에는(단위 테스트가 끝난 후) 코드를 추가 할 수 있는 환경이 생긴다. 한꺼번에 모든 것을 통합하려고 노력하는 대신, 매일 통합할 수 있다. 새도 도입된 변화의 영향은 더욱 명확하게 보이며, 상호작용은 제한적이다. 그러므로 디버깅과 테스팅은 속도도 빨라지고 더 정확해질 것이다.
- 보여줄 것이 생긴다.
- 진전 상황에 대해 더 정확하게 감을 잡을 수 있다.
예광탄 코드 대 프로토타이핑prototyping
프로토타입은 나중에 버릴 수 있는 코드를 만든다. 예광탄 코드는 기능은 별로 없지만 완결된 코드이며, 최종 시스템 골격의 일부를 이룬다. 프로토타입을 예광탄이 하나라도 발사되기 전에 먼저 일어나는 정찰과 정보 수집으로 생각하면 되겠다.
2.5. 프로토타입과 포스트잇
생략.
2.6. 도메인 언어
생략.
2.7. 추정
추정에 대한 지식을 배운 후에 경험을 통해 추정 능력을 개발하고, 어디에 크게에 대한 직관적 느낌을 적용해야 할지를 알게 된다면, 무언가의 가능성을 가늠할 수 있는 능력을 발휘할 수 있게 될 것이다. 코딩할 때에도 어떤 서브시스템을 최적화해야 하고, 어떤 서브시스템을 그대로 남겨 두어도 될지를 판단할 수 있는 능력을 갖게 될 것이다.
18. 추정을 통해 놀람을 피하라
얼마나 정확한 것이 충분히 정확한 것인가?
추정에서 한 가지 재미있는 사실은 사용하는 단위가 결과의 해석에 차이를 가져온다는 것이다. 만약 무언가를 끝내는 데 130일 정도의 근무일 동안 일해야 한다고 말한다면, 듣는 사람은 상당히 가까운 시일 내에 끝날 것이라 생각하며 정확한 일정을 기대하게 된다. 하지만 “대략 6달 정도 걸리겠군요.”라 말한다면 지금부터 5~7달 사이 언젠가 끝날 것이라 여길 것이다. 두 숫자는 같은 기간을 이야기하지만, ‘130일’은 여러분이 느끼는 것보다 더 높은 정확성을 내포한다.
기간 | 추정의 단위 |
---|---|
1~15 일 | 일 |
3~8 주 | 주 |
8~30 주 | 달 |
30 주 이상 | 추정치를 말하기 전에 다시 한번 생각해 보라 |
그러므로, 프로젝트에 대략 125 근무일(25주)이 소요될 것이라는 것을 알았다면 “대략 여섯 달”이 걸릴 거라고 이야기 하라.
추정치는 어디에서 오는가?
1. 무엇을 묻고 있는지를 이해하자
2. 시스템의 모델을 만들어보라
3. 모델을 컴포넌트로 나누어라
4. 각 매개 변수에 값을 주어라
5. 답을 계산하라
6. 추정치를 기록하는 용기
누군가 추정에 대해 물으면 무엇이라 대답해야 할까?
나라면 “나중에 전화드릴께요.”라 말할 것이다. ;-)
프로젝트 도중 숨을 고르고, 잠시 시간을 내어 이번 항목에서 기술한 단계를 밟아나간다면 더 정확한 추정치를 알려줄 수 있다. 자판기 앞에서 말한 추정치는 커피와 마찬가지로 여러분에게 해를 끼칠 것이다.
출처
인사이트 – 앤드류 헌트, 데이비드 토머스의 실용주의 프로그래머The Pragmatic Programmer