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