使用工厂模式时如何保护具体子类的实例化?
How to protect instantiation of concrete subclasses when using factory pattern?
我有一个抽象的 class Employee
和两个具体的子 class,MinorEmployee
和 AdultEmployee
。我知道如何在 Employee
中创建一个静态工厂方法来实例化一个具体子 class:
的实例
public abstract class Employee() {
public static Employee create(LocalTime birthdate) {
if (/* omitted */) {
return new MinorEmployee();
} else {
return new AdultEmployee();
}
}
}
Java 中有没有一种方法可以防止同一包中的调用者直接实例化 MinorEmployee
或 AdultEmployee
?
我不能将它们的构造函数设为私有,否则 Employee
将无法访问它们。我也不想将它们嵌套在 Employee
.
中
我可以给你一些你可以尝试的提示,尽管可能会有一些注意事项:
创建一个单独的工厂 class 而不是基础 class。
在工厂中将构造函数设为私有 class
在工厂中实例化一个虚拟私有对象class
让 MinorEmployee
和 AdultEmployee
的唯一构造函数接受工厂 class 的对象。由于私有构造函数,工厂对象不能存在于 class 之外,实际上没有其他人应该能够从外部实例化那些 classes。
在你的工厂方法中使用虚拟对象传递。
您可以将 MinorEmployee
和 AdultEmployee
中的构造函数声明为 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?
我有一个抽象的 class Employee
和两个具体的子 class,MinorEmployee
和 AdultEmployee
。我知道如何在 Employee
中创建一个静态工厂方法来实例化一个具体子 class:
public abstract class Employee() {
public static Employee create(LocalTime birthdate) {
if (/* omitted */) {
return new MinorEmployee();
} else {
return new AdultEmployee();
}
}
}
Java 中有没有一种方法可以防止同一包中的调用者直接实例化 MinorEmployee
或 AdultEmployee
?
我不能将它们的构造函数设为私有,否则 Employee
将无法访问它们。我也不想将它们嵌套在 Employee
.
我可以给你一些你可以尝试的提示,尽管可能会有一些注意事项:
创建一个单独的工厂 class 而不是基础 class。
在工厂中将构造函数设为私有 class
在工厂中实例化一个虚拟私有对象class
让
MinorEmployee
和AdultEmployee
的唯一构造函数接受工厂 class 的对象。由于私有构造函数,工厂对象不能存在于 class 之外,实际上没有其他人应该能够从外部实例化那些 classes。在你的工厂方法中使用虚拟对象传递。
您可以将 MinorEmployee
和 AdultEmployee
中的构造函数声明为 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?