Factory 方法模式是類的建立模式,又叫虛擬構造子模式或者多態性原廠模式。Factory 方法模式的用意是定義一個建立產品對象的工廠介面,將實際建立工作延遲到子類中。
ξ 13.1 引言
在一個系統中,如果產品角色是具有等級結構的,即由一個或多個抽象角色和多個具體角色構成樹裝結構。這個時候通常會按照產品的等級結構設計一個同結構的工廠等級結構,然後由相應的工廠角色建立相應的產品角色,如所示:
中左側為工廠角色結構,右側為產品角色結構。其中深藍色為抽象角色,灰色為具體角色。可以看出,對於每一種具體產品,都有一種對應的具體工廠來建立。 圖中藍色箭頭為繼承關係,黑色箭頭為建立關係。
ξ 13.2 Factory 方法模式的結構
為Factory 方法的示意性UML圖,從圖上可以看出,原廠模式涉及到四種角色:
① 抽象工廠角色:當然這個角色的是Factory 方法模式的核心,它是與應用程式無關的。任何在模式中建立對象的工廠類必須實現這個介面。在上面的系統中,這個角色由java介面Creator扮演;在實際的系統中,這個角色也常常使用抽象java類實現;
② 具體工廠角色:擔任這個角色的是實現了抽象工廠介面的具體java類。具體工廠角色含有與應用密切相關的邏輯,並且受到應用程式的調用以建立產品對象;
③ 抽象產品角色:Factory 方法模式所建立的對象的基類,也就是產品對象的共同基類或者共同擁有的介面。在系統中,這個角色由java介面或者抽象類別實現;
④ 具體產品角色:這個角色實現了抽象產品角色所聲明的介面。Factory 方法模式所建立的每一個對象都是某個具體產品角色的執行個體。
ξ 13.3 Factory 方法在農場系統中的實現
在這次的執行個體裡面,園丁不再是一個全能的類,取代他的是一個抽象的園丁角色(抽象工廠角色),而針對不同的產品,通常會有對應的具體工廠角色,具體類圖如下:
具體代碼:
// 抽象工廠角色
public interface FruitGardener
...{
public Fruit factory() ;
}
// 具體工廠角色
public class AppleGardener implements FruitGardener
...{
public Fruit factory()
...{
return new Apple() ;
}
}
public class StrawberryGardener implements FruitGardener
...{
public Fruit factory()
...{
return new Strawberry() ;
}
}
public class GrapeGardener implements FruitGardener
...{
public Fruit factory()
...{
return new Grape() ;
}
}
// 抽象產品角色
public interface Fruit
...{
public void grow();
public void harvest();
public void plant();
}
// 具體產品角色
public class Apple implements Fruit
...{
public void grow()
...{
System.out.println( "Apple:grow" ) ;
}
public void harvest()
...{
System.out.println( "Apple:havest" ) ;
}
public void plant()
...{
System.out.println( "Apple:plant" ) ;
}
private int treeAge ;
public int getTreeAge()
...{
return this.treeAge ;
}
public void setTreeAge( int treeAge )
...{
this.treeAge = treeAge ;
}
}
public class Strawberry implements Fruit
...{
public void grow()
...{
System.out.println( "Strawberry:grow" ) ;
}
public void harvest()
...{
System.out.println( "Strawberry:havest" ) ;
}
public void plant()
...{
System.out.println( "Strawberry:plant" ) ;
}
}
public class Grape implements Fruit
...{
private boolean seedless;
public void grow()
...{
System.out.println( "Grape:grow" ) ;
}
public void harvest()
...{
System.out.println( "Grape:havest" ) ;
}
public void plant()
...{
System.out.println( "Grape:plant" ) ;
}
public boolean getSeedless()
...{
return seedless ;
}
public void setSeedless(boolean seedless)
...{
this.seedless = seedless ;
}
}
ξ 13.5 Java語言中Factory 方法的例子
第一個例子有些錯誤,不寫了。
第二個例子是URL和URLConnection的例子:URL本身是一個工廠,它的Factory 方法OpenConnection()返回一個抽象的URLConnection類,根據不同的URL,URLConnection的執行個體也將不同。
ξ 13.6Factory 方法與其他模式的關係
參考模板方法、MVC、享元模式和備忘錄模式。