Java
팩토리 메서드 패턴을 적용해보자
siwoli
2023. 10. 26. 15:52
팩토리 메서드 패턴이란?
- 오버라이드된 메서드가 객체를 반환하는 패턴
- 팩토리 메서드 : 객체를 생성함과 동시에 반환하는 메서드
- 하위 클래스에서 팩토리 메서드를 오버라이딩해서 서로 다른 객체를 반환한다.
- 하위 클래스에서 구체적인 객체 생성 방법을 결정한다.
- 객체지향 설계 원칙 중 의존 역전 원칙(Dependency Inversion Principle)이 적용된 패턴이다.
템플릿 메서드 패턴과 비슷하면서도 다르다.
템플릿 메서드 패턴은 식품 공장 중 하나의 과자 공장에서 서로 다른 종류의 과자를 만드는 거라면
팩토리 메서드 패턴은 식품 공장 중 과자 종류별 공장들에서 각자의 과자를 만드는 거라고 볼 수 있다.
팩토리 메서드 패턴은 생성자를 반환해서 그 생성자만의 동작을 수행하도록 하는데 초점이 맞춰저 있다.
즉 전체 구조에 영향을 최소화하고 객체를 어떻게 사용할지 정할 수 있다.
우테코 프리코스 1주차에서 게임을 실행하는 기능에 이를 적용했다.
먼저 공통된 메서드를 수행하도록 팩토리 인터페이스를 만들었다.
public interface GameFactory {
Game create();
}
Game
은 게임 단위별 클래스들의 상위 클래스로, 객체를 반환할때 공통된 타입을 지정하기 위해 만들었다.
그다음 각 게임 단위별 구현 클래스를 만들어 해당하는 게임단위의 객체를 반환하는 메서드를 만들었다.
public class UnitOfGameFactory implements GameFactory {
@Override
public UnitOfGame create() {
return new UnitOfGame(new ComputerNumbersGenerator());
}
}
public class SetOfGameFactory implements GameFactory {
@Override
public SetOfGame create() {
return new SetOfGame(new UnitOfGameFactory());
}
}
SetOfGame
은 게임 한 세트를 실행한다.
생성자로 UnitOfGameFactory
객체를 받아서 create()
로 UnitOfGame
객체를 받아 사용한다.
public class SetOfGame extends Game {
private final UnitOfGameFactory unitOfGameFactory;
public SetOfGame(UnitOfGameFactory unitOfGameFactory) {
this.unitOfGameFactory = unitOfGameFactory;
}
@Override
public void play() {
String userInput;
do {
UnitOfGame unitOfGame = unitOfGameFactory.create();
unitOfGame.play();
userInput = promptUserInput();
} while (Objects.equals(userInput, "1"));
}
private String promptUserInput() {
String userInput;
do {
GameView.printAfterSetOfGame();
userInput = readLine();
} while (!Objects.equals(userInput, "1") && !Objects.equals(userInput, "2"));
return userInput;
}
}
TotalGame
은 SetOfGameFactory
객체를 받아서 create()
를 통해 SetOfGame
객체를 사용한다.
public class TotalGame extends Game{
private final SetOfGameFactory setOfGameFactory;
public TotalGame(SetOfGameFactory setOfGameFactory) {
this.setOfGameFactory = setOfGameFactory;
}
@Override
public void play() {
GameView.printBeforeTotalGame();
SetOfGame setOfGame = setOfGameFactory.create();
setOfGame.play();
GameView.printAfterTotalGame();
}
}
이게 맞는 방법인지 확실하진 않지만 이렇게 하니 각 게임 단위별 클래스를 공통된 로직으로 다르게 사용할 수 있었다.