2017-02-15 4 views
0

디자인 패턴 책의 추상 팩토리 패턴 샘플 코드와 관련하여 질문이 있습니다.디자인 패턴 - 초록 공장 - BombedMazeFactory

이 책은 방을 연결하는 벽과 문이있는 미로 게임의 단순하고 부분적인 예를 제공합니다.

다음 팩토리 메소드가 기본 MazeFactory 클래스가 :

class MazeFactory { 
public: 
    MazeFactory(); 

    virtual Maze* MakeMaze() const { return new Maze; } 
    virtual Wall* MakeWall() const { return new Wall; } 
    virtual Room* MakeRoom(int n) const { return new Room(n); } 
    virtual Door* MakeDoor(Room* r1, Room* r2) const { 
     return new Door(r1, r2); 
    } 
} 

저자 (들)을 다음 MazeFactory의 전문성 정의 :

class BombedMazeFactory : public MazeFactory { 
    BombedMazeFactory(); 

    virtual Room* MakeWall() const { return new BombedWall; } 
    virtual Door* MakeRoom(int n) const { return new RoomWithABomb(n); } 
}; 

내가 정확히 방법을 모른다는 RoomWithABomb는 작동하지만 폭탄을 포함 할 확률이 5 % 인 방을 만들고 폭파 된 폭탄이있는 방을 포함하는 문을 열면 폭발 할 수 있다고 가정합니다.

이제 클라이언트가 BombedMazeFactory 클래스를 사용하여 미로를 만들고 일부 룸을 생성한다고 가정 해 보겠습니다. 생성 된 룸은 RoomWithABomb * 유형이지만 팩토리는 Room *을 반환합니다.

일부 미로 게임 논리를 구현하기 위해 방에 폭탄이 있는지 여부를 확인해야한다고 가정하지만 방 *은 폭탄에 대한 지식이 없습니다. 방에 폭탄이 들어 있는지 알아낼 수있는 유일한 방법은 룸 *을 나쁜 연습 인 RoomWithABomb *로 캐스팅하는 것입니다.

예가별로 좋지 않거나 이와 같은 사례를 처리하는 다른 방법이 있습니까?

+0

각 방에 Enter() 메서드가있는 경우 RoomWithABomb 서브 클래스에서 재정의 할 수 있으며 임의로 폭탄을 설정하는 논리가 있습니다. – dbugger

답변

0

대답은 여기에 어떤 방의 방을 알 필요가 없다는 것입니다. Roomenter()이라는 클래스의 클래스이고 방을 입력하면 무언가를 출력한다고 가정 해 보겠습니다. 이 클래스는 (제가 C++에 익숙한 아니에요 이후 자바에서이 작업을 수행 할 수 있습니다,하지만 당신은 아이디어를 얻을 것)과 같이 수 :

public class Room { 

    protected int roomNumber; 

    public Room(int n) { 
     roomNumber = n; 
    } 

    public void enter() { 
     System.out.println("You entered room number " + roomNumber); 
    } 

    public void getRoomNumber() { 
     return roomNumber; 
    } 
} 

지금의 폭탄이있는 방에 대해 생각해 보자. 분명히 그것은 Room의 파생물이지만 "You exploded"와 같은 것을 출력해야합니다.

public class RoomWithABomb extends Room { 
    public RoomWithABomb(int n) { 
     super(n); 
    } 

    public void enter() { 
     System.out.println("Oh no! There was a bomb in the room! You died"); 
    } 

} 

그래서 지금 우리 RoomWithABomb 클래스는 Room 클래스의 동작보다 우선합니다 (다형성을!). 그러나 호출자는 입력 된 방의 종류를 정확하게 알 필요가 없습니다. Room (따라서 Room에서 상속되므로 RoomWithABomb이 모두이므로)은 enter() 메서드를가집니다.

그래서 추상 공장의 의도는 무엇입니까? 공통의 수퍼 클래스 나 인터페이스를 상속받은 유사한 객체를 생성하여 다른 객체가 객체를 생성하는 방법을 알 필요가 없도록 만듭니다. 이렇게함으로써 우리는 상기 인터페이스의 구체적인 구현으로부터 다른 객체들을 분리합니다 (Maze는 폭탄이있는 방도 있다는 것을 모릅니다).

+0

이 답변에 만족합니다. 게임의 상태를 변경하기 위해 MazeGame 인스턴스가 필요하므로 enter()를 실행하면 커플 링이 증가하지만 좋은 대안은 없습니다. – mrpringle