Как построить абстрактные классы с помощью шаблона 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 2

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();
    }
}

Обратите внимание, что абстрактный класс будет нуждаться в добавлении методов сеттера, чтобы конструктор мог обновить свойства, не зная конкретного подкласса.

В качестве альтернативы можно использовать отражение , чтобы проверьте подкласс и вызовите его методы.