目的
以同一個介面建立一整族相關的物件,不需點明各物件真正所屬的實體類別。
Create families of related objects without specifying subclass names
適用
- 使用者無法預測要實例化的Class時。
- 系統必須與最終Product的生成、組合、表達方式保持獨立。
- 能讓各陣營的Product和系統互相搭配時使用,並且需要強制約束這件事。
- 一整族相關物件由相同Factory生成,確保不會搭配錯誤。
- 你把類別函式庫貢獻出來,但只想公開介面,不想公開實作細節。
結構及成員
Collaborations: 在執行期,ConcreteFactory只有單獨一個,如果想生成其他陣營的,就要換另一種ConcreteFactory。AbstractFactory將製造Product的責任交付給子類別ConcreteFactory處理。
影響結果
好處
壞處
實作
將Factory做成Singleton
正常情況下,應用程式只需對一族(陣營)的Product配一個ConcreteFactory,因此最好做成Singleton Pattern。
產生成品物件
- AbstractFactory只含製造Product的介面而已,實作是由各ConcreteFactory子類別負責。常見做法是一種Product定義一種Method,然後ConcreteFactory可以Override各自的Method。
- 如果會有好幾族成品物件同時並存,可以採用Prototype Pattern來製作ConcreteFactory。(先將各族系各成品弄一個Prototype物件給ConcreteFactory,以複製Prototype的方式製作新成品)
定義可延伸的Factory
AbstractFactory通常會替每種可能產生的物件定義方法,若想增加新Product類型,就得修改有牽連的類別,因此可使用Make搭配參數來決定該建造哪種Product。
Example: Parser
//Abstra: AbstractParserFactory
public interface AbstractParserFactory {
public XMLParser getParserInstance(String parserType);
}
//Class: Interface XMLParser
public interface XMLParser {
public String parse();
}
//Class: ParserFactoryProducer
public final class ParserFactoryProducer {
private ParserFactoryProducer(){
throw new AssertionError();
}
public static AbstractParserFactory getFactory(String factoryType){
switch(factoryType)
{
case "NYFactory": return new NYParserFactory();
case "TWFactory": return new TWParserFactory();
}
return null;
}
}
//Class: NYParserFactory
public class NYParserFactory implements AbstractParserFactory {
@Override
public XMLParser getParserInstance(String parserType) {
switch(parserType){
case "NYERROR": return new NYErrorXMLParser();
case "NYFEEDBACK": return new NYFeedbackXMLParser();
case "NYORDER": return new NYOrderXMLParser();
case "NYRESPONSE": return new NYResponseXMLParser();
}
return null;
}
}
//Class: NYErrorXMLParser
public class NYErrorXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing error XML...");
return "NY Error XML Message";
}
}
//Class: NYFeedbackXMLParser
public class NYFeedbackXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing feedback XML...");
return "NY Feedback XML Message";
}
}
//Class: NYOrderXMLParser
public class NYOrderXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing order XML...");
return "NY Order XML Message";
}
}
//Class: NYResponseParser
public class NYResponseXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing response XML...");
return "NY Response XML Message";
}
}
//Class: TWParserFactory
public class TWParserFactory implements AbstractParserFactory {
@Override
public XMLParser getParserInstance(String parserType) {
switch(parserType){
case "TWERROR": return new TWErrorXMLParser();
case "TWFEEDBACK": return new TWFeedbackXMLParser();
case "TWORDER": return new TWOrderXMLParser();
case "TWRESPONSE": return new TWResponseXMLParser();
}
return null;
}
}
//Class: TWErrorXMLParser
public class TWErrorXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing error XML...");
return "TW Error XML Message";
}
}
//Class: TWFeedbackXMLParser
public class TWFeedbackXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing feedback XML...");
return "TW Feedback XML Message";
}
}
//Class: TWOrderXMLParser
public class TWOrderXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing order XML...");
return "TW Order XML Message";
}
}
//Class: TWResponseXMLParser
public class TWResponseXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing response XML...");
return "TW Response XML Message";
}
}
//Class: TestAbstractFactoryPattern
public class TestAbstractFactoryPattern {
public static void main(String[] args) {
AbstractParserFactory parserFactory = ParserFactoryProducer.getFactory("NYFactory");
XMLParser parser = parserFactory.getParserInstance("NYORDER");
String msg="";
msg = parser.parse();
System.out.println(msg);
System.out.println("************************************");
parserFactory = ParserFactoryProducer.getFactory("TWFactory");
parser = parserFactory.getParserInstance("TWFEEDBACK");
msg = parser.parse();
System.out.println(msg);
}
}
Result:
NY Parsing order XML...
NY Order XML Message
************************************
TW Parsing feedback XML...
TW Feedback XML Message