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 추상 함수가 제공하죠.
페드로: 편리하네요.