文档章节

工厂方法模式-创建型模式2

凯文加内特
 凯文加内特
发布于 2013/09/29 14:50
字数 1554
阅读 93
收藏 0

        工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

定义:
定义一个用于创建对象的接口,让子类决定实例化哪个类,Factory Method使一个类的实例化延迟到子类。

结构:

说明:
       Product接口:工厂方法创建的对象的接口。
       ConcreteProduct类,接口的具体实现。
       Creator类,创建器,声明个工厂方法,通常返回一个Product类型的实例对象。
       ConcreteCreator类,具体的创建器对象,覆盖实现Creator定义的工厂方法,返回具体的Product 实例。

具体代码

/**
 * 类说明: 创建产品对象的接口 
 * Time: 2013-9-27 下午4:52:49 
 * @author 凯文 加内特
 * Company: http://weibo.com/u/3165936675
 */
public interface Product {

}

/**
 * 类说明: 实现
 * Time: 2013-9-27 下午4:53:55 
 * @author 凯文 加内特
 * Company: http://weibo.com/u/3165936675
 */
public class ConcreteProduct implements Product {

}

/**
 * 类说明: 创建器
 * Time: 2013-9-27 下午4:54:37 
 * @author 凯文 加内特
 * Company: http://weibo.com/u/3165936675
 */
public abstract class Creator {

	protected abstract Product factoryMethod();

	public void someOperation() {
		Product p = factoryMethod();
	}
}

/**
 * 类说明: 具体的创建器对象
 * Time: 2013-9-27 下午4:56:16 
 * @author 凯文 加内特
 * Company: http://weibo.com/u/3165936675
 */
public class ConcreteCreator extends Creator {
	protected Product factoryMethod() {
		return new ConcreteProduct();
	}
}

模式应用代码:
 将数据导入到DB、txt文件中,代码如下:

/**
 * 类说明: 导出的文件对象的接口,相当结构中的Product * Time: 2013-10-8 下午5:34:33 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
public interface ExportFileApi {
	/**
	 * 导出内容成为文件
	 * @param data 示意:需要保存的数据
	 * @return 是否导出成功
	 */
	public boolean export(String data);

/**
 * 类说明: 导出成数据库备份文件形式的对象,相当结构中的ConcreteProduct
 * Time: 2013-10-8 下午5:34:19 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
public class ExportDB implements ExportFileApi {
	public boolean export(String data) {
		//简单示意一下,这里需要操作数据库和文件
		System.out.println("导出数据" + data + "到数据库备份文件");
		return true;
	}
}

/**
 * 类说明: 导出成文本文件格式的对象,相当结构中的ConcreteProduct
 * Time: 2013-10-8 下午5:35:42 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
public class ExportTxtFile implements ExportFileApi {
	public boolean export(String data) {
		//简单示意一下,这里需要操作文件
		System.out.println("导出数据" + data + "到文本文件");
		return true;
	}
}

/**
 * 类说明: 实现导出数据的业务功能对象,相当结构中的ConcreteCreator,此处没有用抽象类
 * Time: 2013-10-8 下午5:34:52 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
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;
	}
}

/**
 * 类说明: 客户端类
 * Time: 2013-10-8 下午5:34:02 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
public class Client {
	public static void main(String[] args) {
		//创建需要使用的Creator对象
		ExportOperate exportOperate = new ExportOperate();
		//调用输出数据的功能方法,传入选择到处类型的参数
		exportOperate.export(1, "测试数据");
	}
}

如果扩展一个导入到xml文件中的功能,则添加一个ExportOperate2类,继承ExportOperate类,并重写factoryMethod方法,再添加一个ExportXml类并实现导出接口ExportFileApi即可,原先代码不动,甚是方便,满足了开闭原则,示例代码如下:

/**
 * 类说明: 扩展ExportOperate对象,加入可以导出XML文件
 * Time: 2013-10-8 下午5:35:32 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
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;
	}
}


/**
 * 类说明: 导出成xml文件的对象
 * Time: 2013-10-8 下午5:35:51 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
public class ExportXml implements ExportFileApi {
	public boolean export(String data) {
		//简单示意一下
		System.out.println("导出数据" + data + "到XML文件");
		return true;
	}
}

/**
 * 类说明: 客户端类
 * Time: 2013-10-8 下午5:34:02 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */
public class Client {
	public static void main(String[] args) {
		//创建需要使用的Creator对象
		ExportOperate exportOperate2 = new ExportOperate2();
		//下面变换传入的参数来测试参数化工厂方法
		exportOperate2.export(1, "Test1");
		exportOperate2.export(2, "Test2");
		exportOperate2.export(3, "Test3");
	}
}


使用场景:
如果一个类需要创建一个接口的对象,但是又不知道具体的实现,这种情况下可以选择工厂方法模式。把创建对象的工作延迟到子类去实现。

优点和缺点
优点:
可以在不知道具体实现的情况下进行编程。
容易扩展, 当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了"开放-封闭"原则。而 简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。 
缺点:
具体产品对象与工厂方法的耦合性

留给自己的问题:
1.jdk、spring等开源源码中的示例

© 著作权归作者所有

凯文加内特
粉丝 341
博文 701
码字总数 110786
作品 0
青岛
后端工程师
私信 提问
java常见的几种设计模式

设计模式 1、概述 1)设计模式(Design pattern):是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结; 2)分类: 创建型模式(创建对象的): 单例模式、抽象工厂模式、建造者...

走了丶
2017/08/27
0
0
设计模式之五大创建型模式

一、概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 (2)结构型模式,共七种:适配器模式、装饰器模式、代理...

小城故事_
2016/03/19
70
0
设计模式-创建-singleton(单例)模式

单例模式是一种创建型的模式,适用于 全局只有一个对象的类, 结构图 只有一个静态 实例变量 和一个静态 函数 外部通过Instance() 静态函数来获取 唯一实例 存在的问题: 线程安全性 可用dou...

梦想游戏人
2016/04/28
55
0
PHP之设计模型分类(二)

创建型模式: 单例模式、工厂模式(简单工厂、工厂方法、抽象工厂)、创建者模式、原型模式。 1、单例模式 目的:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 应用场景:数据库...

peasant
2016/05/03
50
0
Java创建型模式的讨论

创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。 创建...

tequliapop
2016/01/13
125
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis Plus删除

/** @author beth @data 2019-10-17 00:30 */ @RunWith(SpringRunner.class) @SpringBootTest public class DeleteTest { @Autowired private UserInfoMapper userInfoMapper; /** 根据id删除......

一个yuanbeth
今天
4
0
总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
今天
5
0
java内存模型

前言 Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模...

ls_cherish
今天
4
0
友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部