前言
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
示例
1. 饮料制作
public interface Drink {
void production();
}
public class ColaDrinkProduction implements Drink{
@Override
public void production() {
System.out.println("生产可乐饮料");
}
}
public class SpriteDrinkProduction implements Drink{
@Override
public void production() {
System.out.println("生产雪碧饮料");
}
}
2. 饮料打包
public interface Pack {
void productPack();
}
public class ColaDrinkPack implements Pack{
@Override
public void productPack() {
System.out.println("打包可乐饮料");
}
}
public class SpriteDrinkPack implements Pack{
@Override
public void productPack() {
System.out.println("打包雪碧饮料");
}
}
3. 生产工厂
public interface ProductionFactory {
//制作饮料
Drink productionDrink();
//打包饮料
Pack packDrink();
}
public class ColaDrinkProductionFactory implements ProductionFactory {
@Override
public Drink productionDrink() {
return new ColaDrinkProduction();
}
@Override
public Pack packDrink() {
return new ColaDrinkPack();
}
}
public class SpriteDrinkProductionFactory implements ProductionFactory {
@Override
public Drink productionDrink() {
return new SpriteDrinkProduction();
}
@Override
public Pack packDrink() {
return new SpriteDrinkPack();
}
}
4. 工厂调用
ProductionFactory factory = new ColaDrinkProductionFactory();
factory.productionDrink().production();
factory.packDrink().productPack();
factory = new SpriteDrinkProductionFactory();
factory.productionDrink().production();
factory.packDrink().productPack();
5. 源码
https://download.csdn.net/download/javanbme/15985345
抽象工厂模式把开放-封闭原则,依赖倒转原则运用的很好,可以很方便地切换两个饮料生产过程的代码,但是如果你的需求来自增加功能,比如我们现在要增加发货的功能,需要增加IDrinkDeliverGoods、ColaDrinkDeliverGoods、SpriteDrinkDeliverGoods
还需要更改IProductionFactory、ColaDrinkProductionFactory和 SpriteDrinkProductionFactory 才可以完全实现。太糟糕了。
简单工厂模式+反射改进抽象工厂模式
1. 去掉ProductionFactory、SpriteDrinkProductionFactory、ColaDrinkProductionFactory三个工厂类 ,新增 DrinkFactory类。
类的全限定名自行修改
public class DrinkFactory {
public static Drink productionDrink(String type){
String className = "com.suiyun.factory.drink." + type +"DrinkProduction";
System.out.println(className);
try {
return (Drink)Class.forName(className).newInstance();
} catch (Exception e) {
return null;
}
}
public static Pack packDrink(String type){
String className = "com.suiyun.factory.pack." + type +"DrinkPack";
try {
return (Pack)Class.forName(className).newInstance();
} catch (Exception e) {
return null;
}
}
}
2. 工厂调用
String type = "Cola";
Drink drink = DrinkFactory.productionDrink(type);
drink.production();
Pack pack = DrinkFactory.packDrink(type);
pack.productPack();
3. 源码
https://download.csdn.net/download/javanbme/15987456