使用工厂模式时,如何保护混凝土子类的实例化



我有一个抽象类Employee,带有两个具体的子类MinorEmployeeAdultEmployee。我知道如何在Employee中创建静态工厂方法,该方法实例化混凝土子类的实例:

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

Java中是否有一种方法可以防止同一软件包中的呼叫者直接实例化MinorEmployeeAdultEmployee

我无法将其构造函数私有化,或者Employee无法访问它们。我也不想将它们嵌套在Employee中。

我可以给您提示您可以尝试的东西,尽管可能有一些警告:

  • 创建一个单独的工厂类,而不是基类。

  • 在工厂类中将构造函数私有化

  • 实例化工厂类中的虚拟私人对象

  • MinorEmployeeAdultEmployee的构造器接受出厂类的对象。由于由于私人构造函数,工厂的对象不能外面存在,因此实际上没有其他人可以从外部实例化这些类。

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

您可以将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
    }
}    

另一种方法是:

您可以将构造函数私有化,并使用辅助方法来识别新实体的请求的到来。如果来自您想要的位置,请返回对象的新实例,您可以投掷并例外。

如何弄清Java中哪个类别称为方法?

最新更新