我只是记录一下,方便自己以后查找.希望这些链接对大家有用.
这三个模式都是创造型模式,这三种模式区分我觉得讲的很好的一个例子是:http://blog.csdn.net/wyxhd2008/article/details/5597975
一定要先看看上面的链接,我觉得讲的很形象.
简单工厂模式:http://blog.csdn.net/hudashi/article/details/7632405
示例1:
Fruit.java文件
public
interface
Fruit
{
/*
* 采集
*/
public
void
get
();
}
Apple.java文件
public
class
Apple
implements
Fruit
{
/*
* 采集
*/
public
void
get
(){
System
.
out
.
println
(
"采集苹果"
);
}
}
Banana.java文件
public
class
Banana
implements
Fruit
{
/*
* 采集
*/
public
void
get
(){
System
.
out
.
println
(
"采集香蕉"
);
}
}
FruitFactory.java文件
public
class
FruitFactory
{
/*
* 获得Apple类的实例
*/
public static Fruit getApple() {
return new Apple();
}
/*
* 获得Banana类实例
*/
public static Fruit getBanana() {
return new Banana();
}
/*
* get方法,获得所有产品对象
*/
public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if(type.equalsIgnoreCase("apple")) {
return Apple.class.newInstance();
} else if(type.equalsIgnoreCase("banana")) {
return Banana.class.newInstance();
} else {
System.out.println("找不到相应的实例化类");
return null;
}
Class fruit = Class.forName(type);
return (Fruit) fruit.newInstance();
}
}
MainClass.java文件
public
class
MainClass
{
public
static
void
main
(
String
[]
args
)
throws
InstantiationException
,
IllegalAccessException
,
ClassNotFoundException
{
//实例化一个Apple
Apple apple = new Apple();
//实例化一个Banana
Banana banana = new Banana();
apple.get();
banana.get();
//实例化一个Apple,用到了多态
Fruit apple = new Apple();
Fruit banana = new Banana();
apple.get();
banana.get();
//实例化一个Apple
Fruit apple = FruitFactory.getApple();
Fruit banana = FruitFactory.getBanana();
apple.get();
banana.get();
Fruit apple = FruitFactory.getFruit("Apple");
Fruit banana = FruitFactory.getFruit("Banana");
apple.get();
banana.get();
}
}
结束
简单工厂
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
不修改代码的话,是无法扩展的。
工厂方法模式:http://blog.csdn.net/hudashi/article/details/7643460
(1)先来看Product的接口,就是ExportFileApi接口,跟前面的示例没有任何变化,为了方便大家查看,这里重复一下,示例代码如下:
/**
* 导出的文件对象的接口
*/
public
interface
ExportFileApi
{
/**
* 导出内容成为文件
* @param data 示意:需要保存的数据
* @return 是否导出成功
*/
public
boolean
export
(
String
data
);
}
(2)同样提供保存成文本文件和保存成数据库备份文件的实现,跟前面的示例没有任何变化,示例代码如下:
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;
}
}
(3)接下来该看看ExportOperate类了,这个类的变化大致如下:
ExportOperate类中的创建产品的工厂方法,通常需要提供默认的实现,不抽象了,也就是变成正常方法
ExportOperate类也不再定义成抽象类了,因为有了默认的实现,客户端可能需要直接使用这个对象
设置一个导出类型的参数,通过export方法从客户端传入
看看代码吧,示例代码如下:
/**
* 实现导出数据的业务功能对象
*/
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;
}
}
(4)此时的客户端,非常简单,直接使用ExportOperate类,示例代码如下:
public
class
Client
{
public
static
void
main
(
String
[]
args
)
{
//创建需要使用的Creator对象
ExportOperate operate = new ExportOperate();
//调用输出数据的功能方法,传入选择到处类型的参数
operate.export(1,"测试数据");
}
}
测试看看,然后修改一下客户端的参数,体会一下通过参数来选择具体的导出实现的过程。这是一种很常见的参数化工厂方法的实现方式,但是也还是有把参数化工厂方法实现成为抽象的,这点要注意,并不是说参数化工厂方法就不能实现成为抽象类了。只是一般情况下,参数化工厂方法,在父类都会提供默认的实现。
(5)扩展新的实现
使用参数化工厂方法,扩展起来会非常容易,已有的代码都不会改变,只要新加入一个子类来提供新的工厂方法实现,然后在客户端使用这个新的子类即可。
这种实现方式还有一个有意思的功能,就是子类可以选择性覆盖,不想覆盖的功能还可以返回去让父类来实现,很有意思。
先扩展一个导出成xml文件的实现,试试看,示例代码如下:
/**
* 导出成xml文件的对象
*/
public
class
ExportXml
implements
ExportFileApi
{
public
boolean
export
(
String
data
)
{
//简单示意一下
System.out.println("导出数据"+data+"到XML文件");
return true;
}
}
然后扩展ExportOperate类,来加入新的实现,示例代码如下:
/**
* 扩展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;
}
}
看看此时的客户端,也非常简单,只是在变换传入的参数,示例代码如下:
public
class
Client
{
public
static
void
main
(
String
[]
args
)
{
//创建需要使用的Creator对象
ExportOperate operate = new ExportOperate2();
//下面变换传入的参数来测试参数化工厂方法
operate.export(1,"Test1");
operate.export(2,"Test2");
operate.export(3,"Test3");
}
}
对应的测试结果如下:
导出数据Test1到文本文件
导出数据Test2到数据库备份文件
导出数据Test3到XML文件
工厂方法
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
在同一等级结构中,支持增加任意产品。
抽象工厂模式:http://blog.csdn.net/hudashi/article/details/50965546
这个实例链接中就有,我觉得和工厂方法很像.
抽象工厂
抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。
简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)