Mixin — is-a 인 척 안 하는 상속 패턴
Mixin 은 다른 거랑 결합 위해 디자인된 클래스 — 단독 인스턴스화 X. 보통 집중된 동작 청크 — SerializableMixin 이 to_json() 추가, LoggingMixin 이 log() 추가. 받는 클래스가 mixin 상속해서 그 동작 받음. 이름 컨벤션 도움 — NameMixin 이 명사 X, 라벨처럼 읽혀.
합성 선호인데 mixin 이 왜 있나
합성이 권장 디폴트면 왜 mixin? 다음일 때 값어치 — (a) 동작이 진짜 모든 메서드 호출에 있어야 할 때, (b) 동작이 호스트 클래스 속성에 의존 (mixin 이 어떤 클래스든 자기 포함한 클래스의 self.x 사용 가능), (c) 다형 dispatch 필요 — 구체 클래스 무관하게 "serializable" 객체와 작동하는 코드.
위험 — diamond 와 의외 override
같은 메서드 정의하는 두 mixin 이 diamond 만들어. 계층에 mixin 추가하면 의도 안 한 메서드 override 가능. MRO 가 누가 이길지 결정. mixin 은 충돌 가능성 낮은 직교 관심사용 — 겹치는 거엔 X.
합성이 이길 때
대부분 시간. self.serializer = JsonSerializer() 가 class MyClass(JsonSerializerMixin): 보다 명확. 클래스 변경 없이 serializer 교체 가능. 계층 평탄하게 유지. 테스트가 fake 주입 가능. 비용은 한 단계 indirection (obj.serializer.serialize() vs obj.serialize()) — 보통 그 값어치.
isinstance(obj, SerializableMixin) 이 의미 있어야. 아니면 합성.