170 похожих чатов

Всем привет. есть ли у кого успешный опыт реализации билдера

с обязательными полями - проверкой во время компиляции?
верхнеуровнево пробовал с annotation препроцессором - кажется можно такое сделать. Примеров в сети не находил. Если подскажете пример, было б здорово.

20 ответов

25 просмотров

Что-то типа этого? Builder.of(requiredArg1, requiredArg2).optionalArg1().optinalArg2().build()

Vasily-Shvets Автор вопроса
Akim Glushkov
Что-то типа этого? Builder.of(requiredArg1, requir...

это ворк эраунд такой. а хотелось бы такое - стандартный кодогенерируемый билдер. имя метода = имя проперти. некоторые проперти билдера спец аннотацией. - пусть у reqProperty если builder.optionalProperty1(..).optionalProperty2().reqProperty(…).build() - не падает во время компиляции builder.optionalProperty1(..).optionalProperty2().build()- падает во время компиляции

Vasily-Shvets Автор вопроса
Akim Glushkov
Что-то типа этого? Builder.of(requiredArg1, requir...

минус этой штуки - нет обратной совместимости - те если параметр стновится обязательным (и он по факту задается в коде везде) - все это рушится во всей репе тк нужно сменить сигнатуру билдера Builder.of(requiredArg1)… -> Builder.of(requiredArg1, requiredArg2)

Vasily Shvets
минус этой штуки - нет обратной совместимости - те...

Звучит как что-то хорошее, придётся ведь пойти и починить, а не узнать на проде

Vasily-Shvets Автор вопроса
Stanislav U.
Звучит как что-то хорошее, придётся ведь пойти и п...

ожидаем получить падение сборок именно тех мест, где обязательный паарамер по факту не задется. Проблема подхода Builder.of(requiredArg1, …) - всегда будет огромное количество мест типа таких: Builder.of(requiredArg1).requiredArg2(requiredArg2).build() /когда requiredArg2 еще по api не являетя обязательным) - корректно, но как только обьявим его таким - нужно много бестолковой работы по переделке на такое: Builder.of(requiredArg1, requiredArg2)

Vasily Shvets
ожидаем получить падение сборок именно тех мест, ...

Если у вас часто меняется схема полей и их обязательность, то я бы перешел к валидации на позднем этапе и все поля билдера делать опциональными. В случае если делать кодгенерируемый билдер с проверкой во время компиляции, то это, на мой взгляд, ничем не отличается от Builder.of(requiredArg1, requiredArg2), так как вам компилятор сообщит что нужно выставить поле там, где его нужно выставить и обратить внимание на логику обьекта в этом в каждом конкретном месте. А если одно из полей стало необязательным, то сделать метод Builder.of(requiredArg1) для создания обьектов такого типа.

Vasily-Shvets Автор вопроса
Akim Glushkov
Если у вас часто меняется схема полей и их обязате...

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

Для решения ситуации добавил новый метод. Было Builder.of(req1, req2) {} а стало Builder.of(req1, req2) {} Builder.of(req2) {}

Vasily-Shvets Автор вопроса
Akim Glushkov
Для решения ситуации добавил новый метод. Было Bu...

Builder.of(req1, req2) {} это кажется очень сложное решение - если на входе у нас req1, optional1, optional2…. и никакой информации кто был req2

Vasily Shvets
Builder.of(req1, req2) {} это кажется очень сложно...

Зачем делать метод Билдера, где статический конструкторский метод принимает опциональные аргументы? Смысл билдера?

Vasily-Shvets Автор вопроса
Akim Glushkov
Зачем делать метод Билдера, где статический констр...

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

Vasily Shvets
ожидаем получить падение сборок именно тех мест, ...

Если я правильно понял запрос, нужна проверка на этапе компиляции, что у билдера будут вызваны сеттеры обязательных полей. Но проблема в том, что на этапе инициализации их может не быть, а билдер может передаваться по коду, и т.о. промежуток между созданием билдера и вызовом метода build() может быть любым (а build может не быть вызван и вовсе). Т.е. это требуется глобальный анализатор знающий весь контекст приложения, а не ограниченный, например, контекстом текущего метода - выглядит как перебор

Vasily-Shvets Автор вопроса
Alex Verkhoglyad
Если я правильно понял запрос, нужна проверка на э...

на этапе компиляции там еще не будет вызовов. Все что доступо, насколько я понял - сам текст кода для анализа

Vasily Shvets
на этапе компиляции там еще не будет вызовов. Все ...

Ну вот я создал билдер в одном методе и передал его дальше по коду, как планируете отслеживать контекст?

Vasily-Shvets Автор вопроса
Alex Verkhoglyad
Ну вот я создал билдер в одном методе и передал ег...

на самом деле кажется и это сложно но можно. только анализом конечно - куда передал - дальше смотреть где принимают и что делают

Vasily Shvets
на самом деле кажется и это сложно но можно. тольк...

Кажется это проще решить путем покрытия кода тестами

Vasily Shvets
на самом деле кажется и это сложно но можно. тольк...

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

Vasily-Shvets Автор вопроса
Alex Verkhoglyad
Кажется это проще решить путем покрытия кода теста...

этим не управляю, к сож. Жц переменной определенно сложно и главное непонятно сколько тут еще подводных камней - посмотрим

Vasily Shvets
этим не управляю, к сож. Жц переменной определен...

а самим билдером управляете? можете сделать инициализацию билдера с параметрами? это и будут те самые обязательные параметры, без которых у вас не создастся билдер. если их состав изменится, то и конструктор изменится. только вот если конструктор будет из (String field1Value, String field2Value, String field3Value), и поменяется на (String field1Value, String field3Value, String field4Value), то на этапе компиляции ошибки не будет...

Vasily-Shvets Автор вопроса
Dmitriy Zanin
а самим билдером управляете? можете сделать инициа...

Идея в том, чтобы не отклониться от стандартного шаблона билдера. Есть ещё тн стэп-билдер, который отдает методы в определенном порядке. Его можно адаптировать, чтобы терминальный метод build() был доступен только после того как начнутся optional параметры после всех заданных required. Но генерировать его сложно + есть строгий порядок (может быть неудобным).

Похожие вопросы

Обсуждают сегодня

Скажите, можно ли как-то "переместить" динамический массив из одной переменной в другую? Скажем, переместить из TList<> в TArray<>. Именно переместить, а не скопировать. Если ...
Eugene Krasnikov (ᴊɪɴ x)
37
комрады, че-та лыжы не едут var tmpFont: TFont; begin tmpFont:= TFont.Create; try case rgFontColor.ItemIndex of 0: tmpFont.Color:= clWindowText; 1: tmpFo...
Ed Doc
34
Вот еще криповенькая штука. uMain.pas(517,3) Warning: Case statement does not handle all possible cases И ЧО? 😂
Александр (Rouse_) Багель
15
.model small .stack 100h .data a db 'Hello, World!', '$' ; исходная строка b db 20 dup(?) ; строка b с запасом на максимальную длину .code main: ...
Алексей -man
3
вопрос, кого посмотреть в ютубе или где почитать про указатели чтобы раз и навсегда запомнить зачем они нужны и как правильно ими пользоваться? поделитесь хорошими ресурсами, ...
-
14
М-да. Почему бы просто со stringlist не работать?
Michael Longneck
23
Интересно, нет ли какого-то способа получить из dll не адрес самой метки, а адрес со смещением?
The Bird of Hermes
54
Редактор листа Excel, по сути двумерный массив ячеек. Ячейка - это экземпляр класса, у нее всякие свойства, методы. Проблема в том, что количество используемых строк и колоно...
Sergey Bodrov
2
Is there a digital way to cut the electricity from a usb in linux? It sounds weird, but it's exactly what I need to do. I tried to simulate the unplug/replug but is not the ...
Eduard Rivas
15
Решаемо? У тебя есть софт собирающийся без хинтов ворнингов?
Александр (Rouse_) Багель
9
Карта сайта