Расширение класса Builder - PullRequest
0 голосов
/ 13 июня 2019

Я хочу реализовать шаблон проектирования, в котором я устанавливаю базовый класс построителя (BaseBuilder.java), который расширяют несколько других классов построителя.

Базовый класс построителя является абстрактным и содержит значения, которые являются общими для других построителей. У каждого строителя есть общие элементы, а также уникальные элементы.

Пример класса BaseBuilder-

public class BaseBuilder {

    private final String key;
    private final String token;

    public BaseBuilder(Builder<?> builder) {
        this.key = builder.key;
        this.token = builder.token;
    }

    @Override
    public String toString() {
        return "Builder {" +
            ", key='" + key + '\'' +
            ", token='" + token + '\'' +
            '}';
    }

    public abstract static class Builder<T extends Builder <T>> {

        private String key;
        private String token;

        public Builder setKey(String key) {
            this.key = key;
            return this;
        }

        public Builder setToken(String token) {
            this.token = token;
            return this;
        }

        public BaseBuilder build() {
            return new BaseBuilder(this);
        }
    }
}

Теперь я хотел бы расширить этот BaseBuilder для других сборщиков, например. RedCar.

public class RedCar extends BaseBuilder {

    private final String redWheelCaps;

    public RedCar(RedCardBuilder builder) {
        super(builder);
        this.redWheelCaps = builder.redWheelCaps;
    }

    @Override
    public String toString() {
        return "Red Car Builder {" +
            ", redWheelCaps='" + redWheelCaps + '\'' +
            '}';
    }

    public static class RedCardBuilder extends BaseBuilder<RedCardBuilder> {

        private String redWheelCaps;

        public RedCardBuilder setRedWheelCaps(String redWheelCaps) {
            this.redWheelCaps = redWheelCaps;
            return this;
        }


        public RedCar build() {
            return new RedCar(this);
        }
    }
}

При попытке использовать этот конструктор у меня возникают проблемы при попытке достичь следующих результатов.

// this is ideally what I want to achieve
// there is an error because I am not creating a BaseBuilder object
RedCar redCar = new RedCar.RedCarBuilder()
    .setKey("key")
    .setToken("token")
    .setRedWheelCaps("redCaps")
    .build();

Выше не работает. Мне подсказывают, что я должен использовать BaseBuilder. Поэтому я обновил свой код до следующего:

// this works good, but the order of my set values causes an error
BaseBuilder redCar = new RedCar.RedCarBuilder()
    .setKey("key")
    .setToken("token")
    .setRedWheelCaps("redCaps")
    .build();

Я был вынужден использовать полиморфизм. Что хорошо, однако, у меня все еще была ошибка, пока я не изменил порядок установки значений. По какой-то причине мне нужно сначала установить значения RedCar, прежде чем я смогу установить значения BaseBuilder. В противном случае я получаю ошибку, «не могу разрешить метод». Поэтому я переставил свои установленные значения, чтобы удалить все ошибки.

// no errors at all. This works fine but is not what I was expecting
BaseBuilder redCar = new RedCar.RedCarBuilder()
    .setRedWheelCaps("redCaps")
    .setKey("key")
    .setToken("token")
    .build();

Как я могу исправить свои настройки, чтобы я мог наследовать и устанавливать значения без необходимости соответствовать определенному порядку? И есть ли способ выполнить то, что я пытаюсь сделать, не используя полиморфизм? У меня есть правильная идея шаблона? Спасибо!

EDIT: Больше информации в том, что я могу достичь того, что ищу, так долго, что опускаю установщики из BaseBuilder. Итак, все в порядке.

RedCar redCar = new RedCar.RedCarBuilder()
    .setRedWheelCaps("redCaps")
    .build();

Почему мне не удается наследовать сеттеры от моего BaseBuilder?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...