어떤 필드가 자신이 속한 클래스보다 다른 클래스에서 더 많이 사용될 때는
대상 클래스 안에 새 필드를 선언하고 그 필드 참조 부분을 전부 새 필드 참조로 수정하자
동기
- 어떤 필드가 자신이 속한 클래스보다 다른 클래스에 있는 메서드에서 더 많이 참조한다면, 그 필드를 옮기는 것을 생각해봐야 한다
- 만약 클래스 추출을 할 경우 필드 추출이 우선이고, 메서드 추출이 그 다음이다
방법
책의 예제에는 잘 안나와있는데, 난 아래와 같이 이해했다
-
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
31class 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;
}
} -
하지만 B 클래스의
field
필드도 B 클래스내에서 사용하는 부분이 어느정도 있다(고 가정한다). 이럴땐 필드 이동으로 인한 변경을 최소화 하기 위해 이동 대상 클래스 필드(B의 field)에필드 자체 캡슐화
를 적용한다1
2
3
4
5
6
7
8
9
10
11
12
13
14class A {
// ...
}
class B {
private int field;
// getter/setter
public void someMethod() {
// do something;
getField(); // 필드 자체 캡슐화
// do something;
}
} -
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
22class 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
}
} -
B 클래스에서 A 클래스의
field
를 참조할 방법을 정한다- 참조하는 부분에서 직접
a.getField()
,a.setField()
로 접근하는 방법 필드 자체 캡슐화
한 메서드만 변경하는 방법- 2번에서 이미 수행했고, 이 방식이 변경을 가장 최소화 할 수 있다
1
2
3
4
5
6
7
8
9
10
11
12
13class B {
private A a;
public int getField() {
return a.getField();
}
public void someMethod() {
// do something;
getField(); // 변경 없음
// do something;
}
}
- 참조하는 부분에서 직접
-
B 클래스에서
field
필드를 삭제한다
참고 : 마틴 파울러, 『리팩토링』, 김지원 옮김, 한빛미디어(2012)