5장. 구현 설계
목차
- 5.1 설계의 어려움
- 5.2 핵심 설계 개념
- 5.3 설계 빌딩 블록: 발견적 학습
- 5.4 설계 실천법
- 5.5 잘 알려진 방법론에 대한 의견
5.1 설계의 어려움
"소프트웨어 설계"는 컴퓨터 소프트웨어에 대한 명세를 동작 가능한 소프트웨어로 변환하기 위한 계획에 대한 구상이나 창작, 도구를 뜻한다. 설계는 요구사항을 코드 작성과 디버깅에 연결하는 작업이다. 훌륭한 상위 설계는 여러 개의 하위 수준의 설계를 무리 없이 담을 수 있는 구조를 제공한다.
설계는 불명확한 문제다
설계는 확실하게 정답이 정해져 있지 않다. 한 번 설계하고, 문제가 발견되면 다시 설계하는 과정을 반복해야 한다. 그동안 설계 없이 프로그래밍을 해왔지만 이번 챕터를 읽은 이후 설계를 하고 코딩을 시작해야 겠다.
설계는 엉성한 프로세스다(결과는 정돈되었을지라도)
- 설계는 절충과 우선순위의 문제다
- 설계에는 제약이 따른다
- 설계는 비결정적이다
- 설계는 발견적 학습 과정이다
- 설계는 창발적이다
5.2 핵심 설계 개념
소프트웨어의 주요 기술적 의무: 복잡성 관리
본질적 어려움 : 자동차를 만드는데 바퀴, 문, 엔진이 없는 상대타 본질적 어려움을 겪는 상태다.
비본질적 어려움 : 자동차 바퀴의 종류가 스키니 휠인지 매그 휠인지, 나는 스키니 휠이 필요한데 매그 휠인 경우 이는 비본질적인 어려움을 겪는 상태다.
자동차에 바퀴가 없다면 자동차는 동작을 하지 못한다. 본질적으로 문제가 발생한 상태다. 하지만 자동차의 바퀴가 내가 원하는 바퀴가 아닌 경우 자동차는 동작은 정상적으로 한다. 하지만 내가 원하지 않는 경우이므로 비본질적인 문제가 발생한 상태다.
모든 본질적인 어려움의 근원은 본질적이고 비본질적인 복잡성 때문이다.
복잡성 관리의 중요성
대부분 실패한 프로젝트는 요구사항이나 계획 수립, 관리가 부족해서 실패한다. 하지만 프로젝트가 기술적인 이유로 실패한 경우에는 그 원인을 복잡성 관리 부족에서 찾을 수 있다.
복잡성을 해결하는 방법
비효과적인 설계가 발생하는 경우
- 간단한 문제를 복잡하게 해결할 때
- 복잡한 문제를 단순하고 잘못된 방법으로 해결할 때
- 복잡한 문제를 부적절하고 복잡하게 해결할 때
문제에 따라 개별적으로 적용되는 해결방법을 적용해야 한다.
복잡성을 관리하는 두 가지 접근 방법
- 두뇌가 한 번에 처리해야 하는 본질적인 복잡성의 양을 최소화한다.
- 비본질적인 복잡성이 불필요하게 증가하지 않도록 한다.
바람직한 설계의 특징
- 복잡성 최소화
- 유지보수의 편리함
- 느슨한 결합
- 확장성
- 재사용성
- 높은 팬인
- 낮은 팬아웃
- 이식성
- 간결성
- 계층화
- 표준 기법들
설계 수준
수준 1 : 소프트웨어 시스템
수준 2 : 서브시스템이나 패키지로 분할
수준 3 : 클래스로 분할
수준 4 : 루틴으로 분할
수준 5 : 내부 루틴 설계
5.3 설계 빌딩 블록: 발견적 학습
설계에는 정답이 없다. 좋은 소프트웨어 설계를 하기 위해서는 발견적으로 학습을 해야하고, 여러번 설계를 진행하면서 더 나은 방법을 찾아내야 한다.
객체와 객체 속성 식별 -> 각 객체에 무엇을 할 수 있는지 결정 -> 각 객체가 다른 객체에 무엇을 할 수 있는지 결정 -> 각 객체에서 다른 객체에 보일 부분을 결정 -> 각 객체의 인터페이스를 정의
5.4 설계 실천법
설계는 반복해서 적용해야 한다. 처음부터 완벽한 설계를 하는 것은 불가능하다. 하지만 경험의 축적으로 최적의 설계를 하고, 이를 개선해나가면서 다음번에 비슷한 문제를 마주했을 때 더 나은 설계를 할 수 있다.
5.5 잘 알려진 방법론에 대한 의견
모든 것을 설계하는 것은 낭비이다. 하지만 아무것도 설계하지 않는 것은 문제를 유발한다.
첫 번째 설계에 안주하지 말고 협력하고 단순함을 추구하고, 프로토타입을 만드는 과정을 반복하면 설계에 만족할 것이다.