← 블로그 목록

좋은 설계는 변하지 않는 것을 퍼뜨리는 대신 자주 바뀌는 것을 한곳에 숨긴다

데이비드 파나스의 정보 은닉 원칙이 오래 살아남은 이유는 모듈을 기능이 아니라 변경 가능성이 있는 결정의 경계로 나누는 발상 때문이다. PG사 연동, 수치 테이블, 저장 포맷처럼 자주 바뀌는 부분이 흩뿌려지면 작은 요구도 연쇄 수정이 되지만, 한곳에 숨기면 변경 영향이 줄어든다. 유지보수성은 결국 변동성을 격리하는 일관성에서 나온다.

좋은 설계는 변하지 않는 것을 퍼뜨리는 대신 자주 바뀌는 것을 한곳에 숨긴다

좋은 설계는 변하지 않는 것을 퍼뜨리는 대신 자주 바뀌는 것을 한곳에 숨긴다

소프트웨어 설계를 어렵게 만드는 이유는 지금 필요한 기능만으로는 미래 변경 지점을 완전히 알 수 없기 때문이다. 그래도 한 가지는 분명하다. 어떤 시스템이든 더 자주 바뀌는 결정과 덜 바뀌는 결정이 있다. 좋은 설계는 이 둘을 구분하고, 자주 바뀌는 것을 한곳에 숨기려 한다.

데이비드 파나스의 정보 은닉 원칙이 오래 살아남은 것도 이 때문이다. 모듈은 기능 단위로만 나누는 것이 아니라, 변경될 가능성이 있는 결정을 감추는 경계로 나눠야 한다는 생각이다.

변동성은 기능보다 결정에 붙어 있다

예를 들어 결제 시스템을 생각해 보면, 결제라는 기능 자체보다 외부 PG사 연동 방식, 실패 재시도 규칙, 정산 형식 같은 것이 더 자주 바뀔 수 있다. 게임에서도 전투 시스템보다 수치 테이블, 입력 장치, 렌더링 백엔드, 저장 포맷이 더 자주 바뀌는 경우가 많다.

이런 결정을 여러 모듈에 흩뿌리면 변경은 곧 연쇄 수정이 된다. 반대로 경계 안에 숨겨 두면 변경 영향은 줄어든다.

리팩터링이 중요한 이유도 결국 변동성 때문이다

마틴 파울러가 말하는 리팩터링은 설계를 멋지게 보이게 하는 작업이 아니다. 행동을 유지한 채 구조를 바꿔, 다음 변경을 더 안전하게 만드는 작업에 가깝다. 그래서 리팩터링이 가장 힘을 발휘하는 순간도 자주 바뀌는 것이 퍼져 있는 걸 발견했을 때다.

좋은 리팩터링은 대개 이런 방향으로 간다.

이렇게 해야 모듈이 진짜 의미를 갖는다.

마치며

좋은 설계를 복잡한 추상화나 거대한 패턴으로만 이해하면 실무에서 자주 길을 잃는다. 더 실용적인 질문은 이것이다. 무엇이 자주 바뀌고, 그 변경이 지금 어디까지 퍼져 있는가.

설계의 핵심은 늘 거기서 시작된다. 변동성을 읽고, 그것을 모듈 경계 안에 숨기고, बाकी는 가능한 한 단순하게 유지하는 것. 결국 유지보수성이란 이 원리를 얼마나 일관되게 지키느냐의 문제에 가깝다.

참고 자료

← 목록으로
Related

함께 읽으면 좋은 글

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

좋은 소프트웨어 설계는 화려한 패턴이나 거대한 아키텍처가 아니라 변경 비용을 낮추는 구조에서 드러난다. 단순함과 중복 제거, 자주 바뀌는 결정의 격리, 지속적 리팩터링이 쌓이면 다음 변경을 덜 아프게 받아들이는 코드가 된다. 결국 설계의 질은 다음 수정을 얼마나 잘 견디느냐로 뒤늦게 드러난다.

소프트웨어 설계코드 품질정보 은닉
잘 설계된 소프트웨어는 현재 요구사항을 넘어서 나중에 읽고 고치기 쉬운 구조를 남긴다

잘 설계된 소프트웨어는 지금 동작하는 것만으로는 충분하지 않다. 요구사항 충족, 정보 은닉, 가독성, 변경 용이성, 과잉 설계 회피라는 다섯 기준으로 다시 정리한다.

프로그래밍테스트테스트 주도 개발
테스트 주도 개발은 테스트를 나중에 붙이는 습관이 아니라 설계 순서를 바꾸는 방식이다

테스트 주도 개발은 테스트를 나중에 붙이는 습관이 아니라, 실패하는 테스트부터 써서 설계 순서 자체를 바꾸는 방식이다. 레드-그린-리팩터링의 짧은 피드백 주기에서 핵심은 테스트 개수가 아니라 설계와 검증 사이의 왕복 거리이며, 마지막 단계의 리팩터링이 빠지면 TDD는 반쪽만 남는다. 진짜 가치는 커버리지 숫자보다 더 분명한 경계선과 안전한 변경 능력에 있다.