设计模式 之 工厂方法模式解析
1、工厂方法模式的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到其子类。
2、案例分析
Product: 定义工厂方法所创建的对象的接口,也就是实际需要使用的对象的接口。
ConcreteProduct:具体的Product接口的实现对象。
Creator:创建器,声明工厂方法,工厂方法通常会返回一个Product类型的实例对象,且多是抽象方法。也可在Creator里面提供工厂方法的默认实现,让工厂方法返回一个缺省的Product类型的实例对象。
ConcreteCreator:具体的创建器对象,覆盖实现Creator定义的工厂方法,返回具体的Product实例。
(1)需求:实现一个导出数据的应用框架,来让客户选择数据的导出方式,并真正执行数据导出,导出数据成:文本格式、数据库备份形式、Excel格 式、Xml格式等等
Product:导出的文件对象接口ExportFileApi
Creator:导出数 据的业务功能对象
//导出的文件对象接口ExportFileApi
public interface ExportFileApi {
//可以定义Product的属性和方法
public boolean export(String data);
}
//为了简化,只实现导出文本文件格式和数据库备份文件两种
//导出成文本文件格式的对象
public class ExportTxtFile implements ExportFileApi{
public boolean export(String data) {
//简单示意一下,这里需要操作文件
System.out.println("导出数据"+data+"到文本文件");
return true;
}
}
// 导出成数据库备份文件形式的对象
public class ExportDB implements ExportFileApi{
public boolean export(String data) {
//简单示意一下,这里需要操作数据库和文件
System.out.println("导出数据"+data+"到数据库备份文件");
return true;
}
}
// 实现导出数据的业务功能对象
public abstract class ExportOperate {
public boolean export(String data){
//使用工厂方法
ExportFileApi api = factoryMethod();
return api.export(data);
}
//工厂方法,创建导出的文件对象的接口对象
protected abstract ExportFileApi factoryMethod();
}
public class ExportTxtFileOperate extends ExportOperate{
protected ExportFileApi factoryMethod() {
//创建导出成文本文件格式的对象
return new ExportTxtFile();
}
}
public class ExportDBOperate extends ExportOperate{
protected ExportFileApi factoryMethod() {
//创建导出成数据库备份文件形式的对象
return new ExportDB();
}
}
//客户端
public class Client {
public static void main(String[] args) {
//创建需要使用的Creator对象
ExportOperate operate = new ExportDBOperate();
//调用输出数据的功能方法
operate.export("测试数据");
}
}
(2)功能:让父类在不知道具体实现的情况下,完成自身功能调用,而具体的实现延迟到子类来实现。
(3)特征
工厂方法的实现中,通常父类(Creator)会是一个抽象类,里面包含创建所需对象的抽象方法,这些抽象方法就是工厂方法。
子类在实现这些抽象方法的时候,通常并不是真的由子类来实现具体的功能,而是在子类的方法里面做选择,选择具体的产品实现对象。
父类(Creator)中通常有实现公共功能的方法,不管子类选择了何种具体的产品实现,这些方法的功能总是能正确执行。
(4)使用
工厂方法的实现中,可能需要参数,以便决定到底选用哪一种具体的实现。也就是说通过在抽象方法里面传递参数,在子类实现的时候根据参数进行选择,看看究竟应该创建哪一个具体的实现对象。
工厂方法一般不提供给Creator外部使用,如上例中的 factoryMethod 方法
3、扩展
(1)依赖注入和控制反转是同一概念吗?
答:依赖注入和控制反转是对同一件事情的不同描述,依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
(2)IOC/DI的作用?
答:有效的分离了对象和它所需要的外部资源,使得他们松散耦合,有利于功能复用 (3)工厂方法模式和IoC/DI有什么关系呢?
答:工厂方法模式和 IoC/DI 的思想是相似的,都是“主动变被动”,进行了“主从换位”,从而获得了更灵活的程序结构。
(4)工厂方法和简单工厂的区别
答:工厂方法模式的本质是延迟到子类选择实现,工厂类中使用工厂方法的地方是依赖于抽象而不是具体的实现;简单工厂模式是直接在工厂类里进行“选择实现”,从某个角度来看的话,可以认为简单工厂就是工厂方法模式的一种特例。
(5)工厂方法模式体现了什么设计原则?
答:工厂方法模式很好的体现了“依赖倒置原则”,依赖倒置原则告诉我们“要依赖抽象,不要依赖于具体类”,简单点说就是:不能让高层组件依赖于低层组件,而且不管高层组件还是低层组件,都应该依赖于抽象。
4、何时选用工厂方法模式
建议在如下情况中,选用工厂方法模式:
如果一个类需要创建某个接口的对象,但是又不知道具体的实现,这种情况可以选用工厂方法模式,把 创建对象的工作延迟到子类去实现
如果一个类本身就希望由它的子类来创建所需的对象的时候,应使用工厂方法模式
尾注
- 上述的总结与思考是基于对《研磨设计模式》这本书的精读与演绎
-
更多及时干货,请关注微信公众号:JAVA万维猿圈