设计模式《工厂方法模式》
2018-07-06 本文已影响0人
天道__
引言
上一节我们说了单例模式,这一节我们来说说工厂方法模式。
示例地址
先看类图
工厂方法模式定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
使用场景
在任何需要生成复制对象的地方,都可以使用工厂方法模式。
工厂方法模式示例
举个例子,我们吃饭的时候都会点主食,主食的种类分为 米饭、面,南方人喜欢吃米饭,但是北方人喜欢吃面。
简单工厂模式
1. 我们先来设计产品
/**
* 主食
* @author 512573717@qq.com
* @created 2018/7/6 下午2:36.
*
*/
public interface IZhuShi {
// 主食吃什么
void eat();
}
2. 产品一:南方人爱吃米饭
/**
* 主食米饭
*
* @author 512573717@qq.com
* @created 2018/7/6 下午2:37.
*
*/
public class Rice implements IZhuShi {
@Override
public void eat() {
System.out.println("主食米饭上来了。");
}
}
3. 产品二:北方人爱吃面食
/**
* 主食面
*
* @author 512573717@qq.com
* @created 2018/7/6 下午2:43.
*/
public class Flour implements IZhuShi {
@Override
public void eat() {
System.out.println("主食 面上来了。");
}
}
简单(静态)工厂
接下来是我们怎么创建产品了,就是我们在点餐的时候要选择吃什么。
1. 主食工厂
/**
* 主食工厂
*
* @author 512573717@qq.com
* @created 2018/7/6 下午2:48.
*/
public class FactoryZhuShi {
//南方人
public static final int SOUTH = 1;
//北方人
public static final int NORTH = 2;
public static IZhuShi createZhuShi(int type) {
switch (type) {
case SOUTH:
return new Rice();
case NORTH:
return new Flour();
default:
return new Rice();
}
}
}
2. 调用工厂创建产品
IZhuShi south = FactoryZhuShi.createZhuShi(FactoryZhuShi.SOUTH);
south.eat();
IZhuShi north = FactoryZhuShi.createZhuShi(FactoryZhuShi.NORTH);
north.eat();
3. 如果我们增加了产品三(水饺),这个时候就需要修改工程类了,违背了设计模式的六大原则(开闭原则)。
简单(反射)工厂
Java中反射是无所不能的。那我们就反一种思路,我们通过反射实现。
1. 反射实现工厂
/**
* 通过反射获取主食
*
* @author 512573717@qq.com
* @created 2018/7/6 下午3:11.
*/
public class ReflectFactoryZhuShi {
public static <T extends IZhuShi> T createZhuShi(Class<T> cls) {
T object = null;
try {
object = (T) (Class.forName(cls.getName())).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
}
2. 调用工厂创建产品
IZhuShi south = ReflectFactoryZhuShi.createZhuShi(Rice.class);
south.eat();
IZhuShi north = ReflectFactoryZhuShi.createZhuShi(Flour.class);
north.eat();
3. 在增加新产品的时候,我们无需修改工厂类,解决设计模式的开闭原则。但是反射影响性能,我们在来看看方法工厂模式
简单工厂
反射有效率问题,我们看看最常用的一种写法
1. 日常写法
/**
* 简单工厂
*
* @author 512573717@qq.com
* @created 2018/7/6 下午3:37.
*/
public class MethodFactoryZhuShi {
public static Rice getRice() {
return new Rice();
}
public static Flour getFlour() {
return new Flour();
}
}
2. 简单调用
IZhuShi south = MethodFactoryZhuShi.getRice();
south.eat();
IZhuShi north = MethodFactoryZhuShi.getFlour();
north.eat();
工厂方法模式
1. 工厂接口
/**
* 主食创建工厂
*
* @author 512573717@qq.com
* @created 2018/7/6 下午4:08.
*/
public interface IFactory<T extends IZhuShi> {
T create();
}
2. 米饭工厂
/**
* 米饭工厂
*
* @author 512573717@qq.com
* @created 2018/7/8 下午11:11.
*
*/
public class RiceFactory implements IFactory<Rice> {
@Override
public Rice create() {
return new Rice();
}
}
3. 面食工厂
/**
* 面食工厂
*
* @author 512573717@qq.com
* @created 2018/7/8 下午11:11.
*
*/
public class FlourFactory implements IFactory<Flour> {
@Override
public Flour create() {
return new Flour();
}
}
4. 简单调用
IFactory northFactory = new FlourFactory();
IZhuShi north = northFactory.create();
north.eat();
IFactory southFactory = new RiceFactory();
IZhuShi south = southFactory.create();
south.eat();
总结
当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建并基础抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!