简单工厂模式(静态工厂模式):
普通工厂模式就是创建一个工厂类,创建并返回多个实现相同接口的类的实例。
例子:根据传递的类型生产不同的食物。
有一个生产食物的接口:
/**
* 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();
}
抽象工厂模式的优点在于封装性比较好,以接口的形式提供,不需要知道具体如何实现,全部由工厂类来负责创造。所有的约束条件在工厂内实现,不对外公开。只需要知道是哪个工厂就可以创造出想要的对象。
缺点在于产品族非常难以扩展,例如,如果需要增加一个颜色或半生不熟的产品族。那么代码不满足通用原则,需要全部修改,但是如果增加一个产品,比如面包,这样直接新添加一个面包工厂即可。