定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method 使一个类的实例化延迟到其子类。
结构类图下:
Product:实际需要使用的对象的接口。
Concrete Product:具体Product接口的实现对象。
Creator:创建器,声明工厂方法;
ConcreteCreator:具体的创建器对象,覆盖实现Creator实现的定义的工厂方法,返回具体的Product实例。
应用场景示例:比如业务场景,需要我们实现将一些数据输出,输出的格式可以使xml或者txt等格式。
文件输出接口:
/**
* 导出数据的接口
* @author w_zhanggs
*
*/
public interface ExportFile {
boolean export(String data);
}
xml实现:
public class ExportFileXml implements ExportFile {
@Override
public boolean export(String data) {
if(data == null) return false;
System.out.println("将数据"+data+"导出为xml格式");
return true;
}
}
txt实现:
public class ExportFileTxt implements ExportFile {
@Override
public boolean export(String data) {
if(data == null) return false;
System.out.println("将数据"+data+"导出为txt格式");
return true;
}
}
实际使用ExportFile 接口的类(不适用工厂模式):
public class ExportFileOperate {
/**
* 实现导出数据
*
* @param data
* @return
*/
public boolean exporFile(String data,int type) {
// 比如进行数据导出前进行数据的检验,转换等。
System.out.println("进行数据校验");
System.out.println("进行数据转换");
//此时还不知道将数据导出的格式,具体的实现由子类来实现
ExportFile exportFile = null;
if(type == 0) {
exportFile = new ExportFileTxt();
}else {
exportFile = new ExportFileXml();
}
return exportFile.export(data);
}
}
客户端:
public class Client {
public static void main(String[] args) {
ExportFileOperate exportFileOperate = new ExportFileOperate();
exportFileOperate.exporFile("yyyyy", 0);
}
}
如上不适用模式存在的问题是:
1.客户端需要使用传一个type的参数,决定数据的导出方式,无法控制客户端的传参行为
2.如果新增导出dmp文件的形式,需要修改ExportFileOperate 的exporFile方法,违反了开闭原则。
3.exporFile方法的职责不明确,该方法应专注于业务逻辑的实现,不应该花费力气去创建对象。
使用工厂模式改造以上的类,ExportFileOperate 改为抽象类,并增加一个factoryMethod的抽象方法。
public abstract class ExportFileOperate {
/**
* 实现导出数据
*
* @param data
* @return
*/
public boolean exporFile(String data,int type) {
// 比如进行数据导出前进行数据的检验,转换等。
System.out.println("进行数据校验");
System.out.println("进行数据转换");
//此时还不知道将数据导出的格式,具体的实现由子类来实现
ExportFile exportFile = factoryMethod();
return exportFile.export(data);
}
/**
* 创建工厂的方法
* @return
*/
public abstract ExportFile factoryMethod();
}
新增ExportFileOperate 抽象类的具体实现类:ExportFileXmlOperate 和ExportFileTxtOperate
public class ExportFileXmlOperate extends ExportFileOperate {
@Override
public ExportFile factoryMethod() {
// TODO Auto-generated method stub
return new ExportFileXml();
}
}
public class ExportFileTxtOperate extends ExportFileOperate {
@Override
public ExportFile factoryMethod() {
// TODO Auto-generated method stub
return new ExportFileTxt();
}
}
经过工厂模式的改造后的client端如下:
public class Client {
public static void main(String[] args) {
ExportFileOperate exportFileOperate = new ExportFileTxtOperate();
exportFileOperate.exporFile("yyyyy", 0);
}
}
工厂模式的本质:延迟实现到子类。
优缺点:
1.实现面向抽象编程,更容易扩展
2.工厂方法和具体对象有耦合