抽象工厂模式使用了一个接口,该接口中定义了创建一个产品所需要的所有具体原料的原料族。在抽象工厂模式中主要有四个部分:抽象工厂,抽象产品,具体工厂,具体产品。具体的类图如下:
从上面的图中可以看出,抽象工厂模式依赖两个主体,抽象工厂和抽象产品族,当需要使用抽象工厂模式时只需要实现这两个主体即可。从上面的图中也可以看出,抽象工厂模式很像多个工厂方法模式的组合,但是抽象工厂模式和工厂方法模式本质上是不一样的,主要表现在以下几点:
- 抽象工厂模式时定义一个负责创建一组产品的接口,这个接口内的每个方法都负责创建一个具体产品,同时我们利用实现抽象工厂的子类来提供这些具体的做法;而工厂方法模式则负责创建摸一个抽象产品,并且使用该产品进行其他的一些操作。
- 抽象工厂模式创建对象的时候使用的是一个接口,而工厂方法模式创建对象的时候是使用的一个抽象类(方便进行其他操作)。
总的来说,当需要创建产品家族和想让制造的相关产品集合起来时,就是用抽象工厂模式;当需要对创建的产品进行其他的操作,或者是需要将实例化的动作从具体的类中解耦就可以使用工厂方法模式。
下面我们就以一个具体的例子来介绍抽象工厂模式。在前面一节中我们介绍了使用工厂方法模式来生产pizza,并进行准备,烘烤,切片和装箱等一系列操作。这里对于一个pizza的制作,需要多种原料,并且不同地点的pizza因为制作工艺不同,需要的原料的品种也不同,但是由于pizza是统一连锁店,因而我们需要对原料进行统一管理。这里我们就为不同地区的pizza创建不同的原料工厂,而为了方便管理,我们需要一个抽象的工厂来规范对各个地区原料工厂的行为,并且由于pizza的制作工艺大致是相同的,只不过所使用的量有所不同,因而每个工厂所生产的原料类型是一样的,这里就可以对各个不同的原料类型进行一个抽象。下面是具体的实现代码(为了与上一节代码不重复,这里只附上关键性代码)。
抽象工厂:
public interface PizzaIngredientFactory {
Dough createDough();
Sauce createSauce();
Cheese createCheese();
Veggies[] createVeggies();
Pepperoni createPepperoni();
Clams createClam();
}
抽象产品:
public interface Dough {
}
public interface Sauce {
}
public interface Veggies {
}
public interface Pepperoni {
}
public interface Clams {
}
具体工厂:
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough() {
return new ThinCrustDough();
}
public Sauce createSauce() {
return new MarinaraSauce();
}
public Cheese createCheese() {
return new ReggianoCheese();
}
public Veggies[] createVeggies() {
return new Veggies[]{new Garlic(), new Onion(), new Mushroom(), new RedPepper()};
}
public Pepperoni createPepperoni() {
return new SlicedPepperoni();
}
public Clams createClam() {
return new FreshClams();
}
}
具体产品:
public class ThinCrustDough implements Dough {
}
public class ReggianoCheese implements Cheese {
}
public class Garlic implements Veggies {
}
public class Onion implements Veggies {
}
public class Mushroom implements Veggies {
}
public class RedPepper implements Veggies {
}
public class SlicedPepperoni implements Pepperoni {
}
public class FreshClams implements Clams {
}