我试图描述(举例),以获得澄清周围的工厂模式在这里: http://www.oodesign.com/factory-pattern.html与抽象工厂模式澄清后
当我尝试实施“类注册,而不反思”例如我得到一个空指针例外。这是一样的已经在这里描述:
factory method pattern with class registration produces a nullpointer exception
我明白为什么我得到空指针异常(HashMap中没有被正在使用它的时候填充),我知道我可以修复它通过使用class.forName中的主要或在工厂执行的静态块中。
但是这并没有打破使用这种模式的目的?我认为这个想法是,创建的对象进行了注册 - 如果您不得不手动加载类来强制静态块运行,那么这是否违反了打开关闭原则?
下面是示例代码:
Main.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();
}
}
Widget.java
public abstract class Widget {
protected abstract Widget createWidget();
public abstract void doSomething();
}
WidgetFactory.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;
}
}
WidgetA.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");
}
}
正如前面提到的,要得到它的工作,我可以把这个在主或WidgetFactory类:
static {
try {
Class.forName(WidgetA.class.getName());
Class.forName(WidgetB.class.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace(System.err);
}
}
而且也可能有人请澄清应该如何实现这种模式或共享一种技术来使这种模式工作,而不必在每次添加新的Widget子类时更新Main或WidgetFactory类?
谢谢你的帮助!
查阅这些教程,他们帮助了我很多:[1](https://www.youtube.com/watch?v=ub0DXaeV6hA)] [[2](https://开头WWW。 youtube.com/watch?v=xbjAsdAK4xQ)] –
小部件名称是否总是与类名相同? – mmirwaldt
@MDD感谢您的链接。这些教程是有用的,但没有解决我的具体问题 - 在教程中,我试图避免在工厂类中使用if/else if/else结构。 – user2551913