简单工厂模式(静态工厂模式):
普通工厂模式就是创建一个工厂类,创建并返回多个实现相同接口的类的实例。
例子:根据传递的类型生产不同的食物。
有一个生产食物的接口:
/**
* Created by j on 2018/2/27.
*/
public interface
Food {
public static void
creatFood
()
;
}
一个生产面条的实现类:
/**
* Created by j on 2018/2/27.
*/
public class
Noodle
implements
Food {
public
static
void
creatFood
() {
System.
out
.println(
"
生产面条
"
)
;
}
}
一个生产大米的实现类:
/**
* Created by j on 2018/2/27.
*/
public class
Rice
implements
Food {
@Override
public
static
void
creatFood
() {
System.
out
.println(
"
生产大米
"
)
;
}
}
创建一个食物工厂:
/**
* Created by j on 2018/2/27.
*/
public class
FoodFactory {
public
static
Food
getFood
(String type) {
if
(
"noodle"
.equals(type)) {
return new
Noodle()
;
}
else if
(
"rice"
.equals(type)) {
return new
Rice()
;
}
else
{
throw new
NullPointerException(
"
找不到需要的类型
"
)
;
}
}
}
最后创建一个测试类:
/**
* Created by kaijiyu on 2018/2/27.
*/
public class
Test {
public static void
main
(String[] args) {
Food food =
FoodFactory
.getFood(
"noodle"
)
;
food.creatFood()
;
}
}
其实这样做的缺点很明显,虽然能够根据类型对应返回不同的实例,但是如果新加一个品种比如面包,就需要修改工厂类,违反了开闭原则,不利于维护。
工厂方法模式
工厂方法模式是对简单工厂模式的升级,将工厂抽象出来,对每个产品创建一个工厂来专门生产,使其可以扩展,复合开闭原则。
食物类:
/**
* Created by j on 2018/2/28.
*/
public interface
Food {
public void
getFoodName
()
;
}
/**
* Created by j on 2018/2/28.
*/
public class
Noodle
implements
Food {
@Override
public void
getFoodName
() {
System.
out
.println(
"
食物的名称是面条
"
)
;
}
}
/**
* Created by j on 2018/2/28.
*/
public class
Rice
implements
Food {
@Override
public void
getFoodName
() {
System.
out
.println(
"
食物的名称是大米
"
)
;
}
}
工厂类:
/**
* Created by j on 2018/2/28.
*/
public interface
FoodFactory {
public
Food
createFood
()
;
}
/**
* Created by j on 2018/2/28.
*/
public class
NoodleFactory
implements
FoodFactory {
@Override
public
Food
createFood
() {
return new
Noodle()
;
}
}
/**
* Created by j on 2018/2/28.
*/
public class
RiceFactory
implements
FoodFactory {
@Override
public
Food
createFood
() {
return new
Rice()
;
}
}
测试类:
/**
* Created by j on 2018/2/28.
*/
public class
Test {
public static void
main
(String[] args) {
FoodFactory noodleFactory =
new
NoodleFactory()
;
FoodFactory riceFactory =
new
RiceFactory()
;
Food noodle = noodleFactory.createFood()
;
Food rice = riceFactory.createFood()
;
noodle.getFoodName()
;
rice.getFoodName()
;
}
}
工厂方法模式是对一种产品族的多种产品的生产,如果对于多产品族,比如说食物添加一个产品族,分成生的和熟的,这时代码就无法进行通用了。这时,就需要用到抽象工厂模式
抽象工厂模式
抽象工厂是工厂方法模式的升级版,用于多产品族多种产品的情况使用。
食物类:
public interface
Food {
public void
getFoodName
()
;
public void
getIsCooked
()
;
}
public abstract class
CookedFood
implements
Food{
public void
getIsCooked
(){
System.
out
.println(
"
生产一个熟的食物
"
)
;
}
}
public abstract class
RawFood
implements
Food{
public void
getIsCooked
(){
System.
out
.println(
"
生产一个生的食物
"
)
;
}
}
public class
CookedNoodle
extends
CookedFood {
@Override
public void
getFoodName
() {
System.
out
.println(
"
食物的名称是面条
"
)
;
}
}
public class
CookedRice
extends
CookedFood {
@Override
public void
getFoodName
() {
System.
out
.println(
"
食物的名称是大米
"
)
;
}
}
public class
RawNoodle
extends
RawFood {
@Override
public void
getFoodName
() {
System.
out
.println(
"
食物的名称是面条
"
)
;
}
}
public class
RawRice
extends
RawFood {
@Override
public void
getFoodName
() {
System.
out
.println(
"
食物的名称是大米
"
)
;
}
}
工厂类:
public interface
FoodFactory {
public
Food
createCookedFood
()
;
public
Food
createRawFood
()
;
}
public class
NoodleFactory
implements
FoodFactory {
@Override
public
CookedFood
createCookedFood
() {
return new
CookedNoodle()
;
}
@Override
public
Food
createRawFood
() {
return new
RawNoodle()
;
}
}
public class
RiceFactory
implements
FoodFactory {
@Override
public
Food
createCookedFood
() {
return new
CookedRice()
;
}
@Override
public
Food
createRawFood
() {
return new
RawRice()
;
}
}
测试类:
public class
Test {
public static void
main
(String[] args) {
FoodFactory noodleFactory =
new
NoodleFactory()
;
FoodFactory riceFactory =
new
RiceFactory()
;
//
生产一个熟的面条
Food noodle = noodleFactory.createCookedFood()
;
//
生产一个生的大米
Food rice = riceFactory.createRawFood()
;
noodle.getIsCooked()
;
noodle.getFoodName()
;
rice.getIsCooked()
;
rice.getFoodName()
;
}
}
也可以通过反射的机制和简单工厂模式来将抽象工厂升级:
public class
AbsFoodFactory {
// 通过
AbsFoodFactory.createFood(CookedNoodle.class); 调用
public static
Food
createFood
(Class clazz)
throws
Exception {
return
(Food)clazz.newInstance()
;
}
抽象工厂模式的优点在于封装性比较好,以接口的形式提供,不需要知道具体如何实现,全部由工厂类来负责创造。所有的约束条件在工厂内实现,不对外公开。只需要知道是哪个工厂就可以创造出想要的对象。
缺点在于产品族非常难以扩展,例如,如果需要增加一个颜色或半生不熟的产品族。那么代码不满足通用原则,需要全部修改,但是如果增加一个产品,比如面包,这样直接新添加一个面包工厂即可。