ここで説明されているように(例を使用して)Factoryパターンについて明確にしようとしています: http://www.oodesign.com/factory-pattern.html
「リフレクションなしのクラス登録」の例を実装しようとすると、null ポインター例外が発生します。これは、ここで説明されているものと同じです。
クラス登録を伴うファクトリ メソッド パターンが nullpointer 例外を生成する
Null ポインター例外が発生する理由 (HashMap が使用されるまでにデータが取り込まれていない) を理解しており、 Factory実装内のメインブロックまたは静的ブロックでclass.forNameを使用して修正できることを知っています。
しかし、それはこのパターンを使用する目的を無効にしませんか? 作成中のオブジェクトが登録を行ったという考えだと思いました-静的ブロックを強制的に実行するためにクラスを手動でロードする必要がある場合、これはOpen Close Principleに違反しませんか?
コード例は次のとおりです。
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");
}
}
前述のように、これを機能させるには、これを Main または WidgetFactory クラスに配置します。
static {
try {
Class.forName(WidgetA.class.getName());
Class.forName(WidgetB.class.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace(System.err);
}
}
繰り返しになりますが、新しい Widget サブクラスが追加されるたびに Main クラスまたは WidgetFactory クラスを更新することなく、このパターンをどのように実装するか、またはこのパターンを機能させるためのテクニックを共有してください。
ご協力ありがとうございました!