2017-02-15 137 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); 
    } 
} 

作者(S),然后定义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 *,但工厂返回一个房间*。

为了实现一些迷宫游戏逻辑,我假设你需要检查一个房间是否包含炸弹,但是房间*没有关于炸弹的知识。我们能够找出房间是否含有炸弹的唯一方法是将房间*改为RoomWithABomb *这是不正确的做法吗?

他们的例子不是很好的想法或者是否有其他方式来处理这种情况?

+0

如果每个房间都有一个Enter()方法,则可以在RoomWithABomb子类中覆盖此方法,并具有随机设置炸弹的逻辑。 – dbugger

回答

0

这里的答案是你不需要知道它是什么样的房间。 比方说Room是一种方法enter(),当你进入房间时,它可能会打印出一些东西。这个类看起来是这样的(因为我没那么熟悉C++,我会做到这一点在Java中,但你的想法):

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

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

+0

我很满意这个答案。我想enter()需要一个MazeGame实例来改变游戏的状态,这会增加耦合,但我看不到一个好的选择。 – mrpringle