我阅读了这个主题以及关于如何使用工厂模式的说明
我的工厂里有这个
public class FilterFactory {
static Map<String, Class> creators;
static {
creators = new HashMap<>();
}
/*...*/
}这是其中一个课程,我想把它放在工厂里
public class ExtentionFilterSerializer implements FilterSerializer {
static {
FilterFactory.creators.put(".", ExtentionFilterSerializer.class);
}
/*...*/
}当我试图在程序中使用工厂时,我看到Map是空的。我做错什么了?
发布于 2017-04-06 08:31:07
与代码相关的:
只有在类路径上实现此单元ExtentionFilterSerializer时,注册类ExtentionFilterSerializer的静态块才会执行。如果您没有在程序中的任何地方使用这个类ExtentionFilterSerializer,那么这个类将不会被加载,因此是静态注册。
将Class.forname("ExtentionFilterSerializer")添加到客户端应用程序将修复加载问题。
关于使用的方法的:
使用工厂模式的目的是确定和创建一个具体对象类型的实例,特别是当应用程序在编译时无法确定该实例时。通过添加静态初始化器来动态注册具体类,工厂知道它的存在,但仍然无法确定要使用哪个具体类。
此外,注册部分FilterFactory.creators.put(".", ExtentionFilterSerializer.class);不应该在ExtentionFilterSerializer中,而是在客户端程序中。
工厂设计模式的另一个变体使创建方法变得抽象(与AbstractFactory模式不同)。可以使用这些具体的Factory类创建一个具体的对象,这些类看起来与您的情况非常接近。读这。
发布于 2017-04-06 08:36:39
static块(至少在我的经验中)在执行方面不太可靠。您无法直接控制何时执行static块的ExtentionFilterSerializer。
我更希望实现一个init()方法,这样您就可以显式地调用ExtentionFilterSerializer.init() (甚至可以添加一个参数来告诉应该将这个工厂添加到哪个工厂中)。
我刚刚使用了类似的构造,static块非常不可靠,因此我将它们放置在一个被称为早期的受控init()函数中。从现在开始,您可以确保您的工厂和ExtentionFilterSerializer已正确初始化。
编辑:我下面的文章详细解释了发生了什么。要么实现一个init(),要么确保您的类确实在某个地方。
https://stackoverflow.com/questions/43249693
复制相似问题