Здравствуйте, 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>Это не модуль. Модуль — это когда можно провести границу. В вашем случае границу провести не получится 
Я значит не понял принцип по которому ты проводишь границы. По-моему всё нормально проводится.