Я хотел бы создать Abstract Builder с динамическим выбором реализации. Моя попытка была:
1. Создание интерфейса для моего строителя:
public interface JSONFormatterAbstractBuilder {
Object format(Object object);
}
2. Создайте статический список строителей, чтобы получить правильного строителя для работы:
public abstract class BuilderMap {
private static Map<Class<?>, JSONFormatterBuilder> builderMap = new HashMap<>();
public static JSONFormatterBuilder getBuilder(Class<?> classOfObjectToBeFormatted) {
return builderMap.get(classOfObjectToBeFormatted);
}
public static boolean hasBuilder(Class<?> classOfObjectToBeFormatted) {
return builderMap.containsKey(classOfObjectToBeFormatted);
}
public static JSONFormatterBuilder setBuilder(Class<?> baseObjectClass,
JSONFormatterBuilder builder) {
return (JSONFormatterBuilder) builderMap.put(baseObjectClass, builder);
}
}
3. Создайте класс, реализующий интерфейс компоновщика со статическим инициализатором, чтобы добавить экземпляр в список реализаций компоновщика:
public class BooleanOptBuilder implements JSONFormatterBuilder {
private static BooleanOptBuilder instance = new BooleanOptBuilder();
private BooleanOptBuilder() {}
public static BooleanOptBuilder getInstance() {
return instance;
}
static {
//The static initializer to add the instance to the list of implementations
BuilderMap.setBuilder(boolean_opt_t.class, instance);
}
@Override
public Object format(Object raw) {
if(!(raw instanceof boolean_opt_t))
throw new InputMismatchException("Expecting boolean_opt_t, found : "+raw.getClass().getCanonicalName());
boolean_opt_t object = (boolean_opt_t) raw;
//Does the work ...
}
}
4. Извлечение основного для того, как я намеревался использовать строитель
boolean_opt_t booleanOptObject;
//Initialization of the variable
JSONFormatterBuilder builder = BuilderMap.getBuilder(boolean_opt_t.class);
Object o = builder.format(booleanOptObject);
Я сделал это таким образом, чтобы использовать в каскаде и динамически правильную фабрику в рамках исполнения компоновщика. И далее, я хотел бы добавить новых компоновщиков на карту, просто поместив их в путь к классам, например, через зависимость Maven (поэтому статический инициализатор в BuilderMap, перечисляющий все существующие компоновщики, исключен, потому что для добавления нового компоновщика вы будетенеобходимо изменить класс BuilderMap).
Но, когда я пытаюсь использовать BuilderList, содержимое становится пустым, для того типа, который я спросил. Я думаю, что класс этого компоновщика не загружается, когда я пытаюсь вызвать метод «format», поэтому карта компоновщиков не заполняется. И фрагмент кода не работает, выбрасывая исключение NullPointerException для builder.format(..)
.
Поэтому у меня есть несколько вопросов к моему сообщению:
- Является ли моя реализация правильным способомделать то, что я хочу?
- Если нет, как мне поступить?
- А как мне вручную вызывать загрузку классов?
Заранее спасибо.