64. 객체는 인터페이스를 사용해 참조하라
주제: 객체는 인터페이스를 사용해 참조하라
(개념) 객체를 담는 변수, 필드, 메서드 매개변수, 반환 타입 등을 선언할 때, 실제 객체의 구체 클래스 타입 대신 해당 객체가 구현한 인터페이스 타입을 사용하라는 원칙.
(확장) 아이템 51 "매개변수 타입으로 인터페이스 사용" 원칙을 프로그램 전반으로 확장.
핵심 원칙
참조는 인터페이스로 (Reference via Interface)
생성만 클래스로 (Instantiate with Class)
// 좋은 예: 인터페이스로 참조, 클래스로 생성 List<User> users = new ArrayList<>(); Map<String, Data> dataMap = new HashMap<>(); MemberService service = new MemberServiceImpl(); // 나쁜 예: 구체 클래스로 참조 (유연성 저하) ArrayList<User> users2 = new ArrayList<>();
장점
graph LR
A[Client Code] --> B(Service Interface);
B -- impl --> C[ServiceImpl_A];
B -- impl --> D[ServiceImpl_B];
B -- impl --> E[ServiceImpl_C];유연성 향상 (Increased Flexibility)
구현 교체 용이 (Easy Implementation Swapping)
테스트 용이성 & DI 활용 (Improved Testability & DI Usage)
주의점 (Potential Issues)
암묵적 동작 의존 (Dependency on Implicit Behavior)
LinkedHashSet -> HashSet
컴파일 시점 오류 (Compile-time Errors)
예외
적합한 인터페이스 부재 (No Suitable Interface)
값 클래스 (
Value Classes)String,Integer,BigInteger등. 클래스 타입 직접 사용
클래스 기반 프레임워크 (Class-based Frameworks)
java.io.InputStream,OutputStream
구체 클래스 고유 메서드 필수 사용 시 (Need for Class-specific Methods)
ArrayList의 TrimToSize()PriorityQueue의comparator()
예외 상황 대처 (Handling Exceptions)
Trade-off 인지 (Acknowledge Trade-off) (유연성 < 특정 기능 이점)
대처 방안 (Choose Your Approach)
구체 클래스 타입 직접 선언 (Declare Concrete Class Type)
instanceof+ 캐스팅 (Useinstanceof+ Casting)
최종 요약 (Key Takeaway)
"특별한 이유(고유 메서드 필수 사용 등)가 없다면, 항상 가장 추상적인 타입(인터페이스 > 상위 클래스)으로 참조하라. 특정 구현의 이점이 유연성보다 명확히 중요할 때만 예외를 고려하라."
Last updated