定义
定义一个用于创建对象的接口,让子类决定实例化哪个一类,FactoryMethod使得一个类的实例化延迟到子类。
结构和说明
Product:定义工厂方法所创建的对象接口,也就是实际需要使用的对象接口。
ConcreteProduct:具体的Product接口实现对象。
Creator 创建器,声明工厂方法。
ConcreteCreator 具体创建器对象,覆盖Creator定义工厂方法返回具体的Product实例。
public abstract class Creator{
//创建Product 的工厂方法
protected abstract Product factoryMethod();
public void someOperate(){
Product product = factoryMethod();
//do something..
}
}
public interface Product{
//method createProduct
}
public class ConcreteCreator extends Creator{
public Product factoryMethod(){
return new ConcreteProduct();
}
}
public class ConcreteProduct implements{
//concrete generateProduct
}
应用1:导出数据的应用框架
考虑这样一个实际应用:实现一个导出数据的应用框架,
来让客户选择数据的导出方式,并真正的执行导出数据。导出数据上有一些约定的方式 ,文本,数据库备份 ,excel,xml等。
public interface ExportFileApi{
public boolean export(String data);
}
public class ExportDB implements ExportFileApi{
public boolean export(String data){
System.out.println("导出data:"+data+"导出数据库备份");
return true;
}
}
public class ExportTxtFile implements ExportFileApi{
public boolean export(String data){
System.out.println("导出data:"+data+"导出txt文件");
return true;
}
}
public abstract class ExportOperate{
public boolean export(String data){
//数据校验
//数据转化
//数据格式封装
ExportFileApi api = factoryMethod();
api.export(data);
}
protected abstract ExportFileApi factoryMethod();
}
public class ExportDBOperate extends ExportOperate{
protected ExportFileApi factoryMethod(){
return new ExportDB();
}
}
public class ExportTxtFileOperate extends ExportOperate{
protected ExportFileApi factoryMethod(){
return new ExportTxtFile();
}
}
public class client{
public static void main(String[]args){
String data = "data"
ExportOperate operate = new ExportTxtFileOperate();
operate.export(data);
}
}
理解工厂方法模式
1.工厂方法模式的功能
工厂方法的主要功能是让父类在不知具体的实现情况下,完成自身的功能调用,而具体的实现延迟到子类实现。
2.实现成抽象类
工厂方法的实现中,通常父类会是一个抽象类,里面包含创建所需对象的抽象方法,这些抽象方法就是工厂方法。
3. 实现成具体的类
也可以把父类实现成一个具体的类,这种情况下,通常是通常是在父类中提供获取所需对象的默认实现方法,这样就算没有具体子类,也可以运行。
4.工厂方法的参数和返回值
5.谁来使用工厂方法创建对象
在工厂方法中,应该是Creator中的其他方法在使用工厂方法;客户端应该使用creator对象,或者是使用由creator创建的对象,这个时候工厂方法创建的对象是Creator方法中中使用;客户端可能会使用由Creator创建出来的对象,这个时候工厂方法创建的对象,是构成客户端需要对象的一部分。在工厂方法模式里面,客户端要么使用creator对象,要么使用creator创建的对象,一般客户端不直接使用工厂方法,当然也可以直接把工厂方法暴露给客户端,但一般不这么做。
时序图
1.客户端使用Creator创建的对象时序图
2.客户端使用Creator对象时序图
工厂方法模式与IoC/DI
思想 "主从换位" 应用程序原本是老大,要获取什么资源都主动获取,但在IOC/DI思想中,应用程序被动了,被动的等待IOC、DI容器来创建并注入它所依赖的资源。有效的分离对象和它所需的外部资源使得他们松散耦合,有利于功能复用,系统体系结构变得灵活。
工厂方法模式和IOC/DI的关系,他们思想类似,都是主动变被动进行“主从换位”从而更加灵活。
平行的类层次结构
1.什么是平行类层次结构?
假如有两个类层次结构,其中一个类层次中的每个类在另一个层次中都有一个对应的类的结构。
2.平行类层级结构作用
主要用来把一个类层次中的某些行为分离出来,让类层次中的类把原本的属于自己的职责,委托分离出来的类去实现,从而使得类层次本省变得更加简单,更加容易扩展。
3.工厂方法模式跟平行类层次结构关系
可以用使用工厂方法模式来连接平行的类层次。
参数化工厂方法
//参数化工厂方法一般不使用抽象类
public class ExportOperate{
public boolean export(int type,String data){
ExportFileApi api = factoryMethod(type);
return api.export(data);
}
protected ExportFileApi factoryMethod(int type){
ExportFileApi api = null;
if (type ==1){
api = new ExportTxtFile();
}else if(type ==2){
api = new ExportDB();
}
}
}
//如果添加新的方式导出数据xml形式,该如何扩展?一种直接else if 判断,一种继承ExportOperate对象扩展。
public class ExportOperate2 extends ExportOperate{
//覆盖父类工厂方法创建导出文件对象的接口对象
protected ExportFileApi factoryMethod(int type){
ExportFileApi api = null;
//添加新的实现
if (type==3){
api = new ExportXml();
} else{
api = super.factoryMethod(type);
}
}
}
工厂方法模式的优缺点
1.可以在不知具体实现的情况下编程
2.更容易扩展对象的新版本
3.连接平行的类层次
4.具体产品对象和工厂方法的耦合性
工厂方法模式本质
**延迟到子类来选择实现**
工厂方法模式很好的体现依赖倒置的原则,依赖抽象,不要依赖于具体类。不能让高层组件依赖低层组件,而且不管高层组件还是低层组件都依赖于抽象。
使用场景
如果一个类需要创建某个接口的对象,但又不知道具体实现,这种情况可以选用工厂方法模式,把创建对象的工作延迟到子类去实现。
如果一个类本身就希望,由他的子类来创建所需要的对象可以使用工厂方法模式。