我试图澄清工厂模式,如下所述(带有示例): http ://www.oodesign.com/factory-pattern.html
当我尝试实现“没有反射的类注册”示例时,我得到一个空指针异常。这与此处描述的相同:
我理解为什么会出现空指针异常(HashMap 在使用时未填充),并且我知道我可以通过在工厂实现中的main或静态块中使用class.forName来修复它。
但这不是违背了使用这种模式的目的吗?我认为这个想法是创建的对象进行了注册 - 如果您被迫手动加载类以强制静态块运行,这是否违反了打开关闭原则?
这是示例代码:
主.java
public class Main {
public static void main(String[] args) {
Widget widgetA = WidgetFactory.getInstance().createWidget("WidgetA");
Widget widgetB = WidgetFactory.getInstance().createWidget("WidgetB");
widgetA.doSomething();
widgetB.doSomething();
}
}
小部件.java
public abstract class Widget {
protected abstract Widget createWidget();
public abstract void doSomething();
}
小部件工厂.java
public class WidgetFactory {
private static WidgetFactory instance;
public static synchronized WidgetFactory getInstance() {
if (instance == null) {
instance = new WidgetFactory();
}
return instance;
}
private HashMap<String, Widget> widgets = new HashMap<>();
public void registerWidget(String id, Widget widget) {
widgets.put(id, widget);
}
public Widget createWidget(String id) {
Widget widget = widgets.get(id).create();
return widget;
}
}
小部件A.java
public class WidgetA extends Widget {
static {
WidgetFactory.getInstance().registerWidget("WidgetA", new WidgetA());
}
@Override
protected Widget createWidget() {
return new WidgetA();
}
@Override
public void doSomething() {
System.out.println("WidgetA");
}
}
WidgetB.java
public class WidgetB extends Widget {
static {
WidgetFactory.getInstance().registerWidget("WidgetB", new WidgetB());
}
@Override
protected Widget createWidget() {
return new WidgetB();
}
@Override
public void doSomething() {
System.out.println("WidgetB");
}
}
如前所述,为了让它工作,我可以把它放在 Main 或 WidgetFactory 类中:
static {
try {
Class.forName(WidgetA.class.getName());
Class.forName(WidgetB.class.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace(System.err);
}
}
再次,有人可以澄清一下这个模式应该如何实现或分享一种技术来使这个模式工作,而不必在每次添加新的 Widget 子类时更新 Main 或 WidgetFactory 类?
谢谢您的帮助!