抽象工廠(Abstract factories)

抽象工廠(abstract factory)模式看起來很像前面我們看到的那些factory對象,只不過它有多個而不是一個factory方法。每一個factory 方法創建一個不同類型的對象。基本思想是:在創建工廠對象的地方,由你來決定如何使用該工廠對象創建的那些對象。《設計模式》裏給出的例子實現了在不同用 戶圖形界面(GUIs)之間的可移植性:你根據自己使用的GUI來創建一個與之對應的factory對象,在這以後,當你需要用到菜單,按鈕,滾動條這些 東西的時候,它會根據你使用的GUI自動創建合適的對象。這樣,你就可以把實現不同GUI之間切換的代碼分離出來,使它集中在一個地方。
作爲另外一個例子,假設你要創建一個通用的遊戲環境,而且你還想要支持不同類型的遊戲。下面的例子用抽象工廠給出了它的一種可能的實現。
//: factory:Games.java


// An example of the Abstract Factory pattern.
package factory;
import junit.framework.*;
interface Obstacle {
void action();
}
interface Player {
void interactWith(Obstacle o);
}
class Kitty implements Player {
public void interactWith(Obstacle ob) {
System.out.print("Kitty has encountered a ");
ob.action();
}
}
class KungFuGuy implements Player {
public void interactWith(Obstacle ob) {
System.out.print("KungFuGuy now battles a ");
ob.action();
}
}
class Puzzle implements Obstacle {
public void action() {System.out.println("Puzzle");
}
}
class NastyWeapon implements Obstacle {
public void action() {
System.out.println("NastyWeapon");
}
}
// The Abstract Factory:
interface GameElementFactory {
Player makePlayer();
Obstacle makeObstacle();
}
// Concrete factories:
class KittiesAndPuzzles implements GameElementFactory {
public Player makePlayer() {
return new Kitty();
}
public Obstacle makeObstacle() {
return new Puzzle();
}
}
class KillAndDismember implements GameElementFactory {
public Player makePlayer() {
return new KungFuGuy();
}
public Obstacle makeObstacle() {
return new NastyWeapon();
}
}
class GameEnvironment {
private GameElementFactory gef;
private Player p;
private Obstacle ob;
public GameEnvironment( GameElementFactory factory) {
gef = factory;
p = factory.makePlayer();
ob = factory.makeObstacle();
}
public void play() { p.interactWith(ob); }
}
public class Games extends TestCase {
GameElementFactory
kp = new KittiesAndPuzzles(),
kd = new KillAndDismember();
GameEnvironment
g1 = new GameEnvironment(kp),
g2 = new GameEnvironment(kd);
// These just ensure no exceptions are thrown:
public void test1() { g1.play(); }
public void test2() { g2.play(); }
public static void main(String args[]) {
junit.textui.TestRunner.run(Games.class);
}
}
在 上面的遊戲環境裏,Player對象與Obstale對象交互,根據你所選擇的遊戲類型,player和obstacle的各自類型也會不同。你通過選擇 某個特定的GameElementFactory來決定遊戲的類型,然後GameElementFactory會控制初始化和遊戲的進行。在上面的例子 裏,初始化和遊戲的進行都非常簡單,但那些活動(初始條件和狀態變化)可以在很大程度上決定遊戲的結局。這裏,GameEnvironment不是用來給 其它類繼承的 ,儘管那麼做很可能也說的通。
上面的代碼也包含了雙重分派(Double Dispatching)和工廠方法(Factory Method)兩種模式,
發佈了103 篇原創文章 · 獲贊 17 · 訪問量 48萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章