设计模式 - 抽象工厂 - BombedMazeFactory

时间:2017-02-15 23:33:25

标签: design-patterns factory abstract

我对“设计模式”一书中的抽象工厂模式示例代码有疑问。

这本书展示了迷宫游戏的简化局部示例,其中有连接房间的墙壁和门。

有一个基本的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 *。

为了实现一些迷宫游戏逻辑,我认为你需要检查房间是否包含炸弹,但是Room *不知道炸弹。我们可以找出房间是否包含炸弹的唯一方法是将Room *转换为RoomWithABomb *这是不好的做法吗?

他们的例子是不是经过深思熟虑,还是有其他一些处理案例的方式?

1 个答案:

答案 0 :(得分:0)

这里的答案是你不需要知道它是什么样的房间。 假设Room是一个方法enter()的类,当你进入房间时,它可能打印出来。这个类看起来像这样(我会用Java做这个,因为我不熟悉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的衍生物,但它应该打印出类似“你爆炸”的东西。

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(因此也是每个RoomWithABomb,因为它继承自Room)具有enter()方法。

那么抽象工厂的意图是什么?我们想要创建类似的对象,从公共超类或接口继承的对象,以便其他对象不需要知道如何创建它们。通过这样做,我们还将其他对象与所述界面的具体实现分离(迷宫甚至不知道有一个炸弹的房间)。

相关问题