工厂方法模式(Factory Method)
2016-07-09 12:03
330 查看
1. 模式定义
问题描述:通常在导出数据上会有一些约定的格式,比如导出成文本格式,数据库备份形式,Excel格式,Xml格式。
对于实现数据导出的业务功能对象,它需要创建ExportFileApi的具体实现对象,但是它知道ExportFileApi接口,而不知道其具体的实现,那该怎么办?
工厂方法模式的定义:
定义一个用于创建对象的接口,让子类决定去实例化哪一个类,Factory Method使一个类的实现化延迟到其子类。
2. UML图
Product:定义工厂方法所创建的对象的接口,也就是实现需要使用的对象的接口
ConcreteProduct:Product的实现对象
Creator:声明工厂方法,工厂方法通常会返回一个Product类的实例对象,而且多是抽象方法
ConcreteCreator:覆盖实现Creator定义的工厂方法,返回具体的Product实例
具体代码:
/** * 导出的文件对象的接口 */ public interface ExportFileApi { /** * 导出内容成为文件 * @param data 示意:需要保存的数据 * @return 是否导出成功 */ public boolean export(String data); } /** * 导出成数据库备份文件形式的对象 */ public class ExportDB implements ExportFileApi{ public boolean export(String data) { //简单示意一下,这里需要操作数据库和文件 System.out.println("导出数据"+data+"到数据库备份文件"); return true; } } /** * 导出成文本文件格式的对象 */ public class ExportTxtFile implements ExportFileApi{ public boolean export(String data) { //简单示意一下,这里需要操作文件 System.out.println("导出数据"+data+"到文本文件"); return true; } } /** * 实现导出数据的业务功能对象 */ public abstract class ExportOperate { /** * 导出文件 * @param data 需要保存的数据 * @return 是否成功导出文件 */ public boolean export(String data){ //使用工厂方法 ExportFileApi api = factoryMethod(); return api.export(data); } /** * 工厂方法,创建导出的文件对象的接口对象 * @return 导出的文件对象的接口对象 */ 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) { //创建需要使用的Creator对象 ExportOperate operate = new ExportDBOperate(); //调用输出数据的功能方法 operate.export("测试数据"); } }
3.研磨设计模式
工厂方法模式的功能主要是父类在不知道具体实现的情况下,完成自身的功能调用,而具体的实现让子类去做。工厂方法的本质:延迟到子类去选择实现,有更好的维护性和可扩展性
一般不会把工厂方法暴露给客户端
IOC和DI
IOC Inversion Of Control 控制反转
DI Dependency Injection 依赖注入
依赖注入和控制反转是同一件事情的不同描述
依赖注入:从应用程序的角度描述,应用程序依赖容器创建并注入它所需要的外部资源;
控制反转:从容器的角度描述,容器控制应用程序,由容器反向地向程序注入其所需要的外部资源。
1. 参与者有谁:一个是某个Java对象,另一个是IOC/DI的容器,还有一个是某个对象的外部资源
2. 谁依赖于谁:某个Java对象依赖于IOC/DI的容器
3. 为什么需要依赖:对象需要IOC/DI容器来提供对象需要的外部资源
4. 谁注入谁:IOC/DI容器注入某个外部资源
5. 到底注入什么:注入某个对象所需的外部资源
6. 谁控制谁:IOC/DI的容器控制对象
7. 控制什么:控制对象实例的创建
参数化工厂方法值的是:通过给工厂方法传递参数,让工厂方法根据参数的不同创建不同的产品对象。
/** * 实现导出数据的业务功能对象 */ public class ExportOperate { /** * 导出文件 * @param type 用户选择的导出类型 * @param data 需要保存的数据 * @return 是否成功导出文件 */ public boolean export(int type,String data){ //使用工厂方法 ExportFileApi api = factoryMethod(type); return api.export(data); } /** * 工厂方法,创建导出的文件对象的接口对象 * @param type 用户选择的导出类型 * @return 导出的文件对象的接口对象 */ protected ExportFileApi factoryMethod(int type){ ExportFileApi api = null; //根据类型来选择究竟要创建哪一种导出文件对象 if(type==1){ api = new ExportTxtFile(); }else if(type==2){ api = new ExportDB(); } return api; } } public class Client { public static void main(String[] args) { // //创建需要使用的Creator对象 // ExportOperate operate = new ExportOperate(); // //调用输出数据的功能方法,传入选择到处类型的参数 // operate.export(1,"测试数据"); //创建需要使用的Creator对象 ExportOperate operate = new ExportOperate2(); //下面变换传入的参数来测试参数化工厂方法 operate.export(1,"Test1"); operate.export(2,"Test2"); operate.export(3,"Test3"); } } //扩展非常容易 /** * 扩展ExportOperate对象,加入可以导出XML文件 */ public class ExportOperate2 extends ExportOperate{ /** * 覆盖父类的工厂方法,创建导出的文件对象的接口对象 * @param type 用户选择的导出类型 * @return 导出的文件对象的接口对象 */ protected ExportFileApi factoryMethod(int type){ ExportFileApi api = null; //可以全部覆盖,也可以选择自己感兴趣的覆盖, //这里只想添加自己新的实现,其他的不管 if(type==3){ api = new ExportXml(); }else{ //其他的还是让父类来实现 api = super.factoryMethod(type); } return api; } }
相关文章推荐
- 菜鸟感言
- 视频质量评价方法
- 303. Range Sum Query - Immutable
- DOM解析XML浅析
- windows server2012部署Cognos问题小结
- Java是如何管理内存的?
- Git学习笔记
- 进程同步
- 第八章 Gleaming the Cube
- asp.net中GridView编辑,更新,合计用法示例
- Linux命令(003) -- crontab
- 【NOIP2010提高组】关押罪犯
- Mybatis绑定错误的原因及其解决整理
- js 中 == 和 ===的区别
- 2016sdau课程练习专题三 1010
- spring 概述
- C++常量折叠
- openmp并行计算
- scala数据库工具类
- AIDL使用(一)