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 ответов

18 просмотров

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

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

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

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

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

Какой-то там пердун в 90-х решил, что есть какая-то разная типизация. Кого вообще это волнует?
КТ315
49
Подскажите, а есть vault lite или ченить такое?) А то нужен вольт для похода в вольт, но весит он ~500 мб) как-то многовато для парочки запросов ))
Alexandr Orloff
17
void terminal_scroll() { memmove(terminal_buffer, terminal_buffer + VGA_WIDTH, buffer_size - VGA_WIDTH); memset(terminal_buffer + buffer_size - VGA_WIDTH, 0, VGA_WIDTH); ...
Егор
47
Всем привет! Подскажите, пожалуйста, в чем ошибка? Настраиваю подключение к MySQL. Либы лежат рядом с exe. Все как по "учебнику"
Евгений
16
А можете как-то проверить меня по знаниям по ассемблеру?
A A
132
Здравствуйте! У меня появилась возможность купить книгу "Изучай Haskell во имя добра!". Но я где-то слышал, что эта книга устарела. Насколько это правда??
E
22
Здравствуйте! Я вот на stepic решаю задачи на хаскеле https://stepik.org/lesson/8443/step/8?unit=1578 мой код import Data.List (isInfixOf) removing :: String -> [String] ->...
E
10
Камрады, кто тесно работал с vtv, хотел уточнить. Ширина column задаётся жёстко на этапе создания дерева или можно в рантайме ее менять программно (не мышкой)?
Ed Doc
10
да ладно ... что там неочевидного ? глянуть в исх-ки датасета и/или кверика чтобы понять в каком месте и как выполняется обращения к св-вам blablaSQL - минутное дело, даже е...
Сергей
7
Здесь для arm кто-нибудь кодит ?
Nothing
52
Карта сайта