필드 이동

어떤 필드가 자신이 속한 클래스보다 다른 클래스에서 더 많이 사용될 때는
대상 클래스 안에 새 필드를 선언하고 그 필드 참조 부분을 전부 새 필드 참조로 수정하자

동기

  • 어떤 필드가 자신이 속한 클래스보다 다른 클래스에 있는 메서드에서 더 많이 참조한다면, 그 필드를 옮기는 것을 생각해봐야 한다
  • 만약 클래스 추출을 할 경우 필드 추출이 우선이고, 메서드 추출이 그 다음이다

방법

책의 예제에는 잘 안나와있는데, 난 아래와 같이 이해했다

  1. A 클래스안에서 B 클래스의 field 필드를 자주 이용한다면 B 클래스의 field를 A 클래스로 옮겨버릴 수 있다

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    class A {
    private B b;
    public void someMethod1() {
    // do something
    b.getField(); // 이런식으로 자주 사용된다면
    // do something
    }

    public void someMethod2() {
    // do something
    b.getField(); // 이런식으로 자주 사용된다면
    // do something
    }

    public void someMethod3() {
    // do something
    b.getField(); // 이런식으로 자주 사용된다면
    // do something
    }
    }

    class B {
    private int field;
    // getter/setter

    public void someMethod() {
    // do something;
    field;
    // do something;
    }
    }
  2. 하지만 B 클래스의 field 필드도 B 클래스내에서 사용하는 부분이 어느정도 있다(고 가정한다). 이럴땐 필드 이동으로 인한 변경을 최소화 하기 위해 이동 대상 클래스 필드(B의 field)에 필드 자체 캡슐화를 적용한다

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class A {
    // ...
    }

    class B {
    private int field;
    // getter/setter

    public void someMethod() {
    // do something;
    getField(); // 필드 자체 캡슐화
    // do something;
    }
    }
  3. A 클래스에 field 필드와 getter/setter를 작성하고, B 클래스를 참조하던 부분을 변경한다

    • 필드 이동 시 getter/setter는 세트로 같이 옮긴다
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class A {
    private int field;
    // getter/setter

    public void someMethod1() {
    // do something
    field;
    // do something
    }

    public void someMethod2() {
    // do something
    field;
    // do something
    }

    public void someMethod3() {
    // do something
    field;
    // do something
    }
    }
  4. B 클래스에서 A 클래스의 field를 참조할 방법을 정한다

    • 참조하는 부분에서 직접 a.getField(), a.setField() 로 접근하는 방법
    • 필드 자체 캡슐화한 메서드만 변경하는 방법
      • 2번에서 이미 수행했고, 이 방식이 변경을 가장 최소화 할 수 있다
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      class B {
      private A a;

      public int getField() {
      return a.getField();
      }

      public void someMethod() {
      // do something;
      getField(); // 변경 없음
      // do something;
      }
      }
  5. B 클래스에서 field 필드를 삭제한다

참고 : 마틴 파울러, 『리팩토링』, 김지원 옮김, 한빛미디어(2012)