객체지향 프로그래밍에서의 상속과 조합: aiohttp의 설계 선택 이유
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
웹 개발
대상자
Python 및 aiohttp 프레임워크를 사용하는 개발자, API 설계자, 라이브러리 유지보수자
핵심 요약
- 상속 사용 시 발생하는 주요 문제 :
web.Application
의foo()
메서드와 같은 명명 충돌 및 이후 버전 업데이트 시 예기치 못한 오류 발생 가능성 - 조합 방식의 장점 : 프레임워크와 사용자 코드의 명확한 분리 및 확장성 향상, 그러나 타입 체커와 순환 참조 문제 유발
- 설계 선택의 근본 이유 : 안정성과 유지보수성을 위해 편의성 대신 안정성을 선택한 라이브러리 유지보수자의 판단
섹션별 세부 요약
1. 상속을 통한 확장 시 발생하는 문제
- 명명 충돌 : 사용자가
foo()
메서드를 정의한 후, aiohttp이 동일한 이름의 속성을 추가하면 코드 실행 중 오류 발생 - Namespace Pollution : 사용자 코드와 프레임워크 코드가 혼합되어 유지보수 어려움 증가
- 아키텍처 설계적 한계 :
web.Application
은 메서드 오버라이딩이 아닌 신호/콜백 기반 설계로 되어 있음
2. 조합 방식의 적용과 한계
- 조합 구현 예시 :
```python
class MyApp:
def __init__(self):
self.app = web.Application()
self.app['my_app'] = self
```
- 타입 체커 문제 :
app['my_app']
의 타입 정보가 불확실하게 처리됨 - 순환 참조 :
my_app.app
과app['my_app']
간 양방향 참조로 메모리 누수 위험
3. 설계 선택의 근본적인 고려사항
- 안정성 vs 편의성 : 사용자 편의보다 버전 업데이트 시 기존 애플리케이션의 파괴 방지가 우선
- 유지보수성 고려 : 구현 세부 사항에 대한 의존성 최소화 및 장기적인 코드 구조 유지
- 라이브러리 유지보수자의 경험 : 실제 사용자 사례와 유지보수 과거의 문제점을 바탕으로 설계 결정
4. API 설계의 핵심 교훈
- OOP 원칙이 아닌 '미래 예측' : 장기적인 안정성과 확장성을 위한 보수적인 설계 선택
- 라이브러리의 설계 선택 이유 : 사용자 경험의 단기 편의보다 장기적인 유지보수성을 위한 보수적 결정
결론
- aiohttp의 설계 선택은 '안정성'을 위한 희생이며, 상속보다 조합을 권장
- 타입 체커와 순환 참조 문제를 해결하기 위해 보완 방안이 필요하지만, 현재의 선택이 장기적 유지보수성에 유리
- 라이브러리의 설계 결정은 사용자 경험보다 유지보수성과 안정성을 우선시하는 실무적 고려를 반영함