跳转至

Java 中的工厂方法模式示例解析

简介

在 Java 编程中,设计模式是解决常见软件设计问题的通用解决方案。工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种创建对象的方式,将对象的创建和使用分离。通过使用工厂方法模式,可以提高代码的可维护性、可扩展性以及可测试性。本文将深入探讨工厂方法模式在 Java 中的概念、使用方法、常见实践以及最佳实践,并提供详细的代码示例。

目录

  1. 基础概念
  2. 使用方法
    • 简单工厂方法示例
    • 工厂方法模式结构
  3. 常见实践
    • 基于配置文件的对象创建
    • 根据不同条件创建对象
  4. 最佳实践
    • 单一职责原则遵循
    • 与其他设计模式结合
  5. 小结
  6. 参考资料

基础概念

工厂方法模式定义了一个创建对象的接口,让子类决定实例化哪个类。工厂方法把对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象。这样做的好处是,如果需要创建新的对象类型,只需要在工厂类中添加新的创建逻辑,而不需要修改大量的客户端代码。

使用方法

简单工厂方法示例

假设我们有一个图形绘制系统,需要绘制不同类型的图形,如圆形和矩形。我们可以创建一个简单的工厂方法来创建这些图形对象。

首先,定义图形接口 Shape

public interface Shape {
    void draw();
}

然后,实现具体的图形类 CircleRectangle

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle");
    }
}

接着,创建一个工厂类 ShapeFactory 来创建图形对象:

public class ShapeFactory {
    public Shape createShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        }
        return null;
    }
}

最后,在客户端代码中使用工厂方法创建图形对象:

public class Main {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactory();
        Shape circle = factory.createShape("CIRCLE");
        Shape rectangle = factory.createShape("RECTANGLE");

        if (circle != null) {
            circle.draw();
        }
        if (rectangle != null) {
            rectangle.draw();
        }
    }
}

工厂方法模式结构

上述示例展示了简单工厂方法的使用,但严格意义上的工厂方法模式更加灵活和可扩展。它包含以下几个角色: - 产品(Product):定义了产品的接口或抽象类,如上述示例中的 Shape 接口。 - 具体产品(Concrete Product):实现了产品接口的具体类,如 CircleRectangle。 - 工厂(Creator):定义了创建产品的抽象方法,如 createShape 方法在一个抽象类中声明。 - 具体工厂(Concrete Creator):实现了工厂抽象方法,创建具体产品对象的类。

改进后的工厂方法模式示例如下:

定义抽象工厂类 ShapeCreator

public abstract class ShapeCreator {
    public abstract Shape createShape();
}

具体工厂类 CircleCreatorRectangleCreator

public class CircleCreator extends ShapeCreator {
    @Override
    public Shape createShape() {
        return new Circle();
    }
}

public class RectangleCreator extends ShapeCreator {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }
}

客户端代码使用:

public class Main {
    public static void main(String[] args) {
        ShapeCreator circleCreator = new CircleCreator();
        Shape circle = circleCreator.createShape();
        circle.draw();

        ShapeCreator rectangleCreator = new RectangleCreator();
        Shape rectangle = rectangleCreator.createShape();
        rectangle.draw();
    }
}

常见实践

基于配置文件的对象创建

在实际项目中,我们可能希望根据配置文件来决定创建哪种类型的对象。例如,使用 properties 文件来配置要创建的图形类型。

首先,创建一个 config.properties 文件:

shape=RECTANGLE

然后,修改 ShapeFactory 类来读取配置文件:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class ShapeFactory {
    public Shape createShape() {
        Properties properties = new Properties();
        try (FileInputStream fis = new FileInputStream("config.properties")) {
            properties.load(fis);
            String shapeType = properties.getProperty("shape");
            if (shapeType == null) {
                return null;
            }
            if (shapeType.equalsIgnoreCase("CIRCLE")) {
                return new Circle();
            } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
                return new Rectangle();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

根据不同条件创建对象

在某些情况下,我们需要根据运行时的条件来创建不同类型的对象。例如,根据用户的权限创建不同级别的用户对象。

定义用户接口 User

public interface User {
    void showPermissions();
}

具体用户类 AdminUserRegularUser

public class AdminUser implements User {
    @Override
    public void showPermissions() {
        System.out.println("Admin has all permissions");
    }
}

public class RegularUser implements User {
    @Override
    public void showPermissions() {
        System.out.println("Regular user has limited permissions");
    }
}

创建用户工厂类 UserFactory

public class UserFactory {
    public User createUser(String role) {
        if (role == null) {
            return null;
        }
        if (role.equalsIgnoreCase("ADMIN")) {
            return new AdminUser();
        } else if (role.equalsIgnoreCase("REGULAR")) {
            return new RegularUser();
        }
        return null;
    }
}

最佳实践

单一职责原则遵循

工厂类应该只负责对象的创建,而不应该承担过多的业务逻辑。这样可以确保代码的单一职责原则,提高代码的可维护性。例如,ShapeFactory 类只专注于创建 Shape 对象,而不涉及图形绘制的具体逻辑。

与其他设计模式结合

工厂方法模式可以与其他设计模式结合使用,以实现更强大的功能。例如,与单例模式结合,可以确保创建的对象是单例的;与策略模式结合,可以根据不同的策略创建不同的对象。

小结

工厂方法模式是 Java 编程中一种非常有用的创建型设计模式。通过将对象的创建和使用分离,它提高了代码的可维护性和可扩展性。本文介绍了工厂方法模式的基础概念、使用方法、常见实践以及最佳实践,并提供了详细的代码示例。希望读者通过阅读本文,能够深入理解并在实际项目中高效使用工厂方法模式。

参考资料

  • 《Effective Java》 by Joshua Bloch
  • 《Design Patterns - Elements of Reusable Object-Oriented Software》 by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
  • Oracle Java Documentation