使用工厂模式时如何保护具体子类的实例化?

How to protect instantiation of concrete subclasses when using factory pattern?

我有一个抽象的 class Employee 和两个具体的子 class,MinorEmployeeAdultEmployee。我知道如何在 Employee 中创建一个静态工厂方法来实例化一个具体子 class:

的实例
public abstract class Employee() {
    public static Employee create(LocalTime birthdate) {
        if (/* omitted */) {
            return new MinorEmployee();
        } else {
            return new AdultEmployee();
        }
    }
}

Java 中有没有一种方法可以防止同一包中的调用者直接实例化 MinorEmployeeAdultEmployee

我不能将它们的构造函数设为私有,否则 Employee 将无法访问它们。我也不想将它们嵌套在 Employee.

我可以给你一些你可以尝试的提示,尽管可能会有一些注意事项:

  • 创建一个单独的工厂 class 而不是基础 class。

  • 在工厂中将构造函数设为私有 class

  • 在工厂中实例化一个虚拟私有对象class

  • MinorEmployeeAdultEmployee 的唯一构造函数接受工厂 class 的对象。由于私有构造函数,工厂对象不能存在于 class 之外,实际上没有其他人应该能够从外部实例化那些 classes。

  • 在你的工厂方法中使用虚拟对象传递。

您可以将 MinorEmployeeAdultEmployee 中的构造函数声明为 private,然后在您的工厂方法中使用反射:

public static Employee create(LocalTime birthdate) {
    try {
        Class<? extends Employee> clazz;
        if (omitted) {
            clazz = MinorEmployee.class;
        } else {
            clazz = AdultEmployee.class;
        }
        Constructor<? extends Employee> cons = clazz.getConstructor();
        cons.setAccessible(true);
        return cons.newInstance();
    } catch (NoSuchMethodException | SecurityException
            | InstantiationException | IllegalAccessException
            | InvocationTargetException ex) {
        // handle the exception
    }
}    

另一种方式是:

您可以将构造函数设为私有,并使用辅助方法来识别新实体的请求来自何处。如果来自您想要的地方,return 其他对象的新实例,您可以抛出异常。

how to figure out what class called a method in java?