728x90
반응형
source 는 Github 에 있습니다.
목차는 테스트 & 리팩토링 목차 에 있습니다.
[테스트 & 리팩토링 6편] 팩토리 패턴 if else 줄이기 (map, functional interface 사용)
팩토리 패턴이란?
객체를 생성해주는 패턴 중 하나 입니다.
객체를 생성하는 인터페이스를 미리 정의하고, 인스턴스를 만들 클래스의 결정을 서브 클래스에서 결정합니다.
아래 소스는 팩토리 패턴으로 구현한 소스이며, 리팩토링 전입니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FactoryPatternExample { | |
public static void main(String[] args) { | |
Sport sport = getSport(SportTypeCd.SOCCER); | |
sport.play(); | |
} | |
public static Sport getSport(SportTypeCd sportTypeCd) { | |
if (SportTypeCd.BASEBALL.equals(sportTypeCd)) { | |
return new Baseball(); | |
} else if (SportTypeCd.SOCCER.equals(sportTypeCd)) { | |
return new Soccer(); | |
} else { | |
throw new IllegalArgumentException(String.format("invalid sportTypeCd : ", sportTypeCd)); | |
} | |
} | |
@Getter | |
@RequiredArgsConstructor | |
private enum SportTypeCd { | |
SOCCER("SOCCER", "축구"), | |
BASEBALL("BASEBALL", "야구") | |
; | |
private final String code; | |
private final String desc; | |
} | |
} |
If else 를 줄이는 방법
- 아래와 같이 Map 에 집어넣고 데이터를 가져온다면 if else 를 줄일 수 있습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FactoryPatternRefactoringExample { | |
private static Map<SportTypeCd, Sport> map = new HashMap<>(); | |
static { | |
map.put(SportTypeCd.SOCCER, new Soccer()); | |
map.put(SportTypeCd.BASEBALL, new Baseball()); | |
} | |
public static void main(String[] args) { | |
Sport sport = getSport(SportTypeCd.SOCCER); | |
sport.play(); | |
} | |
public static Sport getSport(SportTypeCd sportTypeCd) { | |
return map.get(sportTypeCd); | |
} | |
@Getter | |
@RequiredArgsConstructor | |
private enum SportTypeCd { | |
SOCCER("SOCCER", "축구"), | |
BASEBALL("BASEBALL", "야구") | |
; | |
private final String code; | |
private final String desc; | |
} | |
} |
interface 구현 없이 Functional interface 사용
- Supplier
functional interface 는 매개변수 없이 T 를 리턴합니다. - T get()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FactoryPatternRefactoring_v2_Example { | |
public static void main(String[] args) { | |
SportInstance sportInstance = SportInstance.findSportInstance(SportInstance.SOCCER.getCode()); | |
System.out.println(sportInstance.getSupplier().get()); | |
} | |
@Getter | |
private enum SportInstance { | |
SOCCER("SOCCER", () -> "play soccer..."), | |
BASEBALL("BASEBALL", () -> "play baseball..."), | |
; | |
private static Map<String, SportInstance> instanceMap = | |
Arrays.stream(SportInstance.values()).collect(Collectors.toMap(o -> o.getCode(), o -> o)); | |
private String code; | |
private Supplier<String> supplier; | |
SportInstance(String code, Supplier supplier) { | |
this.code = code; | |
this.supplier = supplier; | |
} | |
private static SportInstance findSportInstance(String sportTypeCd) { | |
return Optional.ofNullable(instanceMap.get(sportTypeCd)) | |
.orElseThrow(IllegalArgumentException::new); | |
} | |
} | |
} |
'test & refactoring' 카테고리의 다른 글
[테스트 및 리팩토링 8편] fixture-monkey 정리 (0) | 2023.05.05 |
---|---|
[테스트 및 리팩토링 7편] TestContainer Example (0) | 2023.04.22 |
[테스트 & 리팩토링 4편] github pull request template 및 CodeReview 정리 (0) | 2022.06.27 |
[테스트 & 리팩토링 3편] package layer, package import 정리 (0) | 2022.06.27 |
[테스트 & 리팩토링 1편] 외부 연동 코드를 테스트 하는 방법 (0) | 2022.03.24 |
댓글