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

Во первых - надо помнить что дизайн решения не виден

в моменте времени. дизайн оценивается при изменениях кода - если легко менять и поддерживать - значит дизайн хорош.
во вторых - надо заглянуть чуть дальше чем 6 или 7 кодов - пусть их будет 30, а лучше 300 - в таком случае иметь огромный свич уже больно. да даже на 30 пунктов - уже начинается мигрень. сейчас конечно их мало, но время идет и количество вырастет полюбому.

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

получается в не-самом-удобном кейсе каждый блок в структуре when будет иметь какую то свою функциональность. что получается:
1. метод в котором находится when разрастается
2. каждый блок кода обрастает своими зависимостями
3. как следствие - класс требует больше зависимостей

пусть например количество кейсов выросло до 30 - и LOC метода выросло до 1000

следующий этап рефакторинга - а давайте разнесем блоки кодов по отдельным методам класса - в целом идея неплохая и рабочая

но опять же - количество методов класса будет N (кодов) + 1 (when), и будет расти параллельно с новыми кодами ошибок

помимо прочего - растет и конструктор класса в который надо запихивать все больше зависимостей

взглянем на секунду в разрезе тестирования - чтобы протестировать практически голую стейт машину требуется сколько то там мокнутых зависимостей

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

можно подумать и придумать - а давайте просто будем добавлять эти конкретные классы хендлеров ошибок в конструктор основного класса, типа как
MyErrorHandler constructor( val Ahandler, val Bhandler, val Chandler)
отлично - вот только количество аргументов будет еще больше чем просто с
MyErrorHandler constructor( val Adep, val Bdep, val Cdep){
val a = Ahandler(Adep)
val b = Bhandler(Bdep)
val c = Chandler(Adep, Cdep)
...
}
все еще слишком много аргументов конструктора

идем еще дальше и рефакторим как список хендлеров с единым интерфейсом
MyErrorHandler constructor (val handlers: List<iHandler>)

fun onErrorCode(code){
for (handler in handlers){
if(handler.accept(code){ return }
}
throw Error("no handler for code $code")
}
и где то в di модуле этот список наполняется отдельными хендлерами

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

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

ну и конечно я бы тоже when сделал для небольшого количества кейсов. но как только почувствуется какое то нехорошее жжение в одном месте - сразу же надо рефакторить

2 ответов

26 просмотров

Подход с листом хэндлеров понятный, только не совсем понятно как соотносить хэндлер с кодом статуса, в методе accept у конкретного хэндлера делать проверку на то, равен ли приходящий статус задекларированному самим хэндлером?

Konstantin-dmz9 Автор вопроса
Руслан Иваныкин
Подход с листом хэндлеров понятный, только не совс...

это необязательно так у ошибок могут быть эмпирические правила например "код ошибки меньше 500 делаем это" "код выше 1000 делаем что то другое"

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

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

30500 за редактор? )
Владимир
47
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
1
Он в одиночку это дело запилил или была какая-то команда?
Aquinary
12
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Карта сайта