추상화는 당신의 코드를 더 나쁘게 만든다.
Abstraction Can Make Your Code Worse by CodeAesthetic
추상화가 코드를 더 나쁘게 만드는 이유: 추상화와 결합도의 트레이드오프
이 영상은 소프트웨어 설계에서 반복을 제거하기 위해 사용하는 추상화가 필연적으로 결합도를 유발한다는 점을 지적하며, 추상화의 이점이 결합도로 인한 비용보다 클 때만 이를 도입해야 한다는 핵심 메시지를 전달합니다.
1. 추상화의 탄생과 일반적인 인식
- 게임 개발 예시를 통한 추상화의 이해
- 주인공 캐릭터, 적 캐릭터, 장애물이라는 세 가지 객체가 존재함.
- 각 객체는 월드 내 위치 추적 코드와 이미지 렌더링 코드가 필요함.
- 세 클래스에 동일한 코드를 작성하는 대신, 공통 기능을 처리하는 게임 객체(Game Object) 클래스를 생성함.
- 하위 클래스가 어떤 이미지를 보여줄지만 지정하게 함으로써 일반적인 구현을 완성함.
- 설계자의 본능
- 아키텍트들은 반복을 식별하고 추출하는 데 익숙함.
- **"코드 반복은 나쁘고, 더 많은 추상화는 좋다"**는 모드로 프로그래밍에 임함.
2. 숨겨진 비용: 결합도(Coupling)
- 결합도의 정의와 체감
- 엔지니어들은 개념적으로 결합도를 이해하며, 과도하게 결합된 시스템을 수정할 때 그 불편함을 체감함.
- 그러나 소프트웨어를 설계하는 시점에는 결합도의 영향을 즉각적으로 느끼지 못함.
- 추상화와 결합도의 관계
- 결합도는 추상화의 동일하고 반대되는 작용임.
- 추상화를 추가할 때마다 그만큼의 결합도가 시스템에 추가됨.
3. 부적절한 추상화의 사례 연구: 데이터 저장 방식의 변경
- 상황 설정
- 데이터를 XML로 저장하던 기존 프로그램에서 새로운 포맷인 JSON으로 이동하려는 상황임.
- 잘못된 접근: 기존 로직에 설정 추가
- 저장 로직에 구성을 추가하여 두 모드를 모두 지원하게 만들 수 있음.
- 이 방식은 로직이 서로 뒤섞여 있어, 나중에 XML 지원을 제거할 때 복잡하고 위험함.
- 권장되는 접근: 클래스 분리
- JSON 작성기를 별도의 클래스로 만듦.
- XML 지원이 더 이상 필요 없을 때 프로그램 로직을 해체할 필요 없이 파일 전체를 삭제하면 됨.
- 불필요한 추상화의 유혹 1: 공통 변수 추출
- XML과 JSON 클래스 모두 생성 시 파일 이름을 입력받는다는 공통점을 발견함.
- 이를 추출하기 위해 파일 이름을 가진 파일 저장자(File Saver) 부모 클래스를 만들고 보호된 변수로 상속받으려는 본능이 생김.
- 부정적 결과: 두 클래스가 '파일 입력'이라는 동일한 입력 방식에 결합됨.
- 한계: 향후 데이터베이스나 클라우드 연결처럼 파일이 아닌 방식을 사용할 때 이 추상화는 깨짐.
- 가치 판단: 변수 하나를 중복 할당하지 않는 것 외에 로직상의 이점이 없으므로 추상화할 가치가 없음.
- 불필요한 추상화의 유혹 2: 공통 인터페이스
- 두 클래스의 저장 메서드를 대표하는 인터페이스 생성을 고려함.
- 부정적 결과: 두 클래스가 동일한 저장 메서드 형식을 따르도록 제약(결합)됨.
- 실제 사용 사례: 조건문을 통해 클래스를 선택하고 저장 메서드를 호출하는 구조에서, 인터페이스를 추가해도 단 한 줄의 중복 코드만 제거될 뿐 프로그램이 유의미하게 단순해지지 않음.
- 판단: 연결 고리가 없는 두 개의 별개 클래스로 유지하는 것이 더 나음.
4. 추상화가 가치 있는 경우 (도입 기준)
- 사례 1: 저장 옵션의 증가
- 저장 옵션이 3개 이상으로 늘어날 때.
- 특히 각 저장자(데이터베이스 설정 등)가 서로 다른 파라미터를 가질 때, 이들의 생성을 별도 코드로 추출하는 것이 유익함.
- 사례 2: 실행 시점의 지연 또는 반복
- 프로그램이 저장을 나중에 수행하거나 반복해야 할 때.
- 예: 5분마다 자동으로 저장하는 인터널 저장자(Interval Saver) 클래스 생성.
- 이 클래스는 어떤 구체적인 저장자가 호출되는지 알 필요가 없어야 함.
- 핵심 기준
- **"어떤 저장자를 사용할지에 대한 결정"**과 **"실제로 저장하는 시점"**을 분리하고 싶을 때 추상화는 가치를 지님.
5. 최종 결론
- 추상화가 가져오는 가치가 결합도로 인한 비용보다 클 때만 추상화를 적용해야 함.
- 약간의 코드 반복은 허용될 수 있음.
- 과도한 결합보다는 약간의 코드 반복이 코드를 변경할 때 고통이 적음.
토픽:
프로그래밍