设计模式(2.1/23) - 工厂方法模式

27 阅读3分钟

工厂方法模式

1 概述

  • 工厂方法模式是一种创建型设计模式,它通过定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法模式让类的实例化推迟到子类中进行,从而使得父类与子类之间的关系更加灵活和易于扩展。

2 优缺点及应用场景

2.1 优点

  • 1)遵循开闭原则:新增产品时,只需添加新的具体产品类和相应的具体工厂类,无需修改现有代码。
  • 2)单一职责原则:每个具体工厂类负责创建对应的产品。
  • 3)提高灵活性:客户端通过抽象工厂接口创建产品,具体实现延迟到子类。

2.2 缺点

  • 1)增加复杂性:需要为每一种产品提供一个具体工厂类,类的数量会显著增加。
  • 2)类结构复杂:随着产品种类的增加,系统的类结构会变得复杂。

2.3 应用场景

  • 1)日志记录:日志可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志的位置。
  • 2)数据库访问:当用户不知道最终系统使用哪种数据库,或者数据库可能变化时。

3 结构

  • 1)抽象工厂(Creator):声明一个返回产品对象的工厂方法,该方法的返回类型是抽象产品类型。
  • 2)具体工厂(ConcreteCreator):实现工厂方法,返回具体产品实例。
  • 3)抽象产品(Product):定义产品的接口。
  • 4)具体产品(ConcreteProduct):实现抽象产品接口。

4 实现

4.1 UML 类图

工厂方法模式.jpg

4.2 代码示例

  • 以下是一个工厂方法模式的代码示例,以创建不同类型的图形对象为例:
// 为形状创建一个接口
interface Shape {
  void draw();
}

// 创建实现接口的实体类:正方形
class Square implements Shape {
  @Override
  public void draw() {
    System.out.println("Inside Square::draw() method.");
  }
}

// 创建实现接口的实体类:长方形
class Rectangle implements Shape {
  @Override
  public void draw() {
    System.out.println("Inside Rectangle::draw() method.");
  }
}

// 创建实现接口的实体类:圆形
class Circle implements Shape {
  @Override
  public void draw() {
    System.out.println("Inside Circle::draw() method.");
  }
}

// 抽象工厂类
abstract class ShapeFactory {
  public abstract Shape createShape();
}

// 具体工厂类:正方形工厂
class SquareFactory extends ShapeFactory {
  @Override
  public Shape createShape() {
    return new Square();
  }
}

// 具体工厂类:矩形工厂
class RectangleFactory extends ShapeFactory {
  @Override
  public Shape createShape() {
    return new Rectangle();
  }
}

// 具体工厂类:圆形工厂
class CircleFactory extends ShapeFactory {
  @Override
  public Shape createShape() {
    return new Circle();
  }
}

// 使用示例
public class FactoryMethodPatternDemo {
  public static void main(String[] args) {
    // 通过正方形工厂创建 Square 对象
    ShapeFactory squareFactory = new SquareFactory();
    Shape shape1 = squareFactory.createShape();
    // 调用 Square 的 draw 方法
    shape1.draw();

    // 通过矩形工厂创建 Rectangle 对象
    ShapeFactory rectangleFactory = new RectangleFactory();
    Shape shape2 = rectangleFactory.createShape();
    // 调用 Rectangle 的 draw 方法
    shape2.draw();

    // 通过圆形工厂创建 Circle 对象
    ShapeFactory circleFactory = new CircleFactory();
    Shape shape3 = circleFactory.createShape();
    // 调用 Circle 的 draw 方法
    shape3.draw();
  }
}
  • 执行程序,输出结果:
Inside Square::draw() method.
Inside Rectangle::draw() method.
Inside Circle::draw() method.

5 总结

  • 工厂方法模式通过定义一个创建对象的接口,将实例化推迟到子类中进行,从而实现了代码的灵活性和扩展性。它适用于产品种类较多且频繁变化的情况。与简单工厂模式相比,工厂方法模式更符合开闭原则和单一职责原则,但也带来了类数量增加和系统结构复杂的缺点。