Java Refactoring -8, 응집도가 낮은 멤버 클래스 개선

박태건·2021년 7월 20일
1

리팩토링-자바

목록 보기
8/13
post-thumbnail
post-custom-banner

레거시 코드를 클린 코드로 누구나 쉽게, 리팩토링

위 책을 보면서 정리한 글입니다.

응집도가 낮은 멤버 클래스 개선

내부 클래스에만 종속적이지 못한 멤버 클래스는 그 가치를 잃어버린다.

  • 기능이 크거나 많은 클래스는 비대해질 수 밖에 없다.
  • 따라서 큰 기능을 처리할 때 '내부 클래스'를 사용하여 클래스가 비대해지는 것을 방지
  • 내부 클래스를 사용하면 다른 기능과 명확하게 구분 가능하여
    • 코드의 가독성을 높이고
    • 유지보수에 드는 시간도 줄일 수 있다

  • 내부 클래스가 잘못 사용되는 경우
    • 멤버 클래스의 남용
      • 멤버 클래스가 다른 객체를 위한 클래스로 확장되거나 수정될 때 더 이상 멤버 클래스가 아니게 된다.

개선방향

의도와 맞지 않는 멤버 클래스를 일반 클래스로 추출

질문답

내부 클래스란

  • 일반 클래스 내에 존재하는 클래스, 중첩 클래스라고도 부른다.
  • 내부 클래스 분류
구분구조설명
정적 내부 클래스- 외부 클래스를 인스턴스화하지 않아도 바로 사용 가능한 내부 클래스
멤버 내부 클래스- 외부 클래스의 필드나 메서드 사용 가능
- 내부 클래스는 외부 클래스가 인스턴스화 된 후부터 동작
지역 내부 클래스- 메서드 내에 국한되어 사용되는 내부 클래스
- 메서드 내의 지역변수 사용 가능(final로 정의해야 한다-메서드의 동작이 종료된 후에도 클래스의 동작이 종료되지 않기 때문에)
익명 내부 클래스- 일반적인 변수를 인스턴스화하면서 오버라이드 메서드를 구현하는 형태

내부 클래스 사용은 언제 할까

  • 정적 클래스는 외부 클래스를 사용하기 위해 외부 클래스에서 노출하는 클래스 (대표적 예로 빌더 패턴)
  • 멤버 클래스는 보통 외부 클래스의 필드와 유기적으로 연동하여 특정 기능을 구현.
    • 이 때 멤버 클래스는 외부 클래스에 직접 접근 가능하여 private이나 protected로 보호 수준을 설정하여 멤버 클래스를 통해 외부 클래스의 필드에 접근 불가능하도록 해야 한다.
  • 지역 클래스는 함수 내에서 간단한 비동기 처리로 객체를 사용할 때 흔히 사용.
  • 익명 클래스는 인터페이스의 멤버 필드를 재정의해서 사용할 때 흔히 사용.

public 보호 수준을 가진 멤버 클래스를 굳이 일반 클래스로 변경하는 이유

  • 멤버 클래스를 public으로 정의한다는 것부터가 모순이기 때문
    • 일반적인 멤버 클래스는 외부 클래스의 일부 기능으로 외부 클래스의 책임과 역할에 종속적.
    • 보호 수준이 public이라면 다른 객체에서 외부 클래스의 인스턴스를 통해 독립적으로 생성하고 사용한다는 것은 외부 클래스에 종속적이지 않다는 것을 의미
    • 따라서 멤버 클래스는 독립적인 클래스로 구현해야 한다.

레거시 코드

ListDisplay 클래스의 기능이 설계 초기에는 ListComponent만의 리스팅 기능을 위해 만들어졌으나, 이후 MyOrderView 클래스에서 MyOrderView에서 필요한 기능을 ListDisplay 추가하고, 참조하여 사용.

레거시 코드 개선 과정

  1. ListDisplay에 직접 접근하던 ListComponent.ListEventListener를 참조 변수로 받기
  2. MyOrderVie에서 ListComponent를 통한 접근을 ListDisplay 접근으로 변경
  3. ListDisplay를 별도의 클래스로 추출

-- 코드 생략

개선된 레거시 코드

ListComponent 클래스

  • 멤버 클래스인 ListDisplay 제거, 독립적인 ListDisplay를 인스턴스화하여 로직 구현

ListDisplay 클래스

  • 외부 클래스인 ListComponent 클래스의 리스트 이벤트를 참조하는 ListDisplay 클래스의 멤버 필드로 가져와서 참조하도록 변경, 멤버 클래스가 아닌 독립적인 클래스로 추출

MyOrderView 클래스

  • ListComponent 클래스의 멤버 클래스인 ListDisplay 클래스를 사용하여 구현했던 구문을 독립된 클래스로 추출된 ListDisplay 클래스로 수정하여 구현

요약 및 정리

외부 클래스와 전혀 상관없는 기능이 멤버 클래스에 존재하면, 이는 곧 다른 클래스에서 어딘가 사용하고 있다는 뜻이므로, 멤버 클래스가 아닌 독립적인 클래스로 수정되어야 한다.

잘못 사용된 멤버 클래스를 개선하기 위한 생각의 흐름

  1. 멤버 클래스가 public이라면 의심.
  2. 멤버 클래스를 사용하는 클래스를 확인.
  3. 멤버 클래스를 또다른 클래스에서 사용하고 있다면 독립적인 클래스로 전환, 외부 클래스에 종속되어 사용된 필드나 메서드를 멤버 클래스에 속하게 만든다.
  4. 멤버 클래스를 사용한 클래스를 독립된 다른 클래스를 사용하는 코드로 수정.
profile
노드 리액트 스프링 자바 등 웹개발에 관심이 많은 초보 개발자 입니다
post-custom-banner

0개의 댓글