猿问

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

我有一个Employee带有两个具体子类的抽象类,MinorEmployee并且AdultEmployee. 我知道如何在Employee实例化具体子类的实例中创建静态工厂方法:


public abstract class Employee() {

    public static Employee create(LocalTime birthdate) {

        if (/* omitted */) {

            return new MinorEmployee();

        } else {

            return new AdultEmployee();

        }

    }

}

Java中有没有办法防止同一个包中的调用者直接实例化 a MinorEmployeeor AdultEmployee?


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


紫衣仙女
浏览 270回答 3
3回答

皈依舞

我可以给你一些你可以尝试的提示,尽管可能有一些警告:创建一个单独的工厂类而不是基类。在工厂类中将构造函数设为私有在工厂类中实例化一个虚拟私有对象让MinorEmployeeandAdultEmployee的唯一构造函数接受工厂类的对象。由于私有构造函数,工厂对象不能存在于类之外,实际上没有其他人应该能够从外部实例化这些类。使用虚拟对象在您的工厂方法中传递。

尚方宝剑之说

另一种方法是:您可以将构造函数设为私有并使用辅助方法来识别新实体的请求来自何处。如果来自您想要的地方,则返回对象的新实例,否则您可以抛出异常。

holdtom

MinorEmployee您可以在和AdultEmployeeas中声明构造函数,private然后在您的工厂方法中使用反射:public static Employee create(LocalTime birthdate) {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; Class<? extends Employee> clazz;&nbsp; &nbsp; &nbsp; &nbsp; if (omitted) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clazz = MinorEmployee.class;&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clazz = AdultEmployee.class;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; Constructor<? extends Employee> cons = clazz.getConstructor();&nbsp; &nbsp; &nbsp; &nbsp; cons.setAccessible(true);&nbsp; &nbsp; &nbsp; &nbsp; return cons.newInstance();&nbsp; &nbsp; } catch (NoSuchMethodException | SecurityException&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | InstantiationException | IllegalAccessException&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | InvocationTargetException ex) {&nbsp; &nbsp; &nbsp; &nbsp; // handle the exception&nbsp; &nbsp; }}&nbsp; &nbsp;&nbsp;
随时随地看视频慕课网APP

相关分类

Java
我要回答