Skip to the content.

Abstract Factory(抽象工厂)

在此之前,已经学习过了Factory Method(工厂方法),抽象工厂和工厂方法这两个模式都属于创建型设计模式,那么根据[工厂]这个词,大概也能猜出这两个模式都是用来“生产”的

那么这两种用来“生产”的模式 ——— 抽象工厂和工厂方法,这两个设计模式有什么区别呢?或者说也两个模式“生产”的东西有什么不同的吗?

在之前工厂方法的简单实现中,举了个工厂制作蛋糕的例子,那么现在我们的蛋糕店需要生产两种蛋糕,分别为草莓口味的红色的爱心型蛋糕和芒果口味的黄色的方形蛋糕,这两个都是具体的产品,换句话说,对于草莓味心型蛋糕,心型模具和草莓味奶油都是只用来生产这类蛋糕的,那如果我们想做一个爱心型的芒果蛋糕呢?难道还要做一个只属于芒果蛋糕的模具吗?

不,当然不是,在日常生活中,对于这种情况,应该是拿一个爱心模具来做一类爱心型蛋糕,而不会说一种蛋糕做一个模具

到这里,或许对于抽象工厂和工厂方法的区别还是有点模糊

那么,现在来总结一下,

说了这么多,但是还没有见到抽象模式的真身,下面先介绍一下抽象工厂模式,然后,再重新打造我们的工厂,让其能够生产更多类型的蛋糕

Abstract Factory(抽象工厂)的UML类图

先创建产品的抽象类 AbstractProductA

public abstract class AbstractProductA {
    public abstract void doA();
}

AbstractProductB

public abstract class AbstractProductB {
    public abstract void doB();
}

然后再来打造具体的产品细节 ConcreteProductA1

public class ConcreteProductA1 extends AbstractProductA {
    @Override
    public void doA() {
        System.out.println("Concrete Product A 1");
    }

}

ConcreteProductA2

public class ConcreteProductA2 extends AbstractProductA {
    @Override
    public void doA() {
        System.out.println("Concrete Product A 2");
    }

}

ConcreteProductB1

public class ConcreteProductB1 extends AbstractProductB {
    @Override
    public void doB() {
        System.out.println("Concrete Product B 1");
    }

}

ConcreteProductB2

public class ConcreteProductB2 extends AbstractProductB {
    @Override
    public void doB() {
        System.out.println("Concrete Product B 2");
    }

}

OK,关于具体的产品细节已经做好了,现在最关键的就是通过工厂,来将这些细节组装成一个具体的产品

首先,在打造一个抽象工厂

AbstractFactory

public abstract class AbstractFactory {
    // 生产产品细节A
    public abstract AbstractProductA createProductA();
    // 生产产品细节B
    public abstract AbstractProductB createProductB();
}

好了,接下来就是根据需要打造具体的工厂了 ConcreteFactory1:生产产品细节A1和产品细节B2

public class ConcreteFactory1 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

ConcreteFactory2:生产产品细节A2和产品细节B1

public class ConcreteFactory2 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

好了,现在我们只需要通过这两个工厂,就能得到一个具有A和B两种不同细节的产品

抽象工厂模式的简单实现

还是挺简单的,那么,接下来,借助上面的经验,是时候将蛋糕店好好装修一番了,让蛋糕店可以生产各种各样的产品

首先,分析一下,对于蛋糕

那么根据调查发现(是我瞎说的~),现在爱心型的草莓味蛋糕和芒果味的方形蛋糕是卖的最火的,所以,蛋糕店也需要与时俱进,将要生产这种两种蛋糕

好了,分析完了,我们先根据造型,打造一个抽象造型产品(或者说是蛋糕模板也可以啦~)

抽象造型产品

public abstract class CakeStyle {
    public abstract void style();
}

再根据奶油,打造一个抽象奶油产品

抽象奶油产品

public abstract class CakeCream {
    public abstract void cream();
}

OK,下面分别开始制作爱心型模板,方形模板,草莓味奶油,芒果味奶油

爱心型模板

public class HeartStyle extends CakeStyle {
    @Override
    public void style() {
        System.out.println("Heart Style");
    }
}

方形模板

public class SquareStyle extends CakeStyle {
    @Override
    public void style() {
        System.out.println("Square Style");
    }
}

草莓味奶油

public class StrawberryCream extends CakeCream {
    @Override
    public void cream() {
        System.out.println("Strawberry Cream");
    }
}

芒果味奶油

public class MangoCream extends CakeCream {
    @Override
    public void cream() {
        System.out.println("Mango Cream");
    }
}

现在,无论是材料还是工具都做好了,只要根据需要,通过具体的工厂生产就行了

首先,还是来一个抽象工厂

public abstract class CakeFactory {

    public abstract CakeCream cream();

    public abstract CakeStyle style();
}

然后,就分别是爱心型草莓味蛋糕工厂和方形芒果味蛋糕工厂

爱心型草莓味蛋糕工厂

public class StrawberryHeartCake extends CakeFactory{
    @Override
    public CakeCream cream() {
        return new StrawberryCream();
    }

    @Override
    public CakeStyle style() {
        return new HeartStyle();
    }
}

方形芒果味蛋糕工厂

public class MangoSquareCake extends CakeFactory {
    @Override
    public CakeCream cream() {
        return new MangoCream();
    }

    @Override
    public CakeStyle style() {
        return new SquareStyle();
    }
}

大功告成,让我们来看看蛋糕做得怎么样

 public static void main(String[] args) {
        CakeFactory strawberryHeartCake = new StrawberryHeartCake();
        strawberryHeartCake.cream().cream();
        strawberryHeartCake.style().style();

        System.out.println();

        CakeFactory mangoSquareCake = new MangoSquareCake();
        mangoSquareCake.cream().cream();
        mangoSquareCake.style().style();
 }

result:

Strawberry Cream
Heart Style

Mango Cream
Square Style

还不赖嘛~

如果,这时需求变更了,比如,现在更流行吃爱心型芒果味蛋糕

那么我们只需要一个工厂就可以做 到了,而不需要再去重头开始制作奶油和模板

爱心型芒果味蛋糕

public class MangoHeartCake extends CakeFactory {
    @Override
    public CakeCream cream() {
        return new MangoCream();
    }

    @Override
    public CakeStyle style() {
        return new HeartStyle();
    }
}

还是挺简单的嘛~

好了,来总结一下抽象工厂的优缺点吧