Skip to content

工厂模式

一、工厂模式介绍

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种封装对象创建过程的方法,将对象的实例化过程延迟到子类或具体实现类中。

它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。

工厂模式有 3 种不同的实现方式

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

应用场景

  • 解耦:分离职责,把复杂对象的创建和使用的过程分开
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时。
  • 复用代码,降低维护成本:
    • 如果对象创建复杂且多处需用到,如果每处都进行编写,则很多重复代码,如果业务逻辑发生了改变,需用四处修改;
    • 使用工厂模式统一创建,则只要修改工厂类即可,降低成本

二、工厂基类

不同的实现公共的对象

2.1 抽象产品(Abstract Product)

定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法。


/**
 * 笔接口
 * @Author lcy
 * @Date 2021/7/20 10:00
 */
public interface Pen {

    /**
     * 获取产品名称
     * @return java.lang.String
     * @author lcy
     * @date 2021/7/20 10:07
     **/
    String getProductName();

    /**
     * 写字
     * @author lcy
     * @date 2021/7/20 10:07
     **/
    default void write(){
        System.out.printf("The %s is writing%n",getProductName());
    }

}

2.2 具体产品(Concrete Product)

实现了抽象产品接口,定义了具体产品的特定行为和属性。

/**
 * 铅笔
 * @Author lcy
 * @Date 2021/7/20 10:08
 */
public class Pencil implements Pen {

    @Override public String getProductName(){
        return "铅笔";
    }
}
/**
 * 钢笔
 * @Author lcy
 * @Date 2021/7/20 10:09
 */
public class FountainPen implements Pen {

    @Override public String getProductName(){
        return "钢笔";
    }
}

三、简单工厂模式

3.1 特点

  • 包含一个工厂类,该工厂类负责根据传递的参数创建相应的对象。
  • 客户端代码不需要关心具体实例的创建过程,只需通过工厂类获取所需对象即可。

核心类:

  • 抽象产品(Abstract Product):抽象产品类,定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法
  • 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性
  • 具体工厂(Concrete Factory):负责实际创建具体产品的对象

3.2 优缺点

优点:

  • 封装了对象的创建过程,客户端代码无需关心具体实现类。
  • 降低了客户端代码与具体实现类的耦合度。

缺点:

  • 工厂类职责过重,一旦需要添加新的产品类型,就需要修改工厂类的代码,违背了开闭原则。

3.3 工厂实现类

/**
 * 简单工厂模式
 * @Author lcy
 * @Date 2021/7/20 10:10
 */
public class SimplePenFactory {

    /**
     * 根据种类生产
     * @param type 种类
     * @return com.lcy.study.design.factory.Pen
     * @author lcy
     * @date 2021/7/20 10:11
     **/
    public static Pen factory(String type){
        return switch (type) {
            case "FountainPen" -> new FountainPen();
            case "Pencil" -> new Pencil();
            default -> null;
        };
    }

}

四、工厂方法模式

相比简单工厂而言,此种方法具有更多的可扩展性和复用性,同时也增强了代码的可读性,将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类

4.1 特点

  • 引入了抽象工厂接口,由具体子类负责实现工厂接口,每个子类对应一个具体产品的创建。
  • 客户端通过调用工厂接口的方法来创建对象,具体实例化的过程由具体子类决定。

核心类

  • 抽象产品(Abstract Product):抽象产品类,定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法
  • 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性
  • 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
  • 具体工厂(Concrete Factory):负责实际创建具体产品的对象

4.2 优缺点

优点:

  • 符合开闭原则,新增产品时无需修改已有代码,只需添加新的工厂和产品类。
  • 避免了简单工厂模式的缺点,将创建过程分散到具体子类中。

缺点:

  • 客户端需要知道所使用的具体工厂,存在一定的耦合。

4.3 抽象工厂(Abstract Factory)

/**
 * 抽象工厂(Abstract Factory)
 * @Author lcy
 * @Date 2021/7/20 10:10
 */
public interface MethodPenFactory {

    /**
     * 生产
     * @return com.lcy.study.design.factory.Car
     * @author lcy
     * @date 2021/7/20 10:11
     **/
    Pen factory();

}

4.4 具体工厂(Concrete Factory)

/**
 * 简单工厂模式
 * @Author lcy
 * @Date 2021/7/20 10:10
 */
public class PencilFactory implements MethodPenFactory {

    /**
     * 生产铅笔
     * @return com.lcy.study.design.factory.Pen
     * @author lcy
     * @date 2021/7/20 10:11
     **/
    @Override
    public Pen factory(){
        return new FountainPen();
    }

}
/**
 * 简单工厂模式
 * @Author lcy
 * @Date 2021/7/20 10:10
 */
public class FountainPenFactory implements MethodPenFactory {

    /**
     * 生产钢笔
     * @return com.lcy.study.design.factory.Pen
     * @author lcy
     * @date 2021/7/20 10:11
     **/
    @Override
    public Pen factory(){
        return new Pencil();
    }

}

五、抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)用于创建一系列相关或依赖的对象,而无需指定其具体类。抽象工厂模式是工厂方法模式的推广,它关注一族产品的创建,而不仅仅是一个单一产品。

5.1 特点

  • 引入了抽象工厂接口和抽象产品接口,具体工厂子类负责实现这两个接口。
  • 一个抽象工厂可以创建一族相关的产品,而不仅仅是一个。

核心类

  • 抽象工厂接口(Abstract Factory): 声明了创建一族产品的方法,每个方法对应一种产品。
  • 具体工厂类(Concrete Factory): 实现了抽象工厂接口,负责创建一族相关的产品。
  • 抽象产品接口(Abstract Product): 声明了一类产品的通用接口。
  • 具体产品类(Concrete Product): 实现了抽象产品接口,是抽象工厂创建的具体产品。

5.2 优缺点

优点:

  • 符合开闭原则,新增产品族时无需修改已有代码,只需添加新的工厂和产品类。
  • 客户端代码与具体工厂和产品的耦合程度低,更易于替换和扩展。

缺点:

  • 新增产品族时,需要修改抽象工厂接口和所有具体工厂的实现。

5.3 抽象产品(Abstract Product)

新增抽象产品

/**
 * 颜色
 * @Author lcy
 * @Date 2021/7/20 12:00
 */
public interface Color {

    /**
     * 获取颜色
     * @return java.lang.String
     * @author lcy
     * @date 2021/7/20 12:01
     **/
    String getColor();

}

5.4 具体产品(Concrete Product)

新增具体产品

/**
 * 红色
 * @Author lcy
 * @Date 2021/7/20 12:01
 */
public class RedColor implements Color {

    @Override public String getColor(){
        return "red";
    }
}
/**
 * 蓝色
 * @Author lcy
 * @Date 2021/7/20 12:01
 */
public class BlueColor implements Color{

    @Override public String getColor(){
        return "blue";
    }
}

5.5 抽象工厂(Abstract Factory)

抽象工厂升级

/**
 * 抽象工厂
 * @Author lcy
 * @Date 2021/7/20 11:50
 */
public interface AbstractPenFactory {

    /**
     * 获取产品名称
     * @param type 汽车品牌
     * @return java.lang.String
     * @author lcy
     * @date 2021/7/20 11:55
     **/
    default Pen getProductName(String type){
        return null;
    }

    /**
     * 颜色
     * @param color 颜色
     * @return com.lcy.study.design.factory.Color
     * @author lcy
     * @date 2021/7/20 11:55
     **/
    default Color getColor(String color){
        return null;
    }

}

5.6 具体工厂(Concrete Factory)

/**
 * 颜色工厂
 * @Author lcy
 * @Date 2021/7/20 11:56
 */
public class PenColorFactory implements AbstractPenFactory {

    @Override public Color getColor(String color){
        switch (color) {
            case "red":
                return new RedColor();
            case "blue":
                return new BlueColor();
            default:
                return null;
        }
    }
}
/**
 * 笔工厂类
 * @Author lcy
 * @Date 2021/7/20 11:56
 */
public class PenProductFactory implements AbstractPenFactory {

    @Override public Pen getProductName(String type){
        return switch (type) {
            case "FountainPen" -> new FountainPen();
            case "Pencil" -> new Pencil();
            default -> null;
        };
    }
}

5.7 工厂提供者

/**
 * 工厂提供者
 * @Author lcy
 * @Date 2021/7/20 12:21
 */
public class FactoryProduct {

    public static AbstractPenFactory getFactory(String factory){
        switch (factory) {
            case "color":
                return new PenColorFactory();
            case "pen":
                return new PenProductFactory();
            default:
                return null;
        }
    }
}