Menu
CoddyTech

工厂模式

本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 66 课,共 87 课。

工厂模式是一种创建型设计模式,它将对象创建委托给单独的方法或类。你不必在代码中直接使用 new,而是让工厂为你创建对象。当你有多个共享同一接口或父类的相关类时,这种模式尤其有用。

设想一个可以发送电子邮件、SMS 或推送通知的通知系统。如果没有工厂,你的代码就需要了解每个具体类:

// 不使用工厂时,客户端必须知道所有具体类
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

使用工厂模式,可以集中管理创建逻辑:

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

现在客户端代码更简洁了,也不依赖具体类:

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // 输出:Email: Hello!

主要优势在于,添加新的通知类型只需要更新工厂:客户端代码保持不变。这遵循面向接口编程的原则,让你的系统更灵活,也更容易扩展。

challenge icon

挑战

简单

让我们使用工厂模式构建一个图形绘制系统!你不用在代码中到处直接创建图形对象,而是将创建逻辑集中到一个工厂中,由它根据简单的字符串标识符创建不同类型的图形。

你将把代码分成 4 个文件:

  • Shape.java:定义一个名为 Shape 的接口,作为所有图形的通用约定。接口应声明一个 draw() 方法,该方法不返回任何内容,只打印正在绘制的图形信息。
  • Shapes.java:创建 3 个实现 Shape 接口的类:

    Circle:它的 draw() 方法应打印 Drawing a Circle

    Rectangle:它的 draw() 方法应打印 Drawing a Rectangle

    Triangle:它的 draw() 方法应打印 Drawing a Triangle

  • ShapeFactory.java:创建负责处理图形创建的工厂类。你的 ShapeFactory 应有一个静态方法 createShape(String type),该方法返回一个 Shape。根据参数 type:
    • 如果 type 等于 "circle",则返回一个新的 Circle
    • 如果 type 等于 "rectangle",则返回一个新的 Rectangle
    • 如果 type 等于 "triangle",则返回一个新的 Triangle
    • 对于其他任何值,返回 null
  • Main.java:将工厂系统组合起来!你会收到两个输入:两个图形类型(都是字符串)。

    对于每个输入,使用 ShapeFactory 创建图形,并将其存储在一个 Shape 变量中。如果工厂返回有效的图形(不是 null),就调用它的 draw() 方法。如果返回 null,就打印 Unknown shape: [type],其中 [type] 是提供的输入。

    按顺序处理两个输入,每个输入的输出各占一行。

你会按顺序收到两个输入:第一个图形类型(字符串)和第二个图形类型(字符串)。

注意,Main 类从不直接使用 new Circle() 或 new Rectangle()。它只了解 Shape 接口,并请求工厂创建对象。这就是工厂模式的强大之处:客户端代码与具体类解耦了!

亲手试试

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取两种形状类型
        String type1 = scanner.nextLine();
        String type2 = scanner.nextLine();
        
        // TODO:使用 ShapeFactory 创建第一个形状
        // 如果形状不为 null,就调用 draw()
        // 如果形状为 null,就打印 "Unknown shape: [type]"
        
        // TODO:对第二个形状执行相同操作
        
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Java 在线编译器