Abstract Factory Pattern
사용자들이 게임의 새 레벨들을 사지 않고 있다. 세이망 게르(Saimank Gerr)가 불평과 관련된 워드클라우드를 만들었는데, 가장 많은 부정적 피드백 단어는 “추해”, “형편 없어”, “엉망이야” 이다.
레벨 구축 시스템을 개선하라.
페드로: 내가 말했었죠, 이건 형편 없다고.
이브: 확실히 그래요, 눈 배경에도 나무 벽이 있고, 우주 침략자들에도 나무 벽이 있고, 온통 나무 벽이에요.
페드로: 그러니 게임 세계를 레벨 별로 분리하고 각 레벨에 맞는 객체들을 만들어야 해요.
이브: 설명해 주세요.
페드로: 구체적인 블럭을 만드는 데 팩토리 메소드 패턴 대신, 추상 팩토리 패턴을 이용해서 서로 관련된 객체들을 만들어 주면 레벨들이 좀 나아보일 거에요.
이브: 예제가 있으면 좋겠어요.
페드로: 코드가 예제죠. 우선 레벨 팩토리에 추상 행위를 정의해요.
public interface LevelFactory {
Wall buildWall();
Back buildBack();
Enemy buildEnemy();
}
페드로: 그리고 레벨들을 구성하는 객체들의 계층도를 만듭니다.
class Wall {}
class PlasmaWall extends Wall {}
class StoneWall extends Wall {}
class Back {}
class StarsBack extends Back {}
class EarthBack extends Back {}
class Enemy {}
class UFOSoldier extends Enemy {}
class WormScout extends Enemy {}
페드로: 알겠나요? 각 레벨마다 고유한 객체들이 있죠. 이제 팩토리를 만들어 보죠.
class SpaceLevelFactory implements LevelFactory {
@Override
public Wall buildWall() {
return new PlasmaWall();
}
@Override
public Back buildBack() {
return new StarsBack();
}
@Override
public Enemy buildEnemy() {
return new UFOSoldier();
}
}
class UndergroundLevelFactory implements LevelFactory {
@Override
public Wall buildWall() {
return new StoneWall();
}
@Override
public Back buildBack() {
return new EarthBack();
}
@Override
public Enemy buildEnemy() {
return new WormScout();
}
}
페드로: 각 레벨 팩토리의 클래스들은 자신의 레벨과 관련된 객체들을 만들어요. 레벨들은 이제 확실히 더 나아졌어요.
이브: 어디 봅시다. 그런데 어떤 차이가 있는지 모르겠네요.
페드로: 팩토리 메소드 패턴은 객체 생성을 하위 클래스로 넘겨요. 추상 팩토리 패턴은 같은 일을 하지만 서로 관련된 객체들에 대해서 그렇게 하죠.
이브: 아하, 추상 빌더에 서로 관련된 함수들을 전달하면 된다는 의미로군요.
(defn level-factory [wall-fn back-fn enemy-fn])
(defn make-stone-wall [])
(defn make-plasma-wall [])
(defn make-earth-back [])
(defn make-stars-back [])
(defn make-worm-scout [])
(defn make-ufo-solider [])
(def underground-level-factory
(partial level-factory
make-stone-wall
make-earth-back
make-worm-scout))
(def space-level-factory
(partial level-factory
make-plasma-wall
make-stars-back
make-ufo-solider))
페드로: 알겠어요.
이브: 모든 것이 깔끔하죠. 당신이 좋아하는 “서로 관련된 X들의 집합”, 여기서 X는 함수죠.
페드로: 네, 그런데 partial은 뭐죠?
이브: 함수에 파라미터를 일부만 주는 거에요. 그래서 underground-level-factory는 wall과 back과 enemy를 구축하는 법을 알죠. 나머지 작업은 level-factory 추상 함수가 제공하죠.
페드로: 편리하네요.