工厂模式

96 阅读3分钟

工厂模式

工厂模式(Factory Pattern)是一种在软件工程中常用的创建型设计模式,它提供了一种创建对象的方式,同时隐藏创建逻辑,不是通过直接使用 new 运算符实例化对象。

工厂模式定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

例子:

  1. 汽车制造:你需要一辆汽车,只需从工厂提货,而不需要关心汽车的制造过程及其内部实现。
  2. Hibernate:更换数据库时,只需更改方言(Dialect)和数据库驱动(Driver),即可实现对不同数据库的切换。

工厂模式包含以下几个主要角色:

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

工厂方法模式流程:

  1. 定义产品接口

    • 创建一个产品接口,它定义了产品的公共方法。
  2. 创建具体产品类

    • 实现产品接口,创建多个具体产品类。
  3. 创建工厂类

    • 创建工厂,实现生产产品。
  4. 客户端使用

    • 客户端代码通过工厂接口来创建产品,无需知道具体产品类。

代码

package wnan.factory;

public  interface Shape {
    public abstract void draw();
}
package wnan.factory;

public class Circle implements Shape {
    @Override
    public void draw(){
        System.out.println("Circle::show");
    }
}
package wnan.factory;

public class Square implements Shape{
    @Override
    public void draw() {
        System.out.println("Square::draw ");
    }
}
package wnan.factory;

public class ShapeFactory  {
    public static Shape getShape(String shapeName) {
        return switch (shapeName.toLowerCase()) {
            case "circle" -> new Circle();
            case "square" -> new Square();
            default -> null;
        };
    }
}
package wnan.factory;

public class Client {
    public static void main(String[] args) {
        Shape circle = ShapeFactory.getShape("circle");
        circle.draw();

        Shape sqaure = ShapeFactory.getShape("square");
        sqaure.draw();
    }
}

image.png

分析

优点

  1. 调用者只需要知道对象的名称即可创建对象。
  2. 扩展性高,如果需要增加新产品,只需扩展一个工厂类即可。
  3. 屏蔽了产品的具体实现,调用者只关心产品的接口。

缺点

每次增加一个产品时,都需要增加一个具体类和对应的工厂,使系统中类的数量成倍增加,增加了系统的复杂度和具体类的依赖。

使用场景

  1. 日志记录:日志可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志的位置。
  2. 数据库访:当用户不知道最终系统使用哪种数据库,或者数据库可能变化时。
  3. 连接服务器的框架设计:需要支持 "POP3"、"IMAP"、"HTTP" 三种协议,可以将这三种协议作为产品类,共同实现一个接口。

注意事项

工厂模式适用于生成复杂对象的场景。如果对象较为简单,通过 new 即可完成创建,则不必使用工厂模式。使用工厂模式会引入一个工厂类,增加系统复杂度。

源码 design_pattern