안전하게 리팩토링하기
SOLID 원칙 중 DIP가 있다.
어떻게 하면 쉽게 리팩토링 할 수 있는지 간단하면서도 강력한 방법을 이야기해볼까 한다.
이것을 아래와 같이 변경한다고 해보자.
public class LotteriesFactory {
private final RandomNumberGenerator randomNumberGenerator;
public LotteriesFactory(RandomNumberGenerator randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
// 만약 많은 곳에서 해당 코드를 사용하고 있다면 어찌하겠는가 ????????
public String createNumber(){
return randomNumberGenerator.create();
}
}
이것을 아래와 같이 변경한다면 어떻게 안전하게 변경할 수 있을까?
public class LotteriesFactory {
private NumberGenerator randomNumberGenerator;
public LotteriesFactory(NumberGenerator randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
// 만약 많은 곳에서 해당 코드를 사용하고 있다면 어찌하겠는가 ????????
public String createNumber() {
return randomNumberGenerator.create();
}
}
public class RandomNumberGenerator implements NumberGenerator {
@Override
public String create() {
return "123456";
}
}
혹시 여러분은 IDE 에서 어떻게 이것을 안전하게 변경할 수 있나요?
저는 이것을 안전하게 변경하기 위해서 IntelliJ 의 Refactor 기능을 적극적으로 활용할 것입니다.
.
.
.
.
.
.
.
.
.
.
.
.
어떻게 하고 계신가요? 혹시 Rename 으로 하고 있나요? 아니면 이미 한땀한땀 고치고 계신건 아닌가요?
RandomNumberGenerator randomNumberGenerator
에서 어떻게 NumberGenerator numberGenerator
로 변경했나요?
저라면 RandomNumberGenerator 여기에서부터 시작합니다.
implements NumberGenerator
와 @Override
를 활용해 아무런 비즈니스의 문제없이 NumberGenerator
를 만들어 냅니다.
public class RandomNumberGenerator implements NumberGenerator {
@Override
public String create() {
return "123456";
}
}
이후에는 어떻게 할까요?
아마도 LotteriesFactory 를 고치려 할 것 입니다.
public class LotteriesFactory {
private final RandomNumberGenerator randomNumberGenerator;
public LotteriesFactory(RandomNumberGenerator randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
public String createNumber(){
return randomNumberGenerator.create();
}
}
어떻게 하면 기존 로직에 영향없이 코드를 변경할 수 있을까요?
public class LotteriesFactory {
private NumberGenerator randomNumberGenerator;
public LotteriesFactory(RandomNumberGenerator randomNumberGenerator) {
this((NumberGenerator) randomNumberGenerator); // Look at this
}
public LotteriesFactory(NumberGenerator randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
public String createNumber(){
return randomNumberGenerator.create();
}
}
Refactor > Inline method 를 하게 되면 아래와 같이 변경됩니다.
public class LotteriesFactory {
private NumberGenerator randomNumberGenerator;
public LotteriesFactory(NumberGenerator randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
public String createNumber(){
return randomNumberGenerator.create();
}
}
class LotteriesFactoryTest {
@Test
void testA() {
LotteriesFactory factory = new LotteriesFactory((NumberGenerator) new RandomNumberGenerator());
String number = factory.createNumber();
System.out.println(number);
}
@Test
void testB() {
LotteriesFactory factory = new LotteriesFactory((NumberGenerator) new RandomNumberGenerator());
String number = factory.createNumber();
System.out.println(number);
}
}
이렇게 함으로써 안전하게 코드를 리팩토링하게 됩니다.
[추가 피드백]
이렇게 리팩토링을 하다보니 한가지 문제점을 발견했습니다. refactor > inline method
는 강력합니다. 강력한 만큼 조심해야 될 부분이 있었습니다.
바로 위 테스트 코드처럼 목적에 따라 변경이 필요하지 않는 부분이 변경될 수 있다는 사실을 말이죠.
사실은 하나하나 사용되는 보고 리팩토링을 하는게 맞다는 생각이 듭니다.
'개발 관련됨 > 개발 관련 유용한 정보함' 카테고리의 다른 글
조영호님과 객체지향에 대해서 이야기하기 (2) | 2022.12.22 |
---|---|
postgresSQL의 Idle in transaction 이란 무엇인가? (0) | 2022.09.11 |
gradle 기반의 여러 모듈에서 공통으로 쓰인 스크립트가 있다면? (0) | 2022.02.06 |
MAC OS 에서 Icon 이 Bouncing 하지 않도록 하는 방법 (0) | 2021.09.26 |
docker 에 올라온 postgres 에 접속해, Database 확인하는 방법 (0) | 2021.07.09 |
댓글