Skip to main content

2. 실용주의 접근법

Item 7. 중복의 해악#

  • 프로그래머는 지식을 수집하고, 조직하고, 유지하고, 통제합니다.
  • 모든 지식은 시스템 내에서 단일하고, 애매하지 않고, 정말로 믿을만한 표현양식을 가져야합니다.

Tip 11. DRY - 반복하지 마라(Don't Repeat Yourself)

어떻게 중복이 생기는 지#

  • 강요된 중복 : 개발자들은 다른 선택이 없다고 느끼며, 환경이 중복을 요구하는 것처럼 보입니다.
  • 부주의한 중복 : 개발자들은 자신들이 정복을 중복하고 있다는 것을 깨닫지 못합니다.
  • 참을성 없는 중복 : 중복이 쉬워보이기 때문에 개발자들이 게을러서 중복합니다.
  • 개발자간의 중복 : 한 팀에 있는 여러 사람들이 동일한 정보를 중복합니다.

강요된 중복#

이를 해결하기 위한 기법은 다음과 같습니다.

  • 정보의 다양한 표현 방식 : 간단한 필터나 코드 생성기를 통해서 중복을 제거합니다.
  • 코드내의 문서화 : 나쁜 코드일수록 주석이 늘어나며, 좋은 코드는 핵심적인 부분을 위한 주석을 만듭니다.
  • 문서화와 코드 : 문서를 수정하고 코드를 갱신하는 순서로 진행합니다.

언어에 관한 문제#

  • 특정 언어에서는 요구되는 극복 기법은 어렵습니다.
  • 예를 들어 C/C++에서는 헤더에서는 인터페이스에 대한 사항을 기록하고, 구현 파일에는 그 코드의 사용자가 알 필요가 없는 상세한 것들을 기록합니다.

부주의한 중복#

  • 설계의 실수에서 발생하기도 합니다.
  • 바깥에서는 DRY 원칙의 위배가 노출되지 않고, 클래스 내의 메서드만 고생하도록 코드를 구성하는 것이 좋습니다.

참을성 없는 중복#

  • 돌아가는 길이 지름길입니다. (지금의 몇초가 나중의 몇시간을 초래합니다.)
  • 발견하기도 쉽고, 다루기도 쉽지만 미뤄두면 나중에 큰 고통이 됩니다.

개발자간의 중복#

  • 가장 발견하기 어려운 중복 중 하나며 이는 유지보수에 걸리게 됩니다.
  • 최선책은 개발자간에 적극적이고 빈번한 소통을 장려하는 것입니다.

Tip 12. 재사용하기 쉽게 만들라


Item 8. 직교성#

설계, 빌드, 테스트 그리고 확장하기에 쉬운 시스템을 만들때 직교성은 중요한 개념입니다.

직교성이란#

  • 직교성은 기하학에서 온 용어이며 컴퓨팅에서는 일종의 독립성이나 결합도 줄이기를 의미합니다.
  • 즉, 하나가 바뀌어도 나머지에 어떤 영향도 주지 않는 경우를 의미합니다.

직교성의 장점#

Tip 13. 관련 없는 것들 간에 서로 영향이 없도록 하라

일반적으로 직교적인 시스템의 장점은 크게 두가지가 있습니다.

생산성 향상#

  • 변화가 국소화(localize)되어서 개발 시간과 테스트 시간이 줄어듭니다.
  • 직교적인 접근법은 재사용을 촉진합니다.
  • 직교적인 컴포넌트들을 결합하는 경우 미묘한 생산성 향상이 있습니다.

리스크 감소#

  • 감염된 코드는 격리됩니다.
  • 시스템이 잘 깨어지지 않습니다.
  • 직교적인 시스템은 해당 컴포턴트들에 대해 테스트를 썰계하고 실행하기 훨씬 쉽기 때문에, 더 많은 테스트를 합니다.
  • 써드파티 컴포넌트로 연결되는 인터페이스들이 전체 개발의 작은 부분에 한정되기 때문에 특정 벤더나 제품, 플랫폼에 덜 종속될 것입니다.

프로젝트 팀#

  • 프로젝트 팀의 효율성을 결정직는 것도 일종의 직교성 문제인 경우가 있습니다.
  • 이러한 직교성을 파악하는 방법은 개별 변화에 대한 토론에 참여할 필요가 있는 사람이 많은 수록 직교성이 낮은 것입니다.

설계#

  • 시스템은 협력하는 모듈들의 집합으로 구성되어야 하고, 각 모듈은 다른 부분과 독립적인 기능을 구현해야합니다.
  • 레이어를 두는 것은 모듈간에 종속성이 빨리 늘어나는 위험을 감소시킵니다.
  • 현실세계의 변화와 설계 사이의 결합도를 줄이는 것이 중요합니다.
  • 자신의 힘으로 제어할 수 없는 속성에는 의존하지 않습니다.

툴킷과 라이브러리#

  • 써드파티 툴킷이나 라이브러리를 도입할 때, 시스템의 직교성을 보존할 수 있도록 주의 깊게 살펴봅니다.
  • 툴킷이나 같은 팀의 다른 멤버가 작성한 라이브러리를 도입시에 자신의 코드에 변화를 강요하는 경우에는 좋지 않습니다.
  • 직교성에 대한 흥미로운 변형 중 하나는 애스펙트 지향 프로그래밍(AOP, Aspect-Oriented Programming) 입니다.

코딩#

직교성을 유지하기 위한 코드 기법은 다음과 같습니다.

  • 코드의 결합도를 줄여라
    • 불필요한 것은 다른 모듈에 노출하지 않습니다.
    • 다른 모듈의 구현에 의존하지 않는 코드를 작성하지않습니다.
  • 전역 데이터를 피하라
    • 전역데이터를 사용하면 그 데이터를 공유하는 다른 컴포턴트와 묶이게 됩니다.
    • 싱글턴 패턴은 특정 클래스의 객체가 단 하나의 인스턴스를 지원하는데 이를 전역처럼 사용하면 안됩니다.
  • 유사한 함수를 피하라
    • 유사한 함수의 집합에서의 중복 코드는 구조적 문제의 징후입니다.
    • 스트래티지 패턴(strategy pattern)을 사용해서 더 나은 구현을 고민합니다.

테스트#

  • 직교적으로 설계, 구현한 시스템은 테스트하기가 쉽습니다.
  • 단위 테스트를 만드는 것 자체가 직교성을 테스트해 볼 수 있는 흥미로운 작업입니다.
  • 버그 수정은 시스템의 직교성을 총체적으로 점검해 볼 수 있는 값진 시간입니다.

문서화#

  • 직교성을 문서에 적용하면 내용과 표현이 두 축이됩니다.

직교적으로 살아가기#

  • DRY 원리와 직교성 원리를 충실히 사용한다면 개발하고 있는 시스템이 더 유연하고, 이해하기 쉬우며, 디버그, 테스트, 유지도 쉬워집니다.

Q. 윈도우의 거대한 사용자 인터페이스와 쉘 프롬프트의 작고 조합 가능한 명령줄의 차이, 무엇이 직교적이고, 왜 그러한지.

  • 당연히 쉘 프롬프트.
  • 윈도우 같은 사용자 인터페이스는 구현된 기능을 편리하게 사용하는데 이점을 가짐. (접근성의 문제)
  • 쉘 프롬프트는 조합을 통해서 다양한 기능을 만들 수 있음.
  • 최근에 이와 비슷한 경우로 NAS 서버에서 싱크를 맞추기 위해, Java로 PowerShell Script를 짜는 코드를 만들어서, 이미지 퀄리티 이슈를 해결한 적이 있음.

Q. C++는 다중 상속을 지원하고, 자바는 다중 인터페이스를 구현 / 다중 상속과 다중 인터페이스 사용이 직교성에 끼치는 영향이 다른지, 위임과 상속의 차이

  • 다중 인터페이스가 더 좋다고 생각.
    • 현재는 C++도 다중 상속을 빼버렸음.
    • 물론 목적에 따라 다르다고 생각하나 일반적으로 인터페이스는 설계도의 역할
    • 클래스를 사용하는 상속은 무겁고 완전한 내용을 요구합니다. IS-A라는 한정적 조건에서만 사용합니다.
    • 인터페이스는 좀 더 가볍고 유연합니다. CAN-DO라는 다양한 조건에서 사용합니다.
  • 위임이 일반적으로 좋다.
    • 상속은 위에 이야기처럼 IS-A라는 한정적 조건에서만 좋다.
    • 상속은 불필요한 종속성을 추가할 확률이 높슾니다.
    • 위임은 확장성을 통한 부분에서 큰 이점을 가집니다. (ex. JDBC)
  • 출처

Item 9. 가역성#

당신이 가진 생각이 딱 하나밖에 없다면, 그것만큼 위험한 것은 없습니다.

  • 중요할 결정들이 수없이 바뀔 수 있습니다.
  • 프로젝트를 진행하는 중에 바뀌게 되면 큰 비용을 치뤄야합니다.

가역성#

  • 소프트웨어를 개발하는 속도는 요구사항, 사용자, 하드웨어의 변화를 앞지를 수 없습니다.
  • 클라이언트-서버 모델에서 서버를 바꾸는 작업도 어려우면 안됩니다.

Tip 14. 최종 결정이란 없다

유연한 아키텍처#

  • 아키텍처, 배포, 벤터 통합 영역의 유연성에 대해서도 관심을 기울어야합니다.
  • 요구사항을 메타데이터에 넣고, 필요한 수행문을 코드에 넣을 때 애스팩트나 펄 등을 통해서 메커니즘을 자동화합니다.

Q. 슈뢰딩거 이야기 + 나의 코드는 몇가지 가능한 미래를 지원할 수 있는가? 어떤 미래가 일을 감당할 수 있을까?

  • 옛날에 비해서 많이 발전.
  • 그래서 더 인터페이스가 중요한 이슈
  • 비지니스는 언제든 바뀔 수 있고, 수없이 요구사항이 바뀜. 그렇기 때문에 확장성 측면에서 생각을 많이하고 고려를 많이해야함.
  • 레거시 코드에서 새로운 코드를 추가할 때, 이러한 부분이 고민이 많이됨.
  • 과거에 만든 코드와 현재의 코드는 이부분이 크게 차이가 있다. (발표자료 공유.)

Item 10. 예광탄#

탄창의 일반 탄환 중에서 예광탄이 끼여있고 이러한 탄은 눈에 보이고, 반응도 즉각적이고, 실제와 동일한 환경이기에 외부의 영향도 최소화됩니다.

이와 마찬가지로 새로운 프로젝트에서도 요구사항이 막연할 때, 이러한 예광탄이 필요합니다.

어둠 속에서 빛을 내는 코드#

  • 코딩에서도 동일한 효과를 얻으려면, 우리를 요구사항으로부터 최종 시스템의 일부 측면에 신속하게, 눈에 보이고, 반복적으로 도달하게 해줄 것을 찾아야합니다.

Tip 15. 목표물을 찾기 위해 예광탄을 써라

예광탄 코드 접근 방법에는 여러 장점이 있습니다.

  • 사용자들은 뭔가 작동하는 것을 일찍부터 보게 됩니다.
    • 쓸 시스템에 진전을 눈에 보게 됩니다.
  • 개발자들은 들어가서 일할 수 있는 구조를 얻습니다.
    • 애플리케이션의 모든 요소간 상호작용을 다 만들고 코드로 구체화를 해놓은 경우, 많은 것을 만들 필요가 없습니다.
    • 모든 사람의 생산성이 더 좋아지고 일관성도 촉진됩니다.
  • 통합 작업을 수행할 기반이 생깁니다.
    • 환경이 구성된 이후로는 매일 통합 테스트를 하여, 영향과 변화를 확인하 수 있습니다.
    • 디버깅과 테스트의 속도도 빨라지고 정확해집니다.
  • 보여줄 것이 생깁니다.
  • 진전 상황에 대해 더 정확하게 감을 잡을 수 있습니다.
    • 개발 단위가 작기 때문에 진전됨을 보여주기가 쉽습니다.

예광탄이 언제나 목표를 맞추는 것은 아닙니다.#

  • 예광탄 코드 기법은 일이 어떻게 될지 100% 확신할 수 없는 상황에서 사용됩니다.
  • 코드의 크기가 작을 수록 관성이 약해서 빠르고 쉽게 바꿀 수 있습니다.

예광탄 코드 대 프로토타이핑#

  • 프로토타입은 최종 시스템의 어떤 특정한 측면을 탐사해 보는 것이 목표이기 때문에 예광탄 코드와 다릅니다.
  • 예광탄 코드 접근 방법은 다른 종류의 문제에 대한 대응 방법이며, 애플리케이션이 전체적으로 어떻게 연결되었는지를 아는 것이 목표입니다.
  • 프로토타입은 나중에 버릴 수 있는 코드를 만들며, 예광탄 코드는 기능은 별로 없지만 완성된 코드이며 최종 시스템 골격의 일부를 이룹니다.

Item 11. 프로토타입과 포스트잇#

  • 프로토타입은 제한된 몇 가지 질문에 답할 목적으로 설계되기 때문에 실제 제품보다 훨씬 적은 비용으로 빠르게 개발할 수 있습니다.

프로토타입의 대상#

다음이 대상이 될 수 있습니다.

  • 아키텍처
  • 기존 시스템에 추가할 새로운 기능
  • 외부 데이터의 구조 혹은 내용
  • 써드파티 도구나 컴포넌트
  • 성능 문제
  • 사용자 인터페이스 설계

Tip 16. 프로토타입을 통해 학습하라

프로토타입을 어떻게 사용할 것인가#

프로토타입을 만들 때는 아래를 무시해도 됩니다.

  • 정확성 : 적절히 dummy 데이터를 사용할 수 있습니다.
  • 완전성 : 미리 선정한 입력데이터와 한가지 메뉴 항목에서만 작동하면 되기 때문에 제한된 기능만을 제공하기도 합니다.
  • 안전성 : 에러 검사는 불완정할 수도 있고, 때로는 무시될 수도 있습니다.
  • 스타일 : 프로토타입은 주석이나 문서를 많이 만들지 않아도 됩니다.

아키텍처 프로토타이핑#

  • 많은 프로토타입들이 고려 중인 전체 시스템을 모델링하기 위해 만들어집니다.
  • 다음의 사항을 고민합니다.
    • 주요 컴포넌트의 책임이 잘 정의되고 적절한지
    • 주요 컴포넌트 간 협력이 잘 정의되어 있는지
    • 결합도는 최소화되어있는지
    • 잠재적 중복을 찾아낼 수 있는지
    • 인터페이스 정의와 제약 사항은 수용할만한지
    • 각 모듈이 실행 중에 필요로 하는 데이터에 접근 경오를 가지고 있는지, 모듈은 데이터를 필요로 할 때 데이터에 접근할 수 있는지

어떻게 프로토타입을 사용하지 않을 것인지#

  • 프로토타입은 결국 폐기처분할 코드입니다.
  • 작업 환경이나 문화에서 프로토타입 코드의 목적이 오용될 확률이 높다고 생각되면 예광탄 접근 방식이 더 적합할 수 있습니다.
  • 프로토타입을 적절하게 사용하면 많은 시간과 돈, 고통, 고생을 줄일 수 있습니다.

Q. 시간이 부족 + 마케팅 팀과 함께 웹 페이지 디자인 브레인스토밍

  • 회의실로 달려가서 보드에 그리는 게 베스트라고 생각
  • 어떤 로드맵을 그리고 구성을 어떤식으로 할지 그림을 그려보면서 의견을 공유하는 게 필요.

Item 12. 도메인 언어#

언어의 한계가 곧 자기 세계의 한계다.

  • 때로는 문제 도메인 언어가 어떤 프로그래밍적 해결방안을 제시하기도 합니다. (즉, Lisp 이나 C 로 짜면 해결방식이 다릅니다.)
  • 도메인에 더 가깝게 일할 수 있는 도구를 스스로에게 제공합니다.

Tip 17. 문제 도메인에 가깝게 프로그래밍하라.

소형 언어를 구현하기#

  • 간단한 소형 언어를 구현하는 방법은 파싱하기 쉬운 라인중심 형식의 언어를 만드는 것입니다.

데이터 언어와 명령형 언어#

  • 구현하는 언어는 크게 두가지 방법으로 쓰일 수 있습니다.
이름정의설명
데이터 언어(Data Language)애플리케이션이 사용할 어떤 형식의 데이터구조를 만듦환경설정 정보를 위해 쓰일때가 많습니다.
명령형 언어(Imperative Language)실제로 실행되는 언어프로그램의 유지보수 등을 위해 사용됩니다.

독립 언어와 내장 언어#

  • 반드시 애플리케이션에 직접 사용되어야만 소형 언어가 유용한 것은 아닙니다.

쉬운 개발 아니면 쉬운 유지보수?#

  • 복잡한 문법에 대한 트레이드오프는 확장가능성과 유지보수입니다.
  • 대부분의 애플리케이션이 예상 수명보다 더 오래가기 때문에 가독성 좋은 언어를 채택하는 편이 더 좋습니다.

Item 13. 추정#

  • 추정을 대한 지식을 배운 후에 경험을 통해 추정 능력을 계발하고, 어디에 크기에 대한 직관적 느낌을 적용할 지 알면 가능성을 확인할 수 있습니다.

Tip 18. 추정을 통해 놀람을 피하라

얼마나 정확한 것이 충분히 정확한 것인지#

  • 추정에서 재밌는 사실은 사용하는 단위가 결과의 해석에 차이를 가져옵니다.
기간추정의 단위
1~15일
3~8주
8~30주
30주 이상추정치 말하기 전에 다시 한번 생각이 필요합니다.

추정치는 어디에서 오는가#

  • 모든 추정치는 문제의 모델에 기반합니다.
  • 경험을 통해 성공적인 추정치를 낼 수 있습니다.

무엇을 묻고 있는지를 이해합니다.#

  • 상대방이 무엇을 묻고 있는지에 대해 이해가 필요합니다.

시스템의 모델을 만들어보기#

  • 모델을 만드는 것은 장기적이고 창의적이고도 유용한 작업입니다.
  • 모델을 만드는 것은 추정 프로세스에 부정확성을 야기하나 간결함과 정확성을 맞교환하는 유인한 일입니다.

모델을 컴포넌트로 나누어라#

  • 모델을 가졌다면 이를 컴포턴트로 분해할 수 있습니다.

각 매개 변수에 값을 주어라#

  • 결과에큰 영향을 미치는 매개 변수가 무엇인지를 규명하고, 이 매개 변수의 값들을 최대한 정확히 사용하는 것이 중요합니다.
  • 매개 변수를 계산할 때는 근거가 있게 해야합니다.

답을 계산하라#

  • 계산을 해보고 이상한 답을 얻게 되면 이를 통해서 문제를 잘못 이해했거나 모델이 잘못되었다는 중요한 정보를 얻게 됩니다.

추정치를 기록하는 용기#

  • 계산한 추정치를 기록하고 이후 실제 결과에 얼마나 가까운지를 평가해보는 것은 좋은 생각입니다.

프로젝트 일정 추정하기#

  • 요구사항 체크하기
  • 위험 분석하기
  • 설계, 구현, 통합
  • 사용자와 함께 검증하기

Tip 19. 코드와 함께 일정도 반복하며 조명하라

누군가 추정에 대해 물으면?#

  • 추정치를 계산하고 알려주고, 그렇지 않다면 나중에 알려주기

Q. 현재 프로젝트의 요구사항 가운데 도메인에 한정된 언어로 표현될 수 있는 부분이 있는지?

  • 대부분 그러한 부분이 없으나 라이브러리를 사용한 부분이 걸릴 것 같다

문제 도메인에 가깝게 프로그래밍하기 위해 소형 언어를 채택한다면 일정 이슈가 생길 것. 이러한 부분을 재사용할 수 있을까?

  • 모듈화를 하여, 분리를 잘 시키는 것이 중요하다고 생각.
  • 필요한 모듈을 재사용하자. 기능을 작게 작게 분리해서 필요한 부분이 있으면 재사용한다.
Last updated on