위 책을 보면서 정리한 글입니다.
내부 클래스에만 종속적이지 못한 멤버 클래스는 그 가치를 잃어버린다.
내부 클래스란
- 일반 클래스 내에 존재하는 클래스, 중첩 클래스라고도 부른다.
- 내부 클래스 분류
구분 구조 설명 정적 내부 클래스 - 외부 클래스를 인스턴스화하지 않아도 바로 사용 가능한 내부 클래스 멤버 내부 클래스 - 외부 클래스의 필드나 메서드 사용 가능
- 내부 클래스는 외부 클래스가 인스턴스화 된 후부터 동작지역 내부 클래스 - 메서드 내에 국한되어 사용되는 내부 클래스
- 메서드 내의 지역변수 사용 가능(final로 정의해야 한다-메서드의 동작이 종료된 후에도 클래스의 동작이 종료되지 않기 때문에)익명 내부 클래스 - 일반적인 변수를 인스턴스화하면서 오버라이드 메서드를 구현하는 형태
내부 클래스 사용은 언제 할까
- 정적 클래스는 외부 클래스를 사용하기 위해 외부 클래스에서 노출하는 클래스 (대표적 예로 빌더 패턴)
- 멤버 클래스는 보통 외부 클래스의 필드와 유기적으로 연동하여 특정 기능을 구현.
- 이 때 멤버 클래스는 외부 클래스에 직접 접근 가능하여 private이나 protected로 보호 수준을 설정하여 멤버 클래스를 통해 외부 클래스의 필드에 접근 불가능하도록 해야 한다.
- 지역 클래스는 함수 내에서 간단한 비동기 처리로 객체를 사용할 때 흔히 사용.
- 익명 클래스는 인터페이스의 멤버 필드를 재정의해서 사용할 때 흔히 사용.
public 보호 수준을 가진 멤버 클래스를 굳이 일반 클래스로 변경하는 이유
- 멤버 클래스를 public으로 정의한다는 것부터가 모순이기 때문
- 일반적인 멤버 클래스는 외부 클래스의 일부 기능으로 외부 클래스의 책임과 역할에 종속적.
- 보호 수준이 public이라면 다른 객체에서 외부 클래스의 인스턴스를 통해 독립적으로 생성하고 사용한다는 것은 외부 클래스에 종속적이지 않다는 것을 의미
- 따라서 멤버 클래스는 독립적인 클래스로 구현해야 한다.
ListDisplay 클래스의 기능이 설계 초기에는 ListComponent만의 리스팅 기능을 위해 만들어졌으나, 이후 MyOrderView 클래스에서 MyOrderView에서 필요한 기능을 ListDisplay 추가하고, 참조하여 사용.
- ListDisplay에 직접 접근하던 ListComponent.ListEventListener를 참조 변수로 받기
- MyOrderVie에서 ListComponent를 통한 접근을 ListDisplay 접근으로 변경
- ListDisplay를 별도의 클래스로 추출
-- 코드 생략
외부 클래스와 전혀 상관없는 기능이 멤버 클래스에 존재하면, 이는 곧 다른 클래스에서 어딘가 사용하고 있다는 뜻이므로, 멤버 클래스가 아닌 독립적인 클래스로 수정되어야 한다.
- 멤버 클래스가 public이라면 의심.
- 멤버 클래스를 사용하는 클래스를 확인.
- 멤버 클래스를 또다른 클래스에서 사용하고 있다면 독립적인 클래스로 전환, 외부 클래스에 종속되어 사용된 필드나 메서드를 멤버 클래스에 속하게 만든다.
- 멤버 클래스를 사용한 클래스를 독립된 다른 클래스를 사용하는 코드로 수정.