Factory Method概述
玩具代码案例 - 文件编辑器
工厂方法抽象父类
Editor
package online.javabook.gof.creational.patterns3.factorymethod.editor.creator.api;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;import java.util.ArrayList;import java.util.List;public abstract class Editor { private String title; private Document current; private List<Document> documents = new ArrayList<>(); public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public void open(String file) { setTitle(file); current = createDocument(file); current.open(); current.display(); // multi-documents documents.add(current); } public void save() { current.save(); } public void close() { current.close(); } public void saveAll() { for (Document document : documents) { document.save(); } } public void closeAll() { for (Document document : documents) { document.close(); } } // Factory method protected abstract Document createDocument(String file);}
工厂方法具体子类
PdfEditor
package online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.api.Editor;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl.PdfDocument;public class PdfEditor extends Editor { protected Document createDocument(String file) { Document document = new PdfDocument(); document.setFile(file); return document; }}
PngEditor
package online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.api.Editor;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl.PngDocument;public class PngEditor extends Editor { protected Document createDocument(String file) { Document document = new PngDocument(); document.setFile(file); return document; }}
TxtEditor
package online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.api.Editor;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl.TxtDocument;public class TxtEditor extends Editor { protected Document createDocument(String file) { Document document = new TxtDocument(); document.setFile(file); return document; }}
产品接口
Document
package online.javabook.gof.creational.patterns3.factorymethod.editor.product.api;public abstract class Document { private String file; public String getFile() { return file; } public void setFile(String file) { this.file = file; } public abstract void open(); public abstract void display(); public abstract void save(); public abstract void close();}
具体产品
PdfDocument
package online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;public class PdfDocument extends Document { public PdfDocument(){ } @Override public void open() { System.out.println("打开Pdf文件" + this.getFile()); } @Override public void display() { System.out.println("显示Pdf文件" + this.getFile()); } @Override public void save() { System.out.println("存储Pdf文件" + this.getFile()); } @Override public void close() { System.out.println("关闭Pdf文件" + this.getFile()); }}
PngDocument
package online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;public class PngDocument extends Document { public PngDocument(){ } @Override public void open() { System.out.println("打开PNG文件" + this.getFile()); } @Override public void display() { System.out.println("显示PNG文件" + this.getFile()); } @Override public void save() { System.out.println("存储PNG文件" + this.getFile()); } @Override public void close() { System.out.println("关闭PNG文件" + this.getFile()); }}
TxtDocument
package online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl;import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;public class TxtDocument extends Document { public TxtDocument(){ } @Override public void open() { System.out.println("打开Txt文件" + this.getFile()); } @Override public void display() { System.out.println("显示Txt文件" + this.getFile()); } @Override public void save() { System.out.println("存储Txt文件" + this.getFile()); } @Override public void close() { System.out.println("关闭Txt文件" + this.getFile()); }}
基于工厂方法模式的实现 - 仅支持单一文件类型的工厂方法编辑器
SingleEditorMain
package online.javabook.gof.creational.patterns3.factorymethod.editor.app.good;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.api.Editor;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl.PdfEditor;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl.PngEditor;import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl.TxtEditor;public class SingleEditorMain { public static void main(String[] args) { // product String fileName = "*.txt"; // factory Editor editor = null; if (fileName.endsWith(".txt")) { editor = new TxtEditor(); } else if (fileName.endsWith(".pdf")) { editor = new PdfEditor(); }else if (fileName.endsWith(".png")) { editor = new PngEditor(); } // do business editor.open("file1.txt"); editor.open("file2.txt"); editor.open("file3.txt"); System.out.println("最后一次打开的文件:" +editor.getTitle()); editor.saveAll(); editor.closeAll(); }}
Console
打开Txt文件file1.txt显示Txt文件file1.txt打开Txt文件file2.txt显示Txt文件file2.txt打开Txt文件file3.txt显示Txt文件file3.txt最后一次打开的文件:file3.txt存储Txt文件file1.txt存储Txt文件file2.txt存储Txt文件file3.txt关闭Txt文件file1.txt关闭Txt文件file2.txt关闭Txt文件file3.txt
基于工厂方法模式的实现 - 支持类型注册与多种文件类型的工厂方法编辑器
MultiEditor
package online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl;
import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.api.Editor;
import online.javabook.gof.creational.patterns3.factorymethod.editor.product.api.Document;
import org.apache.commons.io.FilenameUtils;
import java.util.HashMap;
import java.util.Map;
public class MultiEditor extends Editor {
private Map<String, Class<? extends Document>> registers = new HashMap<>();
// register methods
public <T extends Class<? extends Document>> void registerDocumentClass(String extension, T documentClass) {
registers.put(extension, documentClass);
}
protected Class<? extends Document> getRegisteredDocumentClass(String extension) {
Class<? extends Document> documentClass = registers.get(extension);
return documentClass;
}
// Factory method
protected Document createDocument(String fileName) {
String extension = FilenameUtils.getExtension(fileName);
Class<? extends Document> documentClass = getRegisteredDocumentClass(extension);
Document document = null;
try {
document = documentClass.newInstance();
document.setFile(fileName);
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
}
MultiEditorMain
package online.javabook.gof.creational.patterns3.factorymethod.editor.app.good;
import online.javabook.gof.creational.patterns3.factorymethod.editor.creator.impl.MultiEditor;
import online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl.PdfDocument;
import online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl.PngDocument;
import online.javabook.gof.creational.patterns3.factorymethod.editor.product.impl.TxtDocument;
public class MultiEditorMain {
public static void main(String[] args) {
// factory
MultiEditor editor = new MultiEditor();
editor.registerDocumentClass("txt", TxtDocument.class);
editor.registerDocumentClass("pdf", PdfDocument.class);
editor.registerDocumentClass("png", PngDocument.class);
// do business
editor.open("file1.txt");
editor.open("file2.pdf");
editor.open("file3.png");
System.out.println("最后一次打开的文件:" +editor.getTitle());
editor.saveAll();
editor.closeAll();
}
}
Console
打开Txt文件file1.txt
显示Txt文件file1.txt
打开Pdf文件file2.pdf
显示Pdf文件file2.pdf
打开PNG文件file3.png
显示PNG文件file3.png
最后一次打开的文件:file3.png
存储Txt文件file1.txt
存储Pdf文件file2.pdf
存储PNG文件file3.png
关闭Txt文件file1.txt
关闭Pdf文件file2.pdf
关闭PNG文件file3.png