9. 抽象工厂设计模式

422 阅读4分钟

一、什么是抽象工厂?

之前研究过简单工厂设计模式, 工厂设计模式, 今天来看看抽象工厂设计模式. 对比区分他们有什么不同.

什么是抽线工厂呢?

抽象工厂不但工厂是抽象的,产品也是抽象的,而且有多个产品需要创建,因此,这个抽象工厂会对应到多个实际工厂,每个实际工厂负责创建多个实际产品. 抽线工厂是用来解决比较复杂的问题的.

接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

二. 案例

现在有一个抽象工厂, 制作各种颜色的形状. 有颜色, 有形状, 他们组合在一起是一个工厂. 颜色和形状本身又是一个工厂. 来看看UML图:

代码如图所示: 颜色:

/**
 * 颜色
 */
public interface IColor {

    /**
     * 填充颜色
     */
    void fill();
}

public class Red implements IColor {
    @Override
    public void fill() {
        System.out.println("填充红色");
    }
}


public class Green implements IColor {
    @Override
    public void fill() {
        System.out.println("填充绿色");
    }
}


public class Blue implements IColor {
    @Override
    public void fill() {
        System.out.println("填充蓝色");
    }
}

形状

public interface IShape {
    void draw();
}


/**
 * 圆形
 */
public class Circle implements IShape {

    @Override
    public void draw() {
        System.out.println("画一个圆形");
    }
}

/**
 * 正方形
 */
public class Square implements IShape {

    @Override
    public void draw() {
        System.out.println("画一个正方形");
    }
}

/**
 * 长方形
 */
public class Rectangle implements IShape {

    @Override
    public void draw() {
        System.out.println("画一个长方形");
    }
}

抽象工厂

/**
 * 抽象工厂接口类
 */
public interface AbstractFactory {

    // 颜色
    IColor getColor(String type);

    // 形状
    IShape getShape(String type);
}

颜色工厂

/**
 * 颜色工厂
 */
public class ColorFactory implements AbstractFactory {

    @Override
    public IColor getColor(String type) {
        if ("red".equals(type)) {
            return new Red();
        } else if("blue".equals(type)) {
            return new Blue();
        } else {
            return new Green();
        }
    }

    @Override
    public IShape getShape(String type) {
        return null;
    }
}

形状工厂

package com.lxl.www.designPatterns.abstractFactoryPattern.shapeColorFactory;

/**
 * 形状工厂
 */
public class ShapeFactory implements AbstractFactory {


    @Override
    public IColor getColor(String type) {
        return null;
    }

    @Override
    public IShape getShape(String type) {
        if ("circle".equals(type)) {
            return new Circle();
        } else if("square".equals(type)) {
            return new Square();
        } else {
            return new Rectangle();
        }
    }
}

工厂生产者

/**
 * 工厂生产者
 */
public class FactoryProductor {

    // 抽象工厂
    AbstractFactory getFactory(String type) {
        if ("color".equals(type)) {
            return new ColorFactory();
        } else if ("shape".equals("type")) {
            return new ShapeFactory();
        } else {
            return new ShapeFactory();
        }
    }

}

什么时候生产什么东西, 要听指令, 所以传一个参数进来. 最后, 来看看客户端调用

public static void main(String[] args) {
        FactoryProductor factoryProductor = new FactoryProductor();
        AbstractFactory shapeFactory = factoryProductor.getFactory("shape");
        IShape circle = shapeFactory.getShape("circle");
        circle.draw();

        AbstractFactory colorFactory = factoryProductor.getFactory("color");
        IColor red = colorFactory.getColor("red");
        red.fill();
    }

运行结果:

画一个圆形
填充红色

首先, 我先要一个形状, 所以先得到形状工厂, 让形状工厂加工一个原型. 然后, 我要给形状上颜色, 去颜色加工厂, 找到颜色, 最后填充.

这就是抽线工厂, 工厂的工厂. 工厂里面的材料需要去其他工厂获得.

抽象工厂模式是为了让创建工厂和一组产品与使用相分离,并可以随时切换到另一个工厂以及另一组产品;

抽象工厂模式实现的关键点是定义工厂接口和产品接口,但如何实现工厂与产品本身需要留给具体的子类实现,客户端只和抽象工厂与抽象产品打交道。

三. 抽象工厂的优缺点

优点:

抽象工厂模式主要是解决一组具有相同约束的对象的创建问题。其中最核心的概念就是产品族和产品等级结构,抽象工厂模式在扩展产品等级结构是非常容易的,只需要增加新的产品类和新的工厂类就可以,从这点看它是符合开闭原则的

缺点:

若是想扩展产品族,也就是增加一种产品,就需要创建对应类,同时需要修改所有的工厂,是不符合开闭原则的。

四. 简单工厂, 工厂模式, 抽线工厂模式的区别

简单工厂设计模式:

工厂设计模式:

抽线工厂设计模式:

通过UML图可以看出,

  1. 简单工厂设计模式, 工厂的作用是创建单个对象.
  2. 工厂模式, 为每一个功能创建一个工厂, 方便扩展, 可扩展能力比简单工厂更强, 代码结构更复杂
  3. 抽象工厂设计模式, 工厂的工厂. 工厂中所有的产品, 都是其他工厂生产出来的, 需要哪个产品, 告诉抽线工厂, 抽象工厂在指定具体产品工厂创建产品.