03-工厂方法模式

工厂方法模式

工厂方法模式是对简单工厂模式的进一步抽象化,好处是可以是系统在不修改原有代码情况下引入新的产品,即满足开闭原则。

模式的结构与实现

简单工厂模式的主要角色:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
  • 具体工厂(Factory):主要实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(AbstractProduct):定义了产品的规范,描述了产品的主要特征和功能。
  • 具体产品(Product):实现抽象产品角色所定义的接口,由具体工厂来创建,和具体工厂一一对应。

UML类图

实例

需求:创建一个可以绘制不同形状的绘图工具,可以绘制圆形,正方形,三角形,每个图形都会有一个draw()方法用于绘图。

分析可知正方形,三角形,圆都有一个共同的draw方法,所以在它们的公共父类(AbstractProduct)里声明一个draw方法。
实现代码步骤如下:
  1. 创建产品顶层抽象类,定义具体产品的公共接口AbstractProduct
    1
    2
    3
    public interface AbstractProduct {
    void draw();
    }
  2. 创建具体的产品类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    //圆形产品
    public class CircleShape implements AbstractProduct {

    public CircleShape(){
    System.out.println("CircleShape created");
    }

    public void draw() {
    System.out.println("CircleShape 正在绘制圆形图案");
    }
    }
    //正方形产品
    public class RectShape implements AbstractProduct {

    public RectShape(){
    System.out.println("RectShape created");
    }

    public void draw() {
    System.out.println("RectShape 正在正方形图案");
    }
    }
    //三角形产品
    public class TriangleShape implements AbstractProduct {

    public TriangleShape(){
    System.out.println("TriangleShape created");
    }

    public void draw() {
    System.out.println("TriangleShape 正在绘制三角形图案");
    }
    }
  3. 创建抽象工厂类
    1
    2
    3
    public interface ShapeFactory {
    AbstractProduct getProduct();
    }
  4. 创建工厂实现类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class CircleShapeFactory implements ShapeFactory {
    public AbstractProduct getProduct() {
    return new CircleShape();
    }
    }
    public class RectShapeFactory implements ShapeFactory {

    public AbstractProduct getProduct() {
    return new RectShape();
    }
    }
    public class TriangleShapeFactory implements ShapeFactory {

    public AbstractProduct getProduct() {
    return new TriangleShape();
    }
    }
  5. client根据调用工厂类静态方法,通过不通参数创建不同的产品实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Client {

    public static void main(String[] args) {
    CircleShapeFactory circleShapeFactory = new CircleShapeFactory();
    AbstractProduct circleShapeFactoryProduct = circleShapeFactory.getProduct();
    circleShapeFactoryProduct.draw();
    RectShapeFactory rectShapeFactory = new RectShapeFactory();
    AbstractProduct rectShapeFactoryProduct = rectShapeFactory.getProduct();
    rectShapeFactoryProduct.draw();
    TriangleShapeFactory triangleShapeFactory = new TriangleShapeFactory();
    AbstractProduct triangleShapeFactoryProduct = triangleShapeFactory.getProduct();
    triangleShapeFactoryProduct.draw();
    }
    }
  6. 结果输出
1
2
3
4
5
6
CircleShape created
CircleShape 正在绘制圆形图案
RectShape created
RectShape 正在正方形图案
TriangleShape created
TriangleShape 正在绘制三角形图案

总结

优点

  • 只需要知道具体工厂的名称就可以得到所要的产品,无需知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个对应的工厂类。
  • 典型的解耦框架。

缺点

  • 类的个数增加,代码复杂度增加。
  • 系统抽象难度增加。
  • 一个抽象产品只能创建一种产品。

应用场景

  1. 客户只知道创建产品的工厂名,而不知道具体的产品名。
  2. 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
  3. 客户不关心创建产品的细节,只关心产品的品牌。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!