简体   繁体   English

实现工厂模式java的错误

[英]Mistakes in realization of factory pattern java

I've read this topic with the instruction about how to use factory pattern 我已经阅读了有关如何使用工厂模式的说明
factory pattern dynamic approach 工厂模式动态方法

I have this in my factory 我在工厂里有这个

public class FilterFactory {
    static Map<String, Class> creators;

    static {
        creators = new HashMap<>();
    }
    /*...*/
}

And this is one of the classes, which I want to put in the factory 这是我想把它放在工厂里的一个类

public class ExtentionFilterSerializer implements FilterSerializer {
    static {
            FilterFactory.creators.put(".", ExtentionFilterSerializer.class);
    }
    /*...*/
}

When I try to use factory in the program, I see that Map is empty. 当我尝试在程序中使用工厂时,我看到Map是空的。 What did I do wrong? 我做错了什么?

For code related: 对于相关的代码:

The static block to register your class ExtentionFilterSerializer will execute if only if this unit ExtentionFilterSerializer is realized on classpath. 只有在类路径上实现此单元ExtentionFilterSerializer才会执行注册ExtentionFilterSerializer类的静态块。 If you haven't used this class ExtentionFilterSerializer anywhere in your program, this class wont be loaded, hence the static registration. 如果您没有在程序中的任何位置使用此类ExtentionFilterSerializer ,则不会加载此类,因此静态注册。

Adding a Class.forname("ExtentionFilterSerializer") to your client application will fix the load issue. Class.forname("ExtentionFilterSerializer")到客户端应用程序将解决加载问题。

Regarding approach used: 关于使用的方法:

The objective of using a Factory pattern is to determine and create an instance of concrete object type especially when the application cannot determine that at compile time. 使用Factory模式的目的是确定并创建具体对象类型的实例,尤其是当应用程序无法在编译时确定时。 By adding a static initializer to dynamically register your concrete class, your Factory know of its existence, but still cannot determine which concrete class to use. 通过添加静态初始化程序来动态注册您的具体类,您的工厂知道它的存在,但仍然无法确定要使用哪个具体类。

Besides, the registration part FilterFactory.creators.put(".", ExtentionFilterSerializer.class); 另外,注册部分FilterFactory.creators.put(".", ExtentionFilterSerializer.class); should never be in ExtentionFilterSerializer , but in a client program. 永远不应该在ExtentionFilterSerializer ,而应该在客户端程序中。

Another variant of a Factory design pattern makes the creation method abstract (not same as AbstractFactory pattern). Factory设计模式的另一种变体使创建方法成为抽象(与AbstractFactory模式不同)。 A concrete object can be created using those concrete Factory classes, which looks close to your case. 可以使用那些看起来与您的案例接近的具体Factory类创建具体对象。 Read this . 这个

static blocks are (at least in my experience) not very reliable in terms of execution. static块(至少在我的经验中)在执行方面不是很可靠。 You have no direct control over when the static block of ExtentionFilterSerializer is executed. 您无法直接控制何时执行ExtentionFilterSerializerstatic块。

I'd rather implement an init() method, so you can explicitly call ExtentionFilterSerializer.init() (maybe even add an argument telling the method to which factory this one should be added). 我宁愿实现一个init()方法,所以你可以显式调用ExtentionFilterSerializer.init() (甚至可以添加一个参数来告诉方法应该添加哪个工厂)。

I just worked with a similar construction and static blocks were very unreliable resulting in me placing them in a controlled init() function, which is called early. 我刚刚使用了类似的构造, static块非常不可靠,导致我将它们放在一个受控的init()函数中,这个函数被称为早期版本。 From this point in time, you can be sure that your factory and your ExtentionFilterSerializer are properly initialized. 从这个时间点开始,您可以确保正确初始化了工厂和ExtentionFilterSerializer

Edit: Post below me explains in detail what happens. 编辑:我下面的帖子详细解释了会发生什么。 Either implement a init() or make sure your class is actually somewhere. 要么实现init()要么确保你的类实际上在某个地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM