좋은 소프트웨어 디자인은 품질을 갑자기 끌어올리는 마법이 아니라 변경 비용을 줄이는 구조다

좋은 소프트웨어 디자인을 말할 때 사람들은 종종 거대한 아키텍처 그림이나 세련된 패턴 이름부터 떠올린다. 하지만 실제로 설계의 질은 더 평범한 곳에서 드러난다. 바꿔야 할 때 덜 아픈가, 테스트하기 쉬운가, 중복이 줄어드는가, 작은 수정이 큰 파급으로 번지지 않는가 같은 곳 말이다.
그래서 좋은 설계는 화려한 구조보다 변경 비용을 낮추는 구조라고 보는 편이 현실적이다. 마틴 파울러가 리팩터링을 행동을 보존하면서 설계를 개선하는 통제된 기법이라고 설명한 것도 같은 맥락이다.
단순함은 기능이 적다는 뜻이 아니라 구조가 이해 가능하다는 뜻이다
켄트 벡의 단순 설계 규칙은 여전히 유효하다. 테스트를 통과하고, 의도를 드러내고, 중복을 줄이고, 요소 수를 최소화하는 설계가 좋은 출발점이라는 생각이다. 이 기준은 멋진 추상화를 미리 쌓는 것보다, 지금 필요한 구조를 이해 가능하게 만드는 데 초점을 둔다.
좋은 설계가 대개 읽기 쉬운 이유도 여기에 있다. 나중에 바꾸기 쉬운 코드는 대개 지금 읽기도 쉽다.
설계의 핵심은 자주 바뀌는 것을 한곳에 모으는 데 있다
데이비드 파나스 이후 소프트웨어 설계에서 반복해서 나오는 원칙은 변할 가능성이 높은 것을 숨겨라다. 데이터 형식, 외부 시스템, 알고리즘 선택, UI 프레임워크처럼 바뀔 가능성이 높은 결정이 여러 곳에 퍼져 있으면 작은 요구 변경도 큰 공사가 된다.
반대로 이런 결정을 모듈 경계 안에 숨겨 두면, 나머지 시스템은 더 안정적으로 남을 수 있다. 결국 좋은 설계는 확장성보다 먼저 변경 범위의 격리를 잘하는 설계다.
리팩터링은 설계의 사후 관리가 아니라 일부다
좋은 설계는 처음부터 완벽하게 정해 놓는 것이 아니라, 기능을 만들면서 구조를 계속 정리하는 과정에 가깝다. 파울러가 말하듯 YAGNI가 성립하려면 코드를 쉽게 바꿀 수 있어야 하고, 그 전제는 곧 지속적인 리팩터링이다.
즉 설계와 구현은 분리된 두 단계가 아니다. 기능을 추가하면서 중복을 줄이고, 경계를 다듬고, 테스트를 붙이며 구조를 개선하는 흐름이 실제 설계 작업에 더 가깝다.
마치며
좋은 소프트웨어 디자인은 품질을 단번에 올려 주는 비밀 기술이 아니다. 대신 시간이 지나면서 왜 이 코드는 덜 무너지는가를 설명해 주는 누적 효과에 가깝다. 바꾸기 쉽고, 읽기 쉽고, 테스트하기 쉬운 구조는 처음에는 평범해 보여도 나중에 큰 차이를 만든다.
결국 좋은 설계의 질문은 이것이다. 이 코드는 다음 변경을 얼마나 덜 아프게 받아들일 수 있는가. 대부분의 품질은 그 질문에서 나온다.