с обязательными полями - проверкой во время компиляции?
верхнеуровнево пробовал с annotation препроцессором - кажется можно такое сделать. Примеров в сети не находил. Если подскажете пример, было б здорово.
Что-то типа этого? Builder.of(requiredArg1, requiredArg2).optionalArg1().optinalArg2().build()
это ворк эраунд такой. а хотелось бы такое - стандартный кодогенерируемый билдер. имя метода = имя проперти. некоторые проперти билдера спец аннотацией. - пусть у reqProperty если builder.optionalProperty1(..).optionalProperty2().reqProperty(…).build() - не падает во время компиляции builder.optionalProperty1(..).optionalProperty2().build()- падает во время компиляции
минус этой штуки - нет обратной совместимости - те если параметр стновится обязательным (и он по факту задается в коде везде) - все это рушится во всей репе тк нужно сменить сигнатуру билдера Builder.of(requiredArg1)… -> Builder.of(requiredArg1, requiredArg2)
Звучит как что-то хорошее, придётся ведь пойти и починить, а не узнать на проде
ожидаем получить падение сборок именно тех мест, где обязательный паарамер по факту не задется. Проблема подхода Builder.of(requiredArg1, …) - всегда будет огромное количество мест типа таких: Builder.of(requiredArg1).requiredArg2(requiredArg2).build() /когда requiredArg2 еще по api не являетя обязательным) - корректно, но как только обьявим его таким - нужно много бестолковой работы по переделке на такое: Builder.of(requiredArg1, requiredArg2)
Если у вас часто меняется схема полей и их обязательность, то я бы перешел к валидации на позднем этапе и все поля билдера делать опциональными. В случае если делать кодгенерируемый билдер с проверкой во время компиляции, то это, на мой взгляд, ничем не отличается от Builder.of(requiredArg1, requiredArg2), так как вам компилятор сообщит что нужно выставить поле там, где его нужно выставить и обратить внимание на логику обьекта в этом в каждом конкретном месте. А если одно из полей стало необязательным, то сделать метод Builder.of(requiredArg1) для создания обьектов такого типа.
весь смысл как раз не падать там, где падать не нужно. Наверное проще пример - был обязательный, стал опциональным. Очевидно что ожидаемое поведение - все заводится у всех и не требует миграции в коде
Для решения ситуации добавил новый метод. Было Builder.of(req1, req2) {} а стало Builder.of(req1, req2) {} Builder.of(req2) {}
Builder.of(req1, req2) {} это кажется очень сложное решение - если на входе у нас req1, optional1, optional2…. и никакой информации кто был req2
Зачем делать метод Билдера, где статический конструкторский метод принимает опциональные аргументы? Смысл билдера?
согласен. вобщем-то как раз пытаюсь донести что этот самый вариант, который как раз вы предложили выше со статич методом - он не очень хорош.
Если я правильно понял запрос, нужна проверка на этапе компиляции, что у билдера будут вызваны сеттеры обязательных полей. Но проблема в том, что на этапе инициализации их может не быть, а билдер может передаваться по коду, и т.о. промежуток между созданием билдера и вызовом метода build() может быть любым (а build может не быть вызван и вовсе). Т.е. это требуется глобальный анализатор знающий весь контекст приложения, а не ограниченный, например, контекстом текущего метода - выглядит как перебор
на этапе компиляции там еще не будет вызовов. Все что доступо, насколько я понял - сам текст кода для анализа
Ну вот я создал билдер в одном методе и передал его дальше по коду, как планируете отслеживать контекст?
на самом деле кажется и это сложно но можно. только анализом конечно - куда передал - дальше смотреть где принимают и что делают
Кажется это проще решить путем покрытия кода тестами
А вот глобально отслеживать жизненный цикл билдера путем статического анализа - наверняка возможно в каком-то виде, но слишком сложно. Я бы предпочел поискать другой способ инициализации что ли
этим не управляю, к сож. Жц переменной определенно сложно и главное непонятно сколько тут еще подводных камней - посмотрим
а самим билдером управляете? можете сделать инициализацию билдера с параметрами? это и будут те самые обязательные параметры, без которых у вас не создастся билдер. если их состав изменится, то и конструктор изменится. только вот если конструктор будет из (String field1Value, String field2Value, String field3Value), и поменяется на (String field1Value, String field3Value, String field4Value), то на этапе компиляции ошибки не будет...
Идея в том, чтобы не отклониться от стандартного шаблона билдера. Есть ещё тн стэп-билдер, который отдает методы в определенном порядке. Его можно адаптировать, чтобы терминальный метод build() был доступен только после того как начнутся optional параметры после всех заданных required. Но генерировать его сложно + есть строгий порядок (может быть неудобным).
Обсуждают сегодня