Re[12]: Интерфейсы и реализация
От: · Великобритания  
Дата: 04.09.20 17:20
Оценка:
Здравствуйте, rosencrantz, Вы писали:

R>>>Он не обязательно хуже, он просто не обладает теми свойствами, которыми обладает мой вариант. Плохо это или хорошо — я ж как раз пытаюсь донести — зависит от восприятия автора/читателя.

R>·>Ок. Каким образом в коде выражается это разбиение на модули? Ну т.е. представь себе ты написал код, закоммитил, я открываю твой код и я там увижу эти модули? Как читатель узнает твоё авторское восприятие этого кода?
R>Ну серьёзно? "Ну т.е. представь себе ты написал код, закоммитил, <скип> Как читатель узнает твоё авторское восприятие этого кода?" — про это пишутся сотни книжек и ведутся регулярные срачи на рсдн. Какой ответ вы ожидаете услышать?
Серьёзно. Так я и пытаюсь обратить внимание важность именно явных моментов. Скажем, твой изначальный код я понял без пояснений что там есть. А вот твои "модули" я там не увидел, а после того как ты их указал — я мысленно увидел и другие варианты разбиения. Значит это только лишь твоя субъекивная картина. Т.е. ты ради своей личной субъективной картины усложняешь код, внося туда лишние конструкции языка и запутывая читателя, т.к. нет ничего явного, что бы позволило передать авторское восприятие.

R>·>Тут я топлю за принцип YAGNI.

R>А не вкусовщина ли это?
Писать простой код — вкусовщина?

R>·>Вот когда нам не станет хватать, что наш class UserHandler пишет батчами в бд, вот тогда мы отрефакторим код и у нас получится interface UserHandler и реализующие его class DbUserWriter, class XmlUserWriter — с не вымученными enterprisified именами, а явно продиктованными новыми появившимися требованиями.

R>Я совершенно за YAGNI, но только там где противопоставляются более накрученное решение и более простое. Добавление 1 интерфейса не делает решение более сложным — ни в восприятии, ни в реализации, ни в сопровождении. Для тех, кто не сечёт фишку, решение по сложности — такое же, как и без интерфейса, для тех, кто сечёт — это "граница интерфейса, точка расширения"
В реализации сложность — как минимум у тебя появляется необходимость придумывать два имени для сущностей. BatchInsertingUserHandler — выглядит жутко.
В сопровождении — выяснить что делает handleUser — надо прыгать между местом использования между интерфейсом и классом.

R>Можно провести аналогию с поясняющей переменной:


R>
R>if (person.age >= 21) {
R>  ...
R>}
R>

R>Всё тут в порядке? YAGNI не чешется?
Тут magic number чешется как минимум. Понятно, что другие принципы тоже важны. Вот какому принципу ты следуешь, когда хочешь сделать тот интерфейс — я и хочу понять.

R>
R>bool isAllowedToDrinkBear = person.age >= 21;
R>if (isAllowedToDrinkBear) {
R>  ...
R>}
R>

R>Нужна поясняющая переменная? Или YAGNI и потом отрефакторим? Вносит она проблемы? Увеличивает сложность экспоненциально? Что насчёт поясняющей функции?
Либо так, либо "const DRINK_BEER_LEGAL_AGE = 21". Т.к. из кода совершенно непонятно какой семантикой обладает "age >= 21". То ли пиво, то ли ношение оружия, толи порно. В твоём примере с интерфейсом я неоднозначностей не заметил, так что не очень хорошая аналогия.
Кстати, медведей лучше не пить, даже в 21.

R>
R>if (isAllowedToDrinkBear(person)) {
R>  ...
R>}
R>

R>Тут как? YAGNI? Что насчёт выноса этой функции в отдельный класс?
Если код используется из разных частей кода, то имеет смысл вынести в функцию, да. А иначе, ясен пень, надо остановиться на предыдущем шаге.

R>
R>if (bearDrinkingDecisionMaker.isAllowedToDrinkBear(person)) {
R>  ...
R>}
R>

R>Во всех случаях (кроме первого) появление имени "isAllowedToDrinkBear" — это тот самый ввод интерфейса.
То же самое, для переиспользования или если isAllowedToDrinkBear имеет смысл покрыть отдельно тестами. Правда конкретно для тривиального выражения вроде "age >= 21" я бы точно не стал тестами отдельно покрывать.

R>>>В вашей версии если UserHandler превращается в BatchInsertingUserHandler, модуль 1 исчезает и его содержимое становится частью модуля 3. Конвертор CSV->XML вы уже не напишете без правок кода, но такой цели и не было. Но вообще чтение CSV у вас теперь гвоздями прибито к вставке в базу.

R>·>Модуль 1 не исчезнет, а станет состоять из только лишь класса UserCsvReader.
R>Это не модуль. Модуль — это когда можно провести границу. В вашем случае границу провести не получится
Я значит не понял принцип по которому ты проводишь границы. По-моему всё нормально проводится.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.