工厂模式可以分为三类--简单工厂模式,工厂方法模式,抽象工厂模式,很久之前我已经写过了简单工厂模式和工厂方法模式了,这篇文章在以前的基础上学习抽象工厂模式。
前面提到,有一家水果店出售苹果和香蕉,现在水果店新增了一项业务,出售果汁,比如苹果汁和香蕉汁。该怎么实现呢?我们先从代码入手:
代码一:使用工厂方法模式:
//水果接口
interface Fruit2{
public void tell();
}
//苹果
class Apple2 implements Fruit2{
public void tell() {
System.out.println("我是苹果");
}
}
//香蕉
class Banana2 implements Fruit2{
public void tell() {
System.out.println("我是香蕉");
}
}
//果汁接口
interface Juice2{
public void say();
}
//苹果汁
class AppleJuice2 implements Juice2{
public void say() {
System.out.println("我是苹果汁");
}
}
//香蕉汁
class BananaJuice2 implements Juice2{
public void say() {
System.out.println("我是香蕉汁");
}
}
//水果工厂
interface FruitFacory{
public Fruit creatFruit();
}
//苹果工厂
class AppleFacory implements FruitFacory{
public Fruit creatFruit() {
return new Apple();
}
}
//香蕉工厂
class BananaFacory implements FruitFacory{
public Fruit creatFruit() {
return new Banana();
}
}
//果汁工厂
interface JuiceFactory{
public Juice creatJuice();
}
//苹果汁工厂
class AppleJuiceFactory implements JuiceFactory{
public Juice creatJuice() {
return new AppleJuice();
}
}
//香蕉汁工厂
class BananaJuiceFactory implements JuiceFactory{
public Juice creatJuice() {
return new BananaJuice();
}
}
public class Store2 {
public static void main(String args[]){
JuiceFactory juiceFactory = new AppleJuiceFactory();
juiceFactory.creatJuice().say();
}
}
代码二:使用抽象工厂模式:
//水果接口
interface Fruit{
public void tell();
}
//苹果
class Apple implements Fruit{
public void tell() {
System.out.println("我是苹果");
}
}
//香蕉
class Banana implements Fruit{
public void tell() {
System.out.println("我是香蕉");
}
}
//果汁接口
interface Juice{
public void say();
}
//苹果汁
class AppleJuice implements Juice{
public void say() {
System.out.println("我是苹果汁");
}
}
//香蕉汁
class BananaJuice implements Juice{
public void say() {
System.out.println("我是香蕉汁");
}
}
//抽象工厂
interface AbstractFactory{
public Fruit getFruit();
public Juice getJuice();
}
//具体工厂1
class Apple_Juice_Factory implements AbstractFactory{
public Fruit getFruit() {
return new Apple();
}
public Juice getJuice() {
return new AppleJuice();
}
}
//具体工厂2
class Banana_Juice_Factory implements AbstractFactory{
public Fruit getFruit() {
return new Banana();
}
public Juice getJuice() {
return new BananaJuice();
}
}
//商店
public class Store {
public static void main(String args[]){
AbstractFactory factory = new Apple_Juice_Factory();
factory.getJuice().say();
}
}
首先,我们引入一个概念---产品族,产品族是指位于不同产品等级结构中,功能相关联的产品(一般位于不同等级结构的相同位置)组成的家族,显然每一个产品族中含有的产品数量与产品等级结构的数量是相同的。
当然,这是一句相当抽象的话,我们结合我们的例子来理解这句话。
在我们的例子中,水果和水果汁就是两个不同的产品等级结构(它们当然不是一个等级,果汁是水果加工后的产物),水果包含苹果和香蕉,果汁包含苹果汁和香蕉汁,苹果和苹果汁,香蕉和香蕉汁功能相关联,所以苹果和苹果汁是一个产品族,香蕉和香蕉汁是一个产品族,每个产品族都有两个产品。看下面这张图应该可以更好的理解:
横坐标表示产品等级结构,纵坐标表示产品族,这样苹果和苹果汁是同一产品族,香蕉和香蕉汁是同一产品族。
当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这些产品的等级结构。如代码一中存在两个产品等级结构,分别是水果等级结构和水果汁等级结构,两者之间相互独立。
抽象工厂模式使用同一个 工厂等级结构负责这些不同产品等级结构产品对象的创建。对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。大家可仔细观察代码二。
通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。
由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。
结合代码来说,Apple_Juice_Factory和Banana_Juice_Factory这两个具体工厂都需要负责水果和果汁这两个等级结构的产品对象的创建,因此他们提供了两个方法public Fruit getFruit()和public Juice getJuice()分别用于创建Fruit和Juice的产品。由于这两个具体工厂实现的方法一致,所以可以抽象出一个抽象工厂AbstractFactory
当只涉及一个产品等级结构时,我们使用工厂方法模式即可,工厂方法模式其实就是抽象工厂模式的一种特殊情况。
当涉及多个产品等级结构时,我们最好使用抽象工厂模式。
这就是小编对抽象工厂的理解。