介绍:提供一个创建一系列相关的相互依赖对象的接口,而无需指定它们具体的类。它和工厂方法模式的区别就在于所创建对象的复杂度上。抽象工厂和简单工厂、工厂方法相比是最具一般性的。
场景:接着我们的pizza工厂,不过现在上头又增加了需求。他希望我们在中国pizza下面有番茄酱和沙拉酱两种口味,而美国pizza下面也有有番茄酱和沙拉酱两种口味。如果使用的是工厂方法模式,那么我们就需要再添加4种工厂分布制作不同的产品。
概念:
优点:工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。
介绍:我们将所有工厂的业务抽象出来,每个工厂必须实现对所有等级类别的产品的生产。每个子工厂用于实现一个产品族的生产。
披萨定义
// 中国番茄酱pizza
public class KetchupChinesePizza extends ChinesePizza {
@Override
public void addSeasoning() {
System.out.println("添加番茄酱");
}
}
// 美国番茄酱pizza
public class KetchupUSPizza extends USPizza {
@Override
public void addSeasoning() {
System.out.println("添加番茄酱");
}
}
// 中国沙拉酱pizza
public class SaladChinesePizza extends ChinesePizza {
@Override
public void addSeasoning() {
System.out.println("添加沙拉酱");
}
}
// 美国沙拉酱pizza
public class SaladUSPizza extends USPizza {
@Override
public void addSeasoning() {
System.out.println("添加沙拉酱");
}
}
抽象工厂
工厂需要能生产中国pizza和美国pizza
public abstract class PizzaFactory {
public abstract ChinesePizza createChinesePizza();
public abstract USPizza createUSPizza();
}
番茄酱工厂
能制作所有国家的番茄酱pizza
public class KetchupPizzaFactory extends PizzaFactory {
@Override
public ChinesePizza createChinesePizza() {
System.out.println("开始制作中国pizza");
KetchupChinesePizza pizza = new KetchupChinesePizza();
pizza.addFlour();
pizza.addWater();
pizza.addSeasoning();
return pizza;
}
@Override
public USPizza createUSPizza() {
System.out.println("开始制作美国pizza");
KetchupUSPizza pizza = new KetchupUSPizza();
pizza.addFlour();
pizza.addWater();
pizza.addSeasoning();
return pizza;
}
}
沙拉酱工厂
能制作所有国家的沙拉酱pizza
public class SaladPizzaFactory extends PizzaFactory {
@Override
public ChinesePizza createChinesePizza() {
System.out.println("开始制作中国pizza");
SaladChinesePizza pizza = new SaladChinesePizza();
pizza.addFlour();
pizza.addWater();
pizza.addSeasoning();
return pizza;
}
@Override
public USPizza createUSPizza() {
System.out.println("开始制作美国pizza");
SaladUSPizza pizza = new SaladUSPizza();
pizza.addFlour();
pizza.addWater();
pizza.addSeasoning();
return pizza;
}
}
提供pizza业务
public class TestMain {
public static void main(String[] args) {
PizzaFactory kf = new KetchupPizzaFactory();
ChinesePizza pizza1 = kf.createChinesePizza();
PizzaFactory sf = new SaladPizzaFactory();
USPizza pizza2 = sf.createUSPizza();
}
}
输出如下:
开始制作中国pizza
加400克面粉
加100ml水
添加番茄酱
开始制作美国pizza
加300克面粉
加100ml水
添加沙拉酱
不足:
如果我们再增加一个产品树(等级结构),比如巴西pizza,那么,我们需要为每个子工厂添加一个巴西披萨的制作方法。
场景:为了对上面的不足加以调整,我们可以通过静态工厂结合抽象工厂,并通过反射机制来对pizza进行制作。
工厂类
public class SRFactory {
public static ChinesePizza createChinesePizza(String name) throws Exception {
System.out.println("开始制作中国pizza");
ChinesePizza pizza = (ChinesePizza) Class.forName(name).newInstance();
pizza.addFlour();
pizza.addWater();
pizza.addSeasoning();
return pizza;
}
public static USPizza createUSPizza(String name) throws Exception {
System.out.println("开始制作美国pizza");
USPizza pizza = (USPizza) Class.forName(name).newInstance();
pizza.addFlour();
pizza.addWater();
pizza.addSeasoning();
return pizza;
}
}
提供pizza业务
public static void main(String[] args) throws Exception {
USPizza pizza = SRFactory.createUSPizza("com.bjpowernode.factory.model.KetchupUSPizza");
ChinesePizza pizza2 = SRFactory.createChinesePizza("com.bjpowernode.designmodel.factory.model.SaladChinesePizza");
}
输出如下:
开始制作美国pizza
加300克面粉
加100ml水
添加番茄酱
开始制作中国pizza
加400克面粉
加100ml水
添加沙拉酱
总结:
工厂模式在具体实践中是使用比较频繁的,但是我们需要了解他们的长处和不足,根据特定情况来决定需要使用的模式。
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54