2017-02-15 14 views
0

デザインパターンブックのAbstract Factoryパターンサンプルコードに関する質問があります。デザインパターン - 抽象ファクトリ - BombedMazeFactory

この本は、部屋を接続する壁と扉がある迷路ゲームの簡略化された部分的な例を示しています。

次のファクトリメソッドを持っている基本的なMazeFactoryクラスがあります:私は正確にどのように知りません

class BombedMazeFactory : public MazeFactory { 
    BombedMazeFactory(); 

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

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の特殊化を定義する著者(複数可) RoomWithABombは動作するはずですが、爆弾が入っている可能性が5%の部屋を作成し、爆発した爆弾部屋を含む扉を開けると言うことができます。

ここで、クライアントがBombedMazeFactoryクラスを使用して迷路を作成し、いくつかの部屋を作成するとします。作成されたルームはRoomWithABomb *タイプですが、ファクトリはRoom *を返します。

いくつかの迷路のゲームロジックを実装するには、部屋に爆弾が含まれているかどうかを確認する必要があると思いますが、Room *は爆弾に関する知識がありません。部屋に爆弾が含まれているかどうかを調べる唯一の方法はRoom *を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の派生ですが、代わりに "あなたが爆発した"のようなものを印刷する必要があります。

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

私はこの答えに満足しています。私はenter()がゲームの状態を変更するためにMazeGameのインスタンスを必要とすると思います。これはカップリングを増やしますが、良い選択肢はありません。 – mrpringle

関連する問題