设计模式-抽象工厂模式

180 阅读5分钟

抽象工厂模式

定义

抽象工厂模式是工厂方法模式的升级版,因为工厂方法模式的特点是具体工厂只生产唯一的具体一个产品,而抽象工厂模式是每个工厂可以生产多个具体种类的产品。

解决什么问题呢?

允许使用抽象的工厂类来创建一组产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。这就解决了每个工厂只能创建一类产品。

模式组成

使用步骤

步骤1: 创建抽象工厂类,定义具体工厂的公共接口;
步骤2: 创建抽象产品族类 ,定义抽象产品的公共接口;
步骤3: 创建抽象产品类 (继承抽象产品族类),定义具体产品的公共接口;
步骤4: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤5: 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤6: 客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例

实例

背景

背景:小成有两间塑料加工厂(A厂仅生产容器类产品;B厂仅生产模具类产品);随着客户需求的变化,A厂所在地的客户需要也模具类产品,B厂所在地的客户也需要容器类产品;
冲突:没有资源(资金+租位)在当地分别开设多一家注塑分厂 解决方案:在原有的两家塑料厂里增设生产需求的功能,即A厂能生产容器+模具产品;B厂间能生产模具+容器产品。

使用步骤

步骤1: 创建抽象工厂类,定义具体工厂的公共接口

abstract class Factory{
   public abstract Product ManufactureContainer();
    public abstract Product ManufactureMould();
}

步骤2: 创建抽象产品族类 ,定义具体产品的公共接口;

abstract class AbstractProduct{
    public abstract void Show();
}

步骤3: 创建抽象产品类 ,定义具体产品的公共接口;

//容器产品抽象类
abstract class ContainerProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

//模具产品抽象类
abstract class MouldProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

步骤4: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;

//容器产品A类
class ContainerProductA extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生产出了容器产品A");
    }
}

//容器产品B类
class ContainerProductB extends ContainerProduct {
    @Override
    public void Show() {
        System.out.println("生产出了容器产品B");
    }
}

//模具产品A类
class MouldProductA extends MouldProduct {

    @Override
    public void Show() {
        System.out.println("生产出了模具产品A");
    }
}

//模具产品B类
class MouldProductB extends MouldProduct {

    @Override
    public void Show() {
        System.out.println("生产出了模具产品B");
    }
}

步骤5: 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;

//A厂 - 生产模具+容器产品
class FactoryA extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductA();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductA();
    }
}

//B厂 - 生产模具+容器产品
class FactoryB extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductB();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductB();
    }
}

步骤6: 客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例

//生产工作流程
public class AbstractFactoryPattern {
    public static void main(String[] args){
        FactoryA mFactoryA = new FactoryA();
        FactoryB mFactoryB = new FactoryB();
        //A厂当地客户需要容器产品A
        mFactoryA.ManufactureContainer().Show();
        //A厂当地客户需要模具产品A
        mFactoryA.ManufactureMould().Show();

        //B厂当地客户需要容器产品B
        mFactoryB.ManufactureContainer().Show();
        //B厂当地客户需要模具产品B
        mFactoryB.ManufactureMould().Show();

    }
}
----------------------
输出
生产出了容器产品A
生产出了容器产品B
生产出了模具产品A
生产出了模具产品B

优点

  • 1.老样子还是降低了耦合性,具体产品的创建在具体的工厂里面(这里面的区别是这个具体工厂可以创建多个具体产品)
  • 2.符合开闭原则,新增一个产品类,只需要增加相应的具体工厂跟相应的工厂子类(我理解其实这也是一个缺点,跟工厂方法模式一样,需要创建的类也增加不少)
  • 3.符合单一职责原则,每个具体工厂类只创建对应的产品(工厂方法模式也是这样,只是工厂方法模式每个工厂只创建一个具体的产品)

缺点

抽象工厂模式很难支持新种类产品的变化。 这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

应用场景

暂时并没有考虑到实际场景,后续如果找到合适场景,补充上来。

总结

抽象工厂模式理解起来相对于工厂方法模式要稍复杂些(对本人而言),而且对架构能力要求更高些,我现在能想到的优势就是,一个工厂可以创建多款产品的。
这篇文章还是参考 (抽象工厂模式)[www.jianshu.com/p/7deb64f90…