상세 컨텐츠

본문 제목

상속을 위임으로 치환 리팩토링 ( Replace Inheritance With Delegation )

자바강좌/리팩토링

by somiyuralove 2020. 2. 16. 23:25

본문

* 상속을 위임으로 치환 리팩토링 ( Replace Inheritance With Delegation )

* 상속

- 상위 클래스에서 선언한 필드와 메서드를 하위 클래스에서 이용할 수 있음.
  이를 부모가 자식에게 물려주는(inherit)것에 비유해서 상속(inheritance)이라고 부름.
  많은 객체지향 프로그램에서 상속 기능이 있음.
  
* 위임

- 다른 인스턴스의 메서드를 호출해서 처리하는것을 처리를 위임한다(delegate)라고 표현. 
- 위임(delegation)이란 '맡긴다'는 의미임.

* 상속과 위임의 비교

- 상속은 클래스 사이의 관계이고, 위임은 인스턴스 사이의 관계, 이는 상위 클래스에서 상속받을 메서드나 필드는 인스턴스마다 정할 순 없지만,
작업을 위탁할 곳은 인스턴스마다 정할 수 있음
- 상속은 정적인 관계이고, 위임은 동적인 관계임. 이는 상속 관계는 컴파일할 때 정해지고 실행 중에 변경할 수 없지만, 위임 관계는 실행 중에 변경할 수 없기 때문임.

* 상속을 위임으로 치환

- 객체 지향 프로그래밍을 배우다 보면 상속을 남용하기도 함. 상속을 사용하면 조금만 코딩해도 상위 클래스의 기능을 바로 사용할 수 있기 때문.
- 하지만 상속을 사용해야 할 곳이 아닌 곳까지 상속을 사용하면 프로그램이 더러워지고 재사용하기 어려워짐.
- 상속을 위임으로 치환(Replace Inheritance with Delegation) 리팩토링은 부적절한 상속을 위임으로 치환함. 이렇게 하면 클래스의 역할이 명확해지고 재사용도 쉬워짐.

* 리팩토링 전 코드

package ReplaceInheritanceWithDelegation.before;

import java.util.Random;

public class Dice extends Random {
/**
 * 
 */
private static final long serialVersionUID = 1L;

public Dice() {
super(314159L);
}

public Dice(long seed) {
super(seed);
}

@Override public int nextInt() {
return nextInt(6) + 1;
}

@Override public void nextBytes(byte[] bytes) {
throw new UnsupportedOperationException();
}

@Override public long nextLong() {
throw new UnsupportedOperationException();
}

@Override public boolean nextBoolean() {
throw new UnsupportedOperationException();
}

@Override public float nextFloat() {
throw new UnsupportedOperationException();
}

@Override public double nextDouble() {
throw new UnsupportedOperationException();
}

@Override public double nextGaussian() {
throw new UnsupportedOperationException();
}
}

package ReplaceInheritanceWithDelegation.before;

public class Main {
public static void main(String[] args) {
Dice dice0 = new Dice();
Dice dice1 = new Dice(456L);
Dice dice2 = new Dice();

Dice[] dices = {
dice0,
dice1,
dice2,
};

dice2.setSeed(456L);

for(Dice d : dices) {
for(int i=0; i< 10; i++) {
System.out.printf("%d, ", d.nextInt());
}
System.out.println();
}

}
}

* 리팩토링 후 코드 

package ReplaceInheritanceWithDelegation.before;

import java.util.Random;

public class Dice {

private final Random _random;

public Dice() {
_random = new Random(314159L);
}

public Dice(long seed) {
_random = new Random(seed);
}

public int nextInt() {
return _random.nextInt(6)+1;
}

public void setSeed(long seed) {
_random.setSeed(seed);
}
}


관련글 더보기

댓글 영역