Как построить абстрактные классы с помощью шаблона builder?
Это абстрактный класс, который у меня есть
public abstract class AbstractActionModel implements IActionModel{
public abstract void getModel();
public abstract void getAction();
}
Тогда я хочу использовать этот абстрактный класс, как показано ниже:
this.getActions().put("sth", AbstractActionModel.builder().action("sth").build());
Поскольку я не могу создать экземпляр абстрактного класса, шаблон builder не будет работать.Я также не знаю никаких альтернативных моделей для этого.
Примечание: также у меня нет знаний о классах, расширенных из этого базового класса.
1 ответ:
Если вы хотите написать конструктор без знания конкретных подклассов, вызывающий код должен будет предоставить информацию о том, какой подкласс создать - либо предоставив фактический объект класса, либо зарегистрировав набор классов с именами. Например:
public class Builders { public static abstract class AbstractActionModel { public abstract void getModel(); public abstract void getAction(); public abstract void setAction(String action); } public static class ConcreteActionModel extends AbstractActionModel { public void getModel() {}; public void getAction() {}; public void setAction(String action) {}; } public static class ModelBuilder { AbstractActionModel model; Map<String, Class<? extends AbstractActionModel>> register = new HashMap<String, Class<? extends AbstractActionModel>>(); public void register(String key, Class<? extends AbstractActionModel> c) {register.put("concrete", ConcreteActionModel.class);} public ModelBuilder choose(String key) throws InstantiationException, IllegalAccessException { model = register.get(key).newInstance(); return this; } public ModelBuilder action(String action) { model.setAction(action); return this; } public AbstractActionModel build() { return model; } } public static void main(String[] args) throws Exception { ModelBuilder mb = new ModelBuilder(); mb.register("concrete", ConcreteActionModel.class); mb.choose("concrete").action("sth").build(); } }
Обратите внимание, что абстрактный класс будет нуждаться в добавлении методов сеттера, чтобы конструктор мог обновить свойства, не зная конкретного подкласса.
В качестве альтернативы можно использовать отражение , чтобы проверьте подкласс и вызовите его методы.