Здравствуйте, Poopy Joe, Вы писали: S>>Юношеский максимализм. PJ>Когда аргументов нет начинаются отсылки в авторитету, возрасту и должностям. Ты не знаешь меня, ты не знаешь мой возраст, ты не знаешь мой опыт.
Юношеский максимализм возможен в любом возрасте. PJ>Это у меня безопасный. Потому что все строго типизировано. Я могу все разобрать и собрать заново не опасаясь регрессий, потому что инварианты выражены в типах. У тебя он именно что безобидный. Боясь, что все развалится ты ограничиваешь себя потому ты ограничиваешь себя перестановкой параметров и ограниченными возможностями тулзов, от которых ты вынужденно зависишь. Так это не проблемы рефакторинга, это проблемы выбора инструментов и языков.
Возможно. Тем не менее, имеем то, что имеем. У нас, к примеру, даже дотнет далеко не везде. Потому что не в любом регионе можно легко найти дотнет-программистов. Некоторые модули написаны, к примеру, на PHP. Не потому, что это лучший язык в мире, а потому, что там, где расположен соответствуюший департамент, кроме PHP никаких специалистов нет.
Как по мне — я бы тупо перенёс разработку туда, где есть нормальные инженеры; но стратегические решения принимаются топ-менеджментом, и потому имеем то, что имеем.
Скорее всего, есть какие-то факторы, которых мне с моего уровня просто не видно.
PJ>Ты выдумал себе какие-то ограничение и решил, что все должны с тобой согласится. Кто-то согласиться, кто-то нет. Ты совершенно не глас истины и источник имен.
Это не я выдумал себе. Существует вполне себе консенсус на эту тему — и только отдельные возражения.
PJ>Если ты выставил его для конкретного сценария, то выставишь ты минимально необходимые данные для этого. В идеальном случае их просто нельзя будет по другому использовать. Ну если уж совсем какие-то странные вещи не городить. Но вряд ли вы доходите до того, что вообще никогда ничего не меняете, потому что кто-то где-то может быть... Все это очень тяжело обсуждать не видя апи и реальных сценариев.
Конечно мы меняем. Просто есть факторы, которые нужно учитывать. Вы отважно заявляете, что этими факторами можно пренебречь.
PJ>Это как? Операция сфейлилась, куда там идти дальше? Типа пытался считать файл, не вышло, ну и ладно...? Даже не знаю в каких случаях это будет работать.
Более-менее во всех. У нас есть граница атомарной операции — либо мы довели её до конца, либо нет. Вопрос в том — делаем ли мы какой-то развёрнутый анализ причин, или просто говорим "Something went wrong" на всех путях.
Очевидно, что второй вариант дешевле поддерживать — не надо переделываться каждый раз, как меняется код ошибки. Именно по этому пути идут очень многие современные продукты — посмотрите, к примеру, на браузеры.
S>>Не, не хочу. Знаю, сколько стоит внесение такого изменения в 1 компании; умножать на 30 я умею с 7 лет. PJ>Если компании стоит миллионы долларов изменение одного кода ошибки, то там все очень и очень плохо. Я впрочем, все равно не верю.
Ну, во-первых, у вас плохо с арифметикой. Если суммарный ущерб в 30 компаниях в диапазоне от 100k до 1M, то стоимость в одной — от 3k до 30k.
Во-вторых, 3k — это вообще не сумма. Если вы не верите в такие затраты, значит вы очень плохо себе представляете, как устроены бизнес процессы.
Я могу вам детальный счёт, как в ресторане, написать, но не вижу смысла — опасаюсь, что вы всё равно в него не поверите, и будете рассказывать, что надо переделать всю структуру саппорта и мейнтененса.
PJ>Т.е. cloud services живы только благодаря вам?
Нам и таким как мы. Думаете, для чего MS вваливает деньги в каналы продаж?
PJ>Не, нам пришлось в явном виде выражать то, что и так давно известно — мутабельность источник геморроя. Нет изменений — нет проблем. И вообще, не было такой проблемы как "сделать прозрачно для модулей". У нас нет страха менять код. Да, это была ошибка дизайна, считать что на диск можно полагаться. Соответственно ее надо исправить корректно, а не прозрачно. В конце-концов, для логики оно и прозрачно, это только персистенс-часть изменилась. Если сайд-эффекты устранены из логики, то это исключает целый класс ошибок.
Я по-прежнему не понимаю, зачем каждый модуль обязан знать о существовании версий и задуряться с вычислением хеш-кодов для снапшота. Наверняка это имеет какой-то смысл, хоть мне он и не виден.
Точно так же и вам какие-то действия на нашей стороне кажутся неверными, но вероятнее всего это тоже от недоинформированности, а не от оверквалификации.
S>>И чем бы один тип uuid отличался от другого такого же uuid? Ничем? Ну вот считайте, что у нас так и есть. И для удобства, этот uuid имеет название subscriptionID. PJ>Тем что он привязан к подписке, соответственно никто не ожидает по нему подписку. Если кому-то понадобились детали подписки, то можно было бы добавить в api функцию uuid -> subscription option. те же яйца вид в профиль, но клиент уже не ожидает подписку всегда, потому что ее никто не обещал.
Ну что ж, неплохой дизайн. Конечно, зная заранее о том, что не все ордера могут быть привязаны к подписке, можно было сделать и ещё лучше.
Но давайте устроим минутку честности: неужели вы бы стали городить вот эту кунсткамеру заранее, несмотря на то, что вам принесли детальные требования, в которых английским по белому написано: "ордер всегда привязан к подписке"?
Ок, ордер привязан ещё много к чему — там есть id покупателя, id региона, ещё много всяких параметров. Какие-то из них по ТЗ являются опциональными, какие-то — обязательными.
Вы прямо про все-все обязательные будете возвращать какие-то opaque id, которые возможно будут конвертироваться в customer или region? А возможно — не будут?
Если нет — то по каким критериям вы отличаете, где возвращать subscription id, а где — fake artificial id?
Если да — are you fucking serious? Усложняете жизнь себе и пользователям ради сомнительной будущей выгоды?
Не люблю апеллировать к авторитетам — но принцип YAGNI вам о чём-нибудь говорит?
Ладно, допустим мы приняли такое решение, как вы предлагаете. Сейчас 2005 год, API выглядит именно так. То, что торчит вместо subscriptionID, называется entitlementID, чтобы в будущем иметь возможность прикрутить другие виды сделок.
Для удобства пользователей мы дали функцию entitlementID -> subscription option.
Теперь, при тестировании наши пользователи заметили, что эта функция всегда возвращает подписку: напомню, по факту, никаких других видов ордеров нету.
У них там в коде, конечно же, стоит что-то вроде:
var subId = GetSubId(entitlementId);
if(subId.HasValue())
{
// основная логика
} else
{
throw new Exception("Жопа!"); // TODO: handle the case where entitlement is not subscription
}
И вот этот TODO прекрасно живёт в их коде с 2005 года. Всё работает, все довольны.
Наконец-то, в 2019 году ваша инвестиция в архитектуру окупилась: потребовались новые виды ордеров! У нас есть future-proof API, который не надо менять.
Мы смело запускаем новую версию в продакшн, а через три дня до нас доезжает эскалация: у крупного клиента "Жопа!" на весь экран.
То есть нарвались мы ровно на то же, что и в нынешнем подходе — только я уже сейчас знаю, что такая ситуация может возникнуть, а вы полагаете, что замена "subscription" на "subscription?" вас защитит от сложностей реального мира.
PJ>А можно не наступать на них?
На практике — нельзя. Всеведение недоступно ни за какие деньги. Можно стараться минимизировать эффекты граблей.
PJ>Первое что приходит в голову — считать контрольную сумму всех ордеров. Каждый вызов возвращает результат их свертки. А если еще помудрить с функцией контрольной суммы, то GetOrdersBatch(1) + GetOrdersBatch(3) сразу может выдать ошибку.
Непонятно. Ну, считаете вы контрольную сумму — дальше что? Вы мне покажите сигнатуру API, в которой будет выражено это ограничение. Инструкцию про то, что надо рассчитать контрольные суммы и сверить их, я могу написать и сам. Или — ещё эффективнее: я просто напишу утверждение про непрерывность словами, безо всяких контрольных сумм.
PJ>Ну торренты это как-то делают очень давно.
Отож. У торрентов есть документация к протоколу, которая выходит за рамки сигнатур. И соответствие или несоответствие реализации этой документации вам никакой компилятор не проверит.
Поэтому применение или неприменение DDD никакого отношения к вопросам проектирования внешнего API не имеет, увы. Через JSON не видно, FP там у вас внутри, ООП на жаве, C++ c шаблонами, или спагетти на visual basic.
PJ>Хорошо бы хотя бы такой держать под контролем, а не еще специально добавлять.
Держать под контролем — конечно нужно и можно. А специально добавлять — почему бы и нет, если это оправдано?
Вот вам категорически не нравится идея делать "фейковые" подписки. Вы бы предпочли сейчас потратить сотни часов на ликвидацию технического долга, чем откладывать его.
А я отношусь к этому крайне скептически, потому что такой подход сразу опускает наш баланс на $XXk. А сколько мы заработаем за счёт этой фичи — величина неизвестная.
Запускаем самый дешёвый вариант, смотрим на метрики:
— сколько этого добра вообще продаётся. Если мало — то отменяем фичу, откатываем всё назад.
— сколько у нас затрат возникает из-за "костыльности" решения. Если их особо нету, то можно продолжать жить с этим долгом. (На всякий случай напомню о концепции Net Present Value из финансового анализа — 100 часов сейчас всегда стоят дороже, чем 100 часов через 3 года)
— и только если у нас есть И прибыль, которая окупает инвестиции в улучшения кода, И проблемы, которые нынешний код создаёт, мы осознанно берём и устраняем тех.долг.
При этом у нас нет никаких проблем обосновать необходимость этого рефакторинга перед кем угодно, вплоть до CEO и президента компании, безо всяких требований к их технической квалификации.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[67]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Poopy Joe, Вы писали:
S>> Вся идея рефакторинга — сделать так, чтобы изменение было не просто "безобидным", а безопасным. PJ>Это у меня безопасный. Потому что все строго типизировано. Я могу все разобрать и собрать заново не опасаясь регрессий, потому что инварианты выражены в типах. У тебя он именно что безобидный. Боясь, что все развалится ты ограничиваешь себя потому ты ограничиваешь себя перестановкой параметров и ограниченными возможностями тулзов, от которых ты вынужденно зависишь. Так это не проблемы рефакторинга, это проблемы выбора инструментов и языков.
Тем не менее, если у тебя рефакторинг может дать на выходе фичу, не совсем понятно, зачем этот подход называть рефакторингом.
Re[68]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Ikemefula, Вы писали:
I>Тем не менее, если у тебя рефакторинг может дать на выходе фичу, не совсем понятно, зачем этот подход называть рефакторингом.
Если разработка фичи идет лучше, если еще и отрефакторишь код, то как еще я это должен называть?
Re[69]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Poopy Joe, Вы писали:
I>>Тем не менее, если у тебя рефакторинг может дать на выходе фичу, не совсем понятно, зачем этот подход называть рефакторингом. PJ>Если разработка фичи идет лучше, если еще и отрефакторишь код, то как еще я это должен называть?
Разработка фичи действительно идет лучше с рефакторингом — именно это Фаулер и пишет.
Проблема в том, что у тебя слово "рефакторинг" включает в себя как возможный результат эту самую фичу
То есть, порочный круг.
Соответсвенно, раз у тебя фича может быть результатом рефакторинга, то 100% изменений могут дать какую нибудь подлянку. Где ждать проблему — не ясно.
Если рефакторинг делать по-Фаулеру, то очевидно, что безопасные изменения чередуются с произвольными. Именно это Фаулер и пишет — надо чередовать рефакторинг с не-рефакторингом, но не смешивать всё вместе.
Безопасные это только те, где есть максимальные гарантии, включая юнит-тесты и многое другое, а не выборочные(конкретный юзер видит или не видит).
Бенефит простой — безопасные изменения обладают определенными свойствами, в силу которых их можно
1 анализировать, хоть глазом, хоть инструментами
2 комбинировать, например, последовательный сплит методов так же безопасен, как и 1 сплит.
3 автоматизировать — не часы, а минуты
Соответственно, фича это:
80% рефакторинга
20% произвольных изменений
Отсюда ясно, что подлянки нужно ждать от этих 20% а не откуда угодно, как у тебя
На самом деле 80 к 20 можно свести и к 99 к 1, т.е. вместо 'перепишем руками и скопируем много раз' будет 'обработаем инструментом'. Логическая цепочка длинее, но из-за автоматизации она всё равно выполняется за минуты.
Например — есть одинаковых 300 мест, которые надо поменять везде чуть-чуть по разному и на выходе ждем 300 похожих мест. Выделяем функцию, устраняем дубликаты, выделяем кейсы, в функции пилим эти кейсы, придаем нужную структуру, делаем инлайн.
Итого — 300 мест переписались как будто руками, но бОльшая часть делалась рефакторингом, а следовательно не надо бояться, что, скажем, не тот параметр попал не туда.
Итого — даже если наличие похожего кода обосновано, его можно обрабатывать автоматическими средствами, которые ничего не ломают.
Здравствуйте, Sinclair, Вы писали:
S>Юношеский максимализм возможен в любом возрасте.
Не, это отсылка к собственной мудрости. Типа я тебя на полгода старше, а значит умнее. (c)
S>Возможно. Тем не менее, имеем то, что имеем. У нас, к примеру, даже дотнет далеко не везде. Потому что не в любом регионе можно легко найти дотнет-программистов. Некоторые модули написаны, к примеру, на PHP. Не потому, что это лучший язык в мире, а потому, что там, где расположен соответствуюший департамент, кроме PHP никаких специалистов нет.
И что с того? Если завтра у вас будет язык для которого вообще тулзов нет. Рефакторинг вообще отменишь?
PJ>>Ты выдумал себе какие-то ограничение и решил, что все должны с тобой согласится. Кто-то согласиться, кто-то нет. Ты совершенно не глас истины и источник имен. S>Это не я выдумал себе. Существует вполне себе консенсус на эту тему — и только отдельные возражения.
Я разных случаях слышал следующую фраза +- "вот это модуль трогать страшно, там весь код древний и куча проблем, надо бы его отрефакторить и чтобы решить их." Я не общаюсь с сотнями программистов по всему миру на тему рефакторинга, как один кадр тут. Но эту фразу я слышал в разных компаниях. Возможно все кругом дураки и только вы дартаньяны, правильно используете термины.
S>Конечно мы меняем. Просто есть факторы, которые нужно учитывать. Вы отважно заявляете, что этими факторами можно пренебречь.
Я ниче такого не говорил. Я лишь сказал, что вы сами себя загнали в такую ситуация. Вероятно сейчас уже выбора нет.
S>Очевидно, что второй вариант дешевле поддерживать — не надо переделываться каждый раз, как меняется код ошибки. Именно по этому пути идут очень многие современные продукты — посмотрите, к примеру, на браузеры.
Ну да, клиент сообщает у нас тут "internal error". Флаг в руки такую систему поддерживать.
Если бы это было проще и дешевле поддерживать, то все бы так и делали, а зачем-то заморачиваются...
S>Ну, во-первых, у вас плохо с арифметикой. Если суммарный ущерб в 30 компаниях в диапазоне от 100k до 1M, то стоимость в одной — от 3k до 30k.
Как ты это вывел? Я тут вроде ниче не считал. Я верю, что ты можешь сложить нужные тебе числа и получить нужный тебе результат. Я не убежден, что изначально эти цифры не высосаны из пальца.
S>Во-вторых, 3k — это вообще не сумма. Если вы не верите в такие затраты, значит вы очень плохо себе представляете, как устроены бизнес процессы.
Так не сумма или миллионы? Ты определись уже.
S>Нам и таким как мы. Думаете, для чего MS вваливает деньги в каналы продаж?
Не знаю, думаю, чтобы заработать еще больше денег. Считать себя спасителями МС это наверно лестно, но я не уверен, что адекватно.
S>Я по-прежнему не понимаю, зачем каждый модуль обязан знать о существовании версий и задуряться с вычислением хеш-кодов для снапшота. Наверняка это имеет какой-то смысл, хоть мне он и не виден.
Так разделение ролей. Только модуль знает сколько файлов он писал. Снапшоту эти детали не интересны от слова совсем, как и прочие детали реализаиции. Все что спапшот хочет знать сколько файлов надо добавить и какой их хеш.
S>Точно так же и вам какие-то действия на нашей стороне кажутся неверными, но вероятнее всего это тоже от недоинформированности, а не от оверквалификации.
Забавная поставка вопроса. Так-то у вас все правильно, могут другие не понять... Я бы вот у нас с удовольствием послушал сторонний анализ архитектуры, если бы кто-то взялся его делать. Потому как взгляд замыливается и никакая оверквалификация не нужна, чтобы что-то заметить.
S>Но давайте устроим минутку честности: неужели вы бы стали городить вот эту кунсткамеру заранее, несмотря на то, что вам принесли детальные требования, в которых английским по белому написано: "ордер всегда привязан к подписке"?
Разве тут написано, что в каждом ордере должен быть id подписки? Нет. А зачем вы ее туда вставили? То, что он привязан — внутренние детали реализации.
S>Ок, ордер привязан ещё много к чему — там есть id покупателя, id региона, ещё много всяких параметров. Какие-то из них по ТЗ являются опциональными, какие-то — обязательными.
Именно. Нафига все это совать в одно сообщение? Кому надо могут из запросить по ордеру дополнительные данные.
S>Вы прямо про все-все обязательные будете возвращать какие-то opaque id, которые возможно будут конвертироваться в customer или region? А возможно — не будут?
У тебя есть order_id это все что тут надо.
S>Если нет — то по каким критериям вы отличаете, где возвращать subscription id, а где — fake artificial id?
почему надо возвращать какой-то фейк? если подписка есть, то ее возвращают, если нет, то ничего. Если клиенту нужна подписка, то ему нельзя врать. А если ему нужны деньги, то ему пофиг на подписку.
S>Если да — are you fucking serious? Усложняете жизнь себе и пользователям ради сомнительной будущей выгоды? S>Не люблю апеллировать к авторитетам — но принцип YAGNI вам о чём-нибудь говорит?
Ты тут о сам с собой поговорил, приписывая мне какие-то выдумки.
S>Наконец-то, в 2019 году ваша инвестиция в архитектуру окупилась: потребовались новые виды ордеров! У нас есть future-proof API, который не надо менять. S>Мы смело запускаем новую версию в продакшн, а через три дня до нас доезжает эскалация: у крупного клиента "Жопа!" на весь экран. S>То есть нарвались мы ровно на то же, что и в нынешнем подходе — только я уже сейчас знаю, что такая ситуация может возникнуть, а вы полагаете, что замена "subscription" на "subscription?" вас защитит от сложностей реального мира.
Так не надо останавливаться на этом. В вдруг у вас c 2005 года все id подписки начинались на S. Это вообще было ваше внутреннее дело, но клиент по какой-то неведомой вам причине, сделал тот же код, что и выше, но subscritionId.StartsWith("S").
И вот так же жопа на экране, хотя вы вообще ничего не меняли, у вас просто номера кончились, а буква S никогда ничего особенно не значила. Ну давайте из такого исходить при проектировании АПИ. Куда это заведет?
PJ>>Первое что приходит в голову — считать контрольную сумму всех ордеров. Каждый вызов возвращает результат их свертки. А если еще помудрить с функцией контрольной суммы, то GetOrdersBatch(1) + GetOrdersBatch(3) сразу может выдать ошибку. S>Непонятно. Ну, считаете вы контрольную сумму — дальше что? Вы мне покажите сигнатуру API, в которой будет выражено это ограничение.
Виде возвращаемого значения операции. Как же еще-то? Получаешь пакет ордеров и контрольную сумму.
S>Инструкцию про то, что надо рассчитать контрольные суммы и сверить их, я могу написать и сам.
В каком месте ты у меня нашел инструкции?
PJ>>Ну торренты это как-то делают очень давно. S>Отож. У торрентов есть документация к протоколу, которая выходит за рамки сигнатур. И соответствие или несоответствие реализации этой документации вам никакой компилятор не проверит. S>Поэтому применение или неприменение DDD никакого отношения к вопросам проектирования внешнего API не имеет, увы. Через JSON не видно, FP там у вас внутри, ООП на жаве, C++ c шаблонами, или спагетти на visual basic.
API разумеется компилятор проверить не может. К DDD однако имеет, в чем ты сам сможешь убедиться, прочитав любую книжку, а не просто фантазируя. К FP пожалуй тоже. Надо будет это API как-то связывать с моделью, а вот тут компилятор уже поможет. И только ооп на жабе сосет, на такова судьба жабы.
PJ>>Хорошо бы хотя бы такой держать под контролем, а не еще специально добавлять. S>Держать под контролем — конечно нужно и можно. А специально добавлять — почему бы и нет, если это оправдано?
Это оправдано, когда это делается иногда и по веской причине, а не на регулярной основе.
S>Вот вам категорически не нравится идея делать "фейковые" подписки. Вы бы предпочли сейчас потратить сотни часов на ликвидацию технического долга, чем откладывать его.
Почему сотни? Почему не тысячи? У тебя любое изменение это миллионы долларов и сотни часов, хоть бы это один error code был. Такие цифры не вызывают никакого доверия.
Re[69]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Poopy Joe, Вы писали:
PJ>>>Ты выдумал себе какие-то ограничение и решил, что все должны с тобой согласится. Кто-то согласиться, кто-то нет. Ты совершенно не глас истины и источник имен. S>>Это не я выдумал себе. Существует вполне себе консенсус на эту тему — и только отдельные возражения. PJ>Я разных случаях слышал следующую фраза +- "вот это модуль трогать страшно, там весь код древний и куча проблем, надо бы его отрефакторить и чтобы решить их." Я не общаюсь с сотнями программистов по всему миру на тему рефакторинга, как один кадр тут. Но эту фразу я слышал в разных компаниях. Возможно все кругом дураки и только вы дартаньяны, правильно используете термины.
Выглядит совсем наоборот — "я пишу на F#, у меня всё типизировано, пока не сломал это рефакторинг"
Классика эффективности это разделение труда по качественным признакам. У тебя эти качественные признаки мягко говоря расплывчаты. У Фаулера границы достаточно точные.
Из того, что я вижу, твой подход при переносе на девелоперов попроще даёт хаос в чистом виде, например,
1 язык и система типов недостаточно крутая
2 квалификация разработчика достаточно посредственная
3 нет автоматических инструментов
4 нет точного контроля — тесты, проверки инвариантов, пред-, пост-условий, редкие логи и тд
... итд
Это я из опыта — у меня работа реанимировать убитые проекты. Вроде все стараются сохранить фичи, ничего не сломать и тд, и вроде даже улучшайзином занимаются. Но на практике проблемы плодятся со страшной силой.
Re[70]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Ikemefula, Вы писали:
I>Проблема в том, что у тебя слово "рефакторинг" включает в себя как возможный результат эту самую фичу
Я сказал, что у меня фича и рефакторинг могу быть зависимыми. Нет смысла в рефакторинге, пока нет фичи и не имеет смысл пилить фичу, пока не сделан рефаторинг. Баг фикс может быть результатом рефакторинга. Дурачков, которые бы откатывали такое назад, я не знаю.
I>Если рефакторинг делать по-Фаулеру, то очевидно, что безопасные изменения чередуются с произвольными. Именно это Фаулер и пишет — надо чередовать рефакторинг с не-рефакторингом, но не смешивать всё вместе.
I>Безопасные это только те, где есть максимальные гарантии, включая юнит-тесты и многое другое, а не выборочные(конкретный юзер видит или не видит).
А кто тебе сказал, что юнит-тесты в какой-то момент переставали работать?
I>Отсюда ясно, что подлянки нужно ждать от этих 20% а не откуда угодно, как у тебя
Дай определение подлянок.
Re[70]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Ikemefula, Вы писали:
I>Выглядит совсем наоборот — "я пишу на F#, у меня всё типизировано, пока не сломал это рефакторинг"
Я даже не понял эту фразу, так что ты сам с собой о чем-то.
Re[69]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Poopy Joe, Вы писали:
PJ>И что с того? Если завтра у вас будет язык для которого вообще тулзов нет. Рефакторинг вообще отменишь?
Нет. Потребую соблюдать ещё большую осторожность. И все идеи типа "мы сейчас совместим фиче-девелопмент с багфиксом и рефакторингом" буду встречать со скептическим энтузиазмом.
PJ>Я разных случаях слышал следующую фраза +- "вот это модуль трогать страшно, там весь код древний и куча проблем, надо бы его отрефакторить и чтобы решить их." Я не общаюсь с сотнями программистов по всему миру на тему рефакторинга, как один кадр тут. Но эту фразу я слышал в разных компаниях. Возможно все кругом дураки и только вы дартаньяны, правильно используете термины.
Всё верно, именно так всё и звучит — решить проблемы в текущем коде затруднительно; его надо сначала отрефакторить.
Это вы почему-то считаете, что этой фразой люди подразумевали решение проблем путём рефакторинга, или одновременное решение-и-рефакторинг.
Ещё иногда при подобных разговорах люди добавляют "а перед тем неплохо бы обложить код тестами, чтобы при рефакторинге его не порушить".
PJ>Я ниче такого не говорил. Я лишь сказал, что вы сами себя загнали в такую ситуация. Вероятно сейчас уже выбора нет.
Выбор есть, и мы его осознанно делаем.
PJ>Ну да, клиент сообщает у нас тут "internal error". Флаг в руки такую систему поддерживать.
PJ>Если бы это было проще и дешевле поддерживать, то все бы так и делали, а зачем-то заморачиваются...
Все как раз так и делают. Вы кругом-то посмотрите.
PJ>Как ты это вывел?
Это то, что я приводил в качестве оценок. Вы же каким-то образом из утверждений "суммарный ущерб — [100k, 1M], получен умножением ущерба в одной компании на 30" вывели, что "ущерб в одной компании на миллионы долларов". PJ>Я тут вроде ниче не считал.
Ну как же. Вам хотелось сделать финансовый аргумент поабсурднее, чтобы легче было его отбросить. "Смена кода ошибки... миллионы долларов... пфе, чушь". PJ>Я верю, что ты можешь сложить нужные тебе числа и получить нужный тебе результат. Я не убежден, что изначально эти цифры не высосаны из пальца.
PJ>Так не сумма или миллионы? Ты определись уже.
. Из вот таких вот 3k быстро набегают сотни тысяч, как только у вашего API становится чуть больше, чем дюжина клиентов.
PJ>Не знаю, думаю, чтобы заработать еще больше денег. Считать себя спасителями МС это наверно лестно, но я не уверен, что адекватно.
PJ>Так разделение ролей. Только модуль знает сколько файлов он писал. Снапшоту эти детали не интересны от слова совсем, как и прочие детали реализаиции. Все что спапшот хочет знать сколько файлов надо добавить и какой их хеш.
Ну, вы видите разделение ролей так. А можно смотреть и под другим углом: модуль пишет "куда-то", которое умеет само вычислять хеши от всего, что насохраняли все модули. И само умеет проверять, живы файлы или нет, перед тем, как отдать их на чтение модулям. А то завтра окажется, что у модуля бинарный конфиг, в котором 000....00000000000000000000 — это валидный блок, он и зачитает битый файл, не чихнув.
PJ>Забавная поставка вопроса. Так-то у вас все правильно, могут другие не понять... Я бы вот у нас с удовольствием послушал сторонний анализ архитектуры, если бы кто-то взялся его делать. Потому как взгляд замыливается и никакая оверквалификация не нужна, чтобы что-то заметить.
А что, никто не берётся? Напишите в форум "Архитектура" — советчиков набежит столько, что отбиваться устанете.
PJ>Разве тут написано, что в каждом ордере должен быть id подписки?
Отчего же? Именно так и написано. В Entity-Relationship терминологии "связь" с такой кардинальностью означает наличие not null атрибута.
А зачем вы ее туда вставили? То, что он привязан — внутренние детали реализации.
Ну какие же они внутренние? Это прямо часть ТЗ, написанного бизнес-аналитиком.
S>>Ок, ордер привязан ещё много к чему — там есть id покупателя, id региона, ещё много всяких параметров. Какие-то из них по ТЗ являются опциональными, какие-то — обязательными. PJ>Именно. Нафига все это совать в одно сообщение? Кому надо могут из запросить по ордеру дополнительные данные.
Эмм, то есть вместо разумного API, который позволяет получить пачку ордеров по некоторым критериям, вы предлагаете на ровном месте лепить K методов получения GetOrderTotalsById, GetOrderCustomerById, и т.п, и тому, кто захочет банально показать заказы на экране, придётся делать N*M+1 вызовов API. Нуу.... как бы в моём уютном мирке это как раз bad design — мы получаем медленный API, неудобный в использовании. И, да, — никаких преимуществ типа "дополнительной гибкости" и т.п. мы взамен не получаем.
S>>Если да — are you fucking serious? Усложняете жизнь себе и пользователям ради сомнительной будущей выгоды? S>>Не люблю апеллировать к авторитетам — но принцип YAGNI вам о чём-нибудь говорит? PJ>Ты тут о сам с собой поговорил, приписывая мне какие-то выдумки.
Да нет, всё я верно угадал.
PJ>Так не надо останавливаться на этом. В вдруг у вас c 2005 года все id подписки начинались на S. Это вообще было ваше внутреннее дело, но клиент по какой-то неведомой вам причине, сделал тот же код, что и выше, но subscritionId.StartsWith("S").
Вы не поверите — я и такое наблюдал PJ>И вот так же жопа на экране, хотя вы вообще ничего не меняли, у вас просто номера кончились, а буква S никогда ничего особенно не значила. Ну давайте из такого исходить при проектировании АПИ. Куда это заведет?
Это заведёт нас в зону успеха, естественно. Настоящие API для внешнего мира проектировать объективно тяжело.
Внезапно оказывается, что внешние разработчики вполне способны к распознаванию паттернов. И если у вас OrderID имел несчастье быть семантически нагруженным (типа BO000001 — это billing order, SO999999 — это Sales order), а потом вы внезапно решили эту систему изменить — ждите беды. Даже если вы заботливо описали сигнатуру как "просто string".
Если у вас нумерация клиентов в системе устроена не случайно, а в виде волшебных чисел, которые комбинируют регион и порядковый номер, то будьте уверены — ваши клиенты этим злоупотребят.
И чем успешнее будет ваш API, тем хуже будет эта ситуация — больше шансов, что из него извлекут неожиданную семантику, и больше стоимость починки этих нежелательных последствий, когда их обнаружат.
Поэтому да, надо исходить при проектировании API именно из этого! Надо такие вещи учитывать, и желательно заранее. Вашим API будут пользоваться неквалифицированные люди, у которых не стоит задача "сделать как можно более красивый и надёжный код", у них с вероятностью 99% будет стоять задача "запилить побыстрее, чтобы оно хоть как-то работало", а все косяки в их реализации будут падать на вас: "ваш API опять глючит, вот только вчера всё работало, а сегодня выдаёт ошибку".
Если вы приходите в проект, где два архитектора назад было принято решение выставить подобные ID наружу, то таки надо предполагать худшее — что буква S имеет сакральное значение для самого прибыльного клиента; и что на прямой вопрос "важна ли вам буква S" он запросто соврёт — потому что реально понимающий в этих вопросах человек обитает где-то в глубинах их корпоративной иерархии (если он вообще ешё доступен), и никто не бросится его разыскивать для разговора с вами, а ответит вам тот человек, чьё время стоит меньше всего в компании клиента (и с соответствующим уровнем квалификации).
Только если у вас есть железные доказательства обратного — вот тогда можно вносить такие изменения. И сбор таких доказательств — значительная часть обязанностей продакт менеджера.
PJ>>>Первое что приходит в голову — считать контрольную сумму всех ордеров. Каждый вызов возвращает результат их свертки. А если еще помудрить с функцией контрольной суммы, то GetOrdersBatch(1) + GetOrdersBatch(3) сразу может выдать ошибку. S>>Непонятно. Ну, считаете вы контрольную сумму — дальше что? Вы мне покажите сигнатуру API, в которой будет выражено это ограничение. PJ>Виде возвращаемого значения операции. Как же еще-то? Получаешь пакет ордеров и контрольную сумму.
Ну и что. Вот я вижу "пакет ордеров и контрольную сумму". Каким образом я при помощи этих данных пойму, что у меня после N вызовов на руках все ордера? PJ>В каком месте ты у меня нашел инструкции?
А, это я забежал вперёд. Извините. Давайте продолжим — я всё ещё хочу понять, каким образом сигнатура метода мне опишет эквивалентность GetOrdersBatch(1) + GetOrdersBatch(2) с GetAllOrders().
Как я понял, вы готовы обойтись без инструкций
PJ>API разумеется компилятор проверить не может. К DDD однако имеет, в чем ты сам сможешь убедиться, прочитав любую книжку, а не просто фантазируя. К FP пожалуй тоже. Надо будет это API как-то связывать с моделью, а вот тут компилятор уже поможет. И только ооп на жабе сосет, на такова судьба жабы.
Ну, как я понимаю, в теории при помощи Зависимых Типов и прочих ФВП можно описывать значительно более сложные API, чем при помощи выразительных средств типа "OOP на Java".
Но на практике это всего лишь означает, что у вашего API будет 0 клиентов.
PJ>Почему сотни? Почему не тысячи? У тебя любое изменение это миллионы долларов и сотни часов, хоть бы это один error code был. Такие цифры не вызывают никакого доверия.
Потому что я представляю себе масштабы системы, и количество мест, в которые нужно вносить изменения. Потому что я присутствую на митингах, где обсуждаются подобные решения, и озвучиваются оценки, сделанные инженерами (которым нет основания не доверять).
И речь вовсе не о любом изменении — если что-то делать легко, то мы это молча делаем, а не обсуждаем с незнакомцами на форумах.
Я попытался привести пример, который бы проиллюстрировал экстремальную ситуацию — но, вижу, понимания стало меньше, чем до примера.
Опять же про error code — это
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[60]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Ikemefula, Вы писали:
I>а вот сам рефакторинг у тебя почемуто только в теории возможен
Идеальный рефакторинг, как он описывается в теориии — да, только в теории и возможен. Плохо, что ты даже не в состоянии понять разницу.
I>Уже давно, 20 лет назад, чего и тебе желаю.
20 лет вечным джуном. Страшное наверное мучение.
Ад пуст, все бесы здесь.
Re[64]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Мирный герцог, Вы писали:
МГ>на рсдн можешь устроить голосовалку, погуглить наконец, а то пока всё это выглядит как в анекдоте "Алло, дорогая, только что по радио передали, что один псих едет по встречке. Будь осторожнее. — Один??? Да их тут тысячи!".
Когда TRK писали свой Юникс, то их было трое против мнения всех остальных программистов мира, которые крутили пальцами у своего коллективного виска. Так что хреновый аргумент.
Ад пуст, все бесы здесь.
Re[71]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Poopy Joe, Вы писали:
I>>Проблема в том, что у тебя слово "рефакторинг" включает в себя как возможный результат эту самую фичу PJ>Я сказал, что у меня фича и рефакторинг могу быть зависимыми.
Твое понимание уже отлито в граните:
С точки зрения бизнеса старое поведение не изменилось + добавилось новая фича — система всегда в валидном состоянии. И это рефакторининг.
Ту не просто зависимость фич и рефакторинга, а вполне конкретная проверка — бизнес у тебя вместо тестов выступает.
Далее, ты писал следующиее:
Я не могу сказать, что оно неправильное, поскольку правильного, отлитого в граните не существует. На практике я никогда такого узкого понимания не встречал, и ни в одном определении нет ничего про классы, но и спорить тут тоже смысла нет, так как нет истины.
Здесь ты написал, что методологию от её автора ты не читал. Вероятно, изобрёл свою, но название было слишком звонким, что бы пройти мимо?
I>>Безопасные это только те, где есть максимальные гарантии, включая юнит-тесты и многое другое, а не выборочные(конкретный юзер видит или не видит). PJ>А кто тебе сказал, что юнит-тесты в какой-то момент переставали работать?
Ты же и сказал, что проверяешь бизнесом Фаулер же говорит о том, что должны быть тесты, при чем не абы какие.
I>>Отсюда ясно, что подлянки нужно ждать от этих 20% а не откуда угодно, как у тебя PJ>Дай определение подлянок.
Здравствуйте, Sinclair, Вы писали:
S>почти не меняются.
"Почти" не считается.
И в самой книге Фаулер объясняет, что же такое внешнее, наблюдаемое поведение
"Никто — ни конечный пользователь, ни программист — не сможет сказать по внешнему виду, что что-то изменилось"
И это мы еще даже не начали говорить о многопоточности.
Здравствуйте, Sinclair, Вы писали:
S>Нет. Потребую соблюдать ещё большую осторожность. И все идеи типа "мы сейчас совместим фиче-девелопмент с багфиксом и рефакторингом" буду встречать со скептическим энтузиазмом.
Поточнее в чем это будет выражаться? Ну параметры местами переставлять нельзя, мы уже выяснили, что это слишком рискованно без поддержки тулзов. А что можно?
S>Всё верно, именно так всё и звучит — решить проблемы в текущем коде затруднительно; его надо сначала отрефакторить.
Не-не, не додумывай. Смысл именно в том, что если отрефакторить, многих проблем не будет.
S>Это вы почему-то считаете, что этой фразой люди подразумевали решение проблем путём рефакторинга, или одновременное решение-и-рефакторинг.
Я не думаю, я точно знаю. Я говорю только о том, что сам видел, без ссылок на 100500 программистов.
S>Ещё иногда при подобных разговорах люди добавляют "а перед тем неплохо бы обложить код тестами, чтобы при рефакторинге его не порушить".
Ну, это всегда неплохо.
PJ>>Если бы это было проще и дешевле поддерживать, то все бы так и делали, а зачем-то заморачиваются... S>Все как раз так и делают. Вы кругом-то посмотрите.
Поточнее куда смотреть. Я такого не вижу, во всяком случае чтобы говорить "все так делают". Может быть все у вас так делают.
PJ>>Я тут вроде ниче не считал. S>Ну как же. Вам хотелось сделать финансовый аргумент поабсурднее, чтобы легче было его отбросить. "Смена кода ошибки... миллионы долларов... пфе, чушь".
А типа берем 100к умножаем на 30, потому что 30 можем, выглядит менее абсурдно что ли?
S>. Из вот таких вот 3k быстро набегают сотни тысяч, как только у вашего API становится чуть больше, чем дюжина клиентов.
У нас больше дюжины клиентов. Причем каждому надо с обновлением гонца отправить. Это не веб, где обновления просто определению должны быть дешевыми. Однако ни про какие сотни тысяч ущерба я не слышал. Но куда нам пейзанам, вы же одни живете в реальности, а остальные так картошкой по полям промышляют...
S>Ну, вы видите разделение ролей так. А можно смотреть и под другим углом: модуль пишет "куда-то", которое умеет само вычислять хеши от всего, что насохраняли все модули. И само умеет проверять, живы файлы или нет, перед тем, как отдать их на чтение модулям.
Разумеется оно так и сделано. Даже странно тут предполагать обратное. Была команда File.Save возвращающая void, стала команда MyFile.Save, возвращающая версию и хеш. Нахрена бы это в модуле считать?!
S>А то завтра окажется, что у модуля бинарный конфиг, в котором 000....00000000000000000000 — это валидный блок, он и зачитает битый файл, не чихнув.
А вот это как раз значения не имеет. Если битый блок по значению совпадает с небитым, то разницы между ними нет.
S>А что, никто не берётся? Напишите в форум "Архитектура" — советчиков набежит столько, что отбиваться устанете.
Бесплатно? Нет. Да еще и хрен найдешь кого, заказывали как-то внешний аудит кода — туфта на выходе.
На РСДН FP считается чем-то средним между лженаукой и черной магией, а DDD бесполезной штукой. Нахрен такие оценщики?
S>Отчего же? Именно так и написано. В Entity-Relationship терминологии "связь" с такой кардинальностью означает наличие not null атрибута.
В базе данных. А причем тут API? Вы че базу данных напрямую выставляете?
S>Ну какие же они внутренние? Это прямо часть ТЗ, написанного бизнес-аналитиком.
Опять рояль в кустах? Из требования "ордер всегда привязан к подписке" никак не следует требование ид подписки во внешнем апи.
S>Эмм, то есть вместо разумного API, который позволяет получить пачку ордеров по некоторым критериям, вы предлагаете на ровном месте лепить K методов получения GetOrderTotalsById, GetOrderCustomerById, и т.п, и тому, кто захочет банально показать заказы на экране, придётся делать N*M+1 вызовов API. Нуу.... как бы в моём уютном мирке это как раз bad design — мы получаем медленный API, неудобный в использовании. И, да, — никаких преимуществ типа "дополнительной гибкости" и т.п. мы взамен не получаем.
Ну если все доводить до идиотизма, то можно и так. А можно сделать один метод GetAvailableProperies где все вернуть в виде списка.
S>Да нет, всё я верно угадал.
Да вообще пальцем в небо.
S>Внезапно оказывается, что внешние разработчики вполне способны к распознаванию паттернов. И если у вас OrderID имел несчастье быть семантически нагруженным (типа BO000001 — это billing order, SO999999 — это Sales order), а потом вы внезапно решили эту систему изменить — ждите беды. Даже если вы заботливо описали сигнатуру как "просто string".
Т.е. даже зная, что вокруг вас одни идиоты, вы закладываетесь на такие риски, вместо радномизации паттернов, что вам стоило ровно один дополнительный вызов функции? Месье понимает только в извращениях.
S>Поэтому да, надо исходить при проектировании API именно из этого! Надо такие вещи учитывать, и желательно заранее. Вашим API будут пользоваться неквалифицированные люди, у которых не стоит задача "сделать как можно более красивый и надёжный код", у них с вероятностью 99% будет стоять задача "запилить побыстрее, чтобы оно хоть как-то работало", а все косяки в их реализации будут падать на вас: "ваш API опять глючит, вот только вчера всё работало, а сегодня выдаёт ошибку".
Я не верю, что вы можете угодить всем с таким подходом. Через какое-то время это все просто встанет колом не позволяя добавить даже то, что очень нужно.
S>Если вы приходите в проект, где два архитектора назад было принято решение выставить подобные ID наружу, то таки надо предполагать худшее — что буква S имеет сакральное значение для самого прибыльного клиента; и что на прямой вопрос "важна ли вам буква S" он запросто соврёт — потому что реально понимающий в этих вопросах человек обитает где-то в глубинах их корпоративной иерархии (если он вообще ешё доступен), и никто не бросится его разыскивать для разговора с вами, а ответит вам тот человек, чьё время стоит меньше всего в компании клиента (и с соответствующим уровнем квалификации).
Да?! А у нас, у каждого подразделения, есть специальный как минимум один специальный людь, который общается заказчиками и выясняет, что им реально надо, и что для них сакрально, а что нет. И ты представляешь, не врут. А всячески готовы идти на встречу и помогать, потому что наш успех это и их успех тоже. И вообще люди с друг-другом могут договариваться и сотрудничать. Здорово, правда? Может вам тоже попробовать?!
S> Ну и что. Вот я вижу "пакет ордеров и контрольную сумму". Каким образом я при помощи этих данных пойму, что у меня после N вызовов на руках все ордера?
Путем сравнение двух чисел результата GetTotalOrders и цепочки твоих. Это вот ровно то, что ты просил. Справишься? Если тебе надо знать в любой момент времени, то возвращать можно пару, текущую и ожидаемую полную.
PJ>>В каком месте ты у меня нашел инструкции? S>А, это я забежал вперёд.
Т.е. то, что я пишу в принципе не существенно, все ответы уже готовы далеко вперед?!
S>Извините. Давайте продолжим — я всё ещё хочу понять, каким образом сигнатура метода мне опишет эквивалентность GetOrdersBatch(1) + GetOrdersBatch(2) с GetAllOrders().
Парой строчек выше. Это ты вот такое "инструкцией" называл? У вас в клиентах дурдом что ли? А как они поймут, что GetOrderTotal возвращает возвращает сумму всех ордеров? Для этого же нужна еще одна инструкция, надо же догадаться посмотреть в ответ...
S>Ну, как я понимаю, в теории при помощи Зависимых Типов и прочих ФВП можно описывать значительно более сложные API, чем при помощи выразительных средств типа "OOP на Java". S>Но на практике это всего лишь означает, что у вашего API будет 0 клиентов.
Как там это называется "парадокс блабла" или как-то так. В общем, все что у нас нет — туфта и не работает.
S>Потому что я представляю себе масштабы системы, и количество мест, в которые нужно вносить изменения. Потому что я присутствую на митингах, где обсуждаются подобные решения, и озвучиваются оценки, сделанные инженерами (которым нет основания не доверять).
Да рыбаки тоже представляют какую рыбу они могут поймать, а врут напропалую.
Re[72]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Ikemefula, Вы писали:
I>>>Проблема в том, что у тебя слово "рефакторинг" включает в себя как возможный результат эту самую фичу PJ>>Я сказал, что у меня фича и рефакторинг могу быть зависимыми.
I>Ту не просто зависимость фич и рефакторинга, а вполне конкретная проверка — бизнес у тебя вместо тестов выступает.
Бизнес определяет требования. Они не поменялись. И они проверяются не только тестами.
Какая часть тут до тебя не дошла? Фича это не обязательно то, что ты продаешь. Это можеть быть внутренняя. Мне похрен а какой книжен ты нашел другое определение, это вообще не термин.
I>Здесь ты написал, что методологию от её автора ты не читал. Вероятно, изобрёл свою, но название было слишком звонким, что бы пройти мимо?
Вероятно ее ты не понял, но вообразил себя ее толкователем.
I>Ты же и сказал, что проверяешь бизнесом Фаулер же говорит о том, что должны быть тесты, при чем не абы какие.
Ты ты не понял фразу, но уже высосал множество выводов? Я не очень понимаю чего ты от меня хочешь? Если ты хочешь о чем-то пофантазировать за меня, то не стесняйся. Просто будет быстрее, если сам с собой в блокнете будешь строчить.
I>>>Отсюда ясно, что подлянки нужно ждать от этих 20% а не откуда угодно, как у тебя PJ>>Дай определение подлянок.
I>Любой баг.
Невозможно гарантировать изменение кода без вероятности внесения бага. Точка.
Re[35]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Codealot, Вы писали:
_AB>>Остальное читать не буду, ибо ты пока поднадоел, а тут есть дискуссия поинтереснее. C>То есть — ты уже и сам понял, что облажался, и не видишь способа выкрутиться.
Не тешь себя ложной надеждой, что ты смог кого-то переспорить.
Просто пока в тебя палочкой скучно тыкать. Есть поинтереснее дела.
C>Что-то выдавало Штирлица нарцисса...
Ты реально думаешь, что кто-то здесь общается не ради своего удовольствия? Ты еще глупее, чем я думал...
И да, получение удовольствия не явлется нарциссизмом, если ты еще не понял. Как и тыкание палочкой в какого-нибудь жучка.
Но раз уж ты смог заинтересовать меня снова, давай рассмотрим признаки нарциссизма:
1. Грандиозное самомнение
Это ты считаешь всех менеджеров глупее себя, не я.
И сразу предупрежу, что то, что я считаю тебя, Мразеца, шымжу и некоторых других глупыми, не означает, что у меня грандиозное самомнение. Несомненно, тот же Синклэр, IT, Мамут и многие другие намного умнее меня. Большинство примерно равны мне, т.к. я ума среднего.
2. Поглощенность фантазиями о неограниченном успехе, власти, великолепии, красоте или идеальной любви;
Это точно не про меня.
3. Вера в свою «исключительность», вера в то, что должен дружить и может быть понят лишь себе подобными — «исключительными» или занимающими высокое положение людьми;
Ты считаешь, что к тебе должны особо относиться при приеме на работу и что менеджеры должны тебя слушать, т.к. все они идиоты, неспособные принять обоснованное решение.
4. Нуждается в чрезмерном восхвалении;
Ты не можешь успокоиться, когда кто-то публично заявил тебе в лицо, что считает тебя человеком недалекого ума. Готов судиться даже.
5. Ощущает, что имеет какие-то особые права;
Возвращаемся к вопросу об интервью. Ты считаешь, что имеешь особые права.
6. Использует других для достижения собственных целей;
Опять-таки та же тема. Ты готов заставить других изменить принципы подбора персонала ради того, чтобы тебя приняли.
7. Не умеет сочувствовать;
Тут ничего сказать не могу про тебя.
8. Часто завидует другим и верит, что другие завидуют ему;
9. Демонстрирует высокомерное, надменное поведение или отношение.
Это вообще с тебя списано. Ты можешь попытаться натянуть пункт 9 на меня, но пункт 8 никак не сможешь.
Итого у тебя минимум 5 пунктов из 9 наблюдается в сообщениях, а можно при желании и 7 засчитать. У меня 1 пункт при желании можно засчитать.
Re[57]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, Poopy Joe, Вы писали:
PJ>Не, в этот момент технический долг дал о себе знать. Существовал он с момента, когда вы начали что-то делать на предположениях
Интересно, когда до тебя дойдет, что всегда софт разрабатывается на основе предположений той или иной степени детализированности и подтвержденности...
PJ>и выставлять наружу модель, даже не имея представления зачем и кому она нужна.
Ну передергивание же. Некрасиво...
Разумеется, они знали, что именно клиенты полагают нужным. Проблема в том, что всегда есть какие-то вещи, которые полагались ненужными, либо которые вообще не были актуальны на момент опроса. По факту они стали нужными позднее.
Тот, кто полагает, что он всё знает заранее, либо дурак, либо просто никогда не разрабатывали ничего сложнее лабораторных работ первого-второго курса.
Вот, например, клиент заказал разработку системы, которая должна перевернуть его индустрию. Клиент очень много усилий и денег посвятил разработке модели, дизайна, общался со своими клиентами, опираясь на свой огромный опыт в индустрии писал ТЗ. Делал презентации, собирал фидбек. Собирал группы клиентов и проводил практические сессии. Он потратил несколько месяцев на это. Мы сделали всё, как просили. Оказалось, что предположения, которые делали и клиент и клиенты клиентов по поводу того, как им хотелось бы работать с системой, оказались несколько неверными. Причем в некоторых вещах кардинально неверными. К счастью, т.к. и наш клиент и мы сами имеем опыт работы, мы с самого начала ориентировались на выпуск MVP с последующей переоценкой, поэтому "много денег и усилий" не оказалось "чрезмерно много денег и усилий" и большую часть разработанного можно использовать или переделать с минимальными потерями.
Однако, этот пример отлично демонстрирует то, что в основе разработки всегда лежат предположения. Которые могут оказаться неверными, даже если ты лидер индустрии с 35% рынка или сколько там у них сейчас...
Ваш пример с дисковым кэшем тоже отличный пример предположения. Вы предполагали, что на дисковую подсистему можно полагаться всегда. Ваше предположение оказалось неверным. Вы сейчас работаете с проектом, которому 20 лет. Разумеется, большая часть предположений для этого проекта была проверена в первые несколько лет. Однако, я уверен, что сейчас вы тоже что-то дорабатываете и перерабатываете. В том числе и потому, что ранее сделанные предположения оказались ошибочными или не выдержали проверки временем.
PJ>Есть множество практик как подобного избегать, то же DDD например.
Ну и как эта практика помогает полностью избежать неопределенности, сложности и изменчивости окружающего мира?
Re[36]: Годами не могу вырваться из некорректных вопросов на
Здравствуйте, _ABC_, Вы писали:
_AB>Не тешь себя ложной надеждой, что ты смог кого-то переспорить.
Как ни странно, тут ты прав. Вся публика как на подбор, хоть колья на головах теши.
_AB>Ты реально думаешь, что кто-то здесь общается не ради своего удовольствия? Ты еще глупее, чем я думал...
Я реально думаю, что цели у всех разные, как и способы получения удовольствия. "тыкать палочкой", как ты выразился — это типично нарциссическое поведение. Точнее — еще оно характерно для садизма, психопатии и макиавеллианизма, но на этих ты вряд ли потянешь. Еще, схожее поведение бывает при СДВГ. В твоем случае, вполне возможный вариант.
_AB>Это ты считаешь всех менеджеров глупее себя, не я.
1. Врёшь, я такого не писал.
2. Как мы уже выяснили, ты считаешь себя крупным специалистом по неврологии, логике и лингвистике (добавь, если я что-то пропустил). Правда, решить несложную задачку по программированию почему-то не в состоянии.
Итого, неадекватное самомнение — оно у тебя есть.
Еще одно качество нарциссов — патологическая лживость — тоже есть.
_AB>Ты не можешь успокоиться, когда кто-то публично заявил тебе в лицо, что считает тебя человеком недалекого ума.
Ну во первых, ты сделал это не публично, а под прикрытием анонимной личины. Сделать это в открытую ты не в состоянии, потому что слишком труслив. Даже с учетом того, что ты вряд ли живешь в стране, где за это может реально прилететь.
_AB>Готов судиться даже.
Во вторых — ты опять врешь, причина была совершенно другая.
_AB>Возвращаемся к вопросу об интервью. Ты считаешь, что имеешь особые права.
Никаких особых прав — было бы достаточно убрать дискриминацию. (мечты, мечты)
_AB>8. Часто завидует другим и верит, что другие завидуют ему;
Чувак, ты реально бредишь. Никто совершенно точно не станет завидовать мне и моим проблемам.
Ну и так далее. Ты врёшь буквально на каждом шагу.
Или, возможно, у тебя всё же СДВГ и ты просто не в состоянии запоминать дальше чем на пару предложений назад. Остальные симптомы — неадекватное самомнение, графомания, отсутствие способности к эмпатии — всё сходится.
На хабре, кстати, была статья от чувака с СДВГ. Только он куда адекватнее тебя
Почитай, вдруг поможет. В отличие от нарциссизма, это всё же лечится, хотя и в ограниченных пределах.
Здравствуйте, Poopy Joe, Вы писали: PJ>Поточнее в чем это будет выражаться? Ну параметры местами переставлять нельзя, мы уже выяснили, что это слишком рискованно без поддержки тулзов. А что можно?
Можно менять структуру кода, без изменения семантики.
PJ>Не-не, не додумывай. Смысл именно в том, что если отрефакторить, многих проблем не будет.
Каких например?
S>>Все как раз так и делают. Вы кругом-то посмотрите. PJ>Поточнее куда смотреть. Я такого не вижу, во всяком случае чтобы говорить "все так делают". Может быть все у вас так делают.
Возьмите любой браузер или веб-приложение. Вон, докерс при попытке заказать товар с доставкой на адрес почтового агрегатора выдаёт "card authorization failure", хотя деньги успешно встают на hold.
Просто парни, которые писали фронт-енд, на все исключения из place order выдают одно и то же: в их практике проблемы были только с платёжной системой, а delivery сроду ничего не выбрасывала.
Стоит один catch на всё.
PJ>А типа берем 100к умножаем на 30, потому что 30 можем, выглядит менее абсурдно что ли?
30 — это минимальное количество компаний, которые потребляют API, о котором я говорю.
PJ>У нас больше дюжины клиентов. Причем каждому надо с обновлением гонца отправить. Это не веб, где обновления просто определению должны быть дешевыми. Однако ни про какие сотни тысяч ущерба я не слышал. Но куда нам пейзанам, вы же одни живете в реальности, а остальные так картошкой по полям промышляют...
А вам вообще рассказывают хоть что-то про деньги, или всё же есть изоляция между модулями инженеров и продавцов? Ну, вот сколько стоит разослать гонцов с обновлениями каждому клиенту?
Сколько стоит установка обновления на каждом из них — уже не вам, а им?
Сколько стоит простой одного клиента в день, если присланное обновление не работает? Понятно, что лично с вас эти деньги не спросят, но ущерб-то будет нанесён.
Если в вашем случае это всё копеечные деньги — считайте, что вам повезло. Это не означает, что можно распространять вашу отвагу в принятии технических решений на области, где крутятся другие деньги.
Понимаете, уборщица, выдергивающая кабель из сервера, тоже может говорить "что-то я не слыхала ни про какие сотни тысяч ущерба".
PJ>Разумеется оно так и сделано. Даже странно тут предполагать обратное. Была команда File.Save возвращающая void, стала команда MyFile.Save, возвращающая версию и хеш. Нахрена бы это в модуле считать?!
Ну вы же сами написали, что модули теперь должны передавать куда-то хеш для снапшота.
S>>А что, никто не берётся? Напишите в форум "Архитектура" — советчиков набежит столько, что отбиваться устанете. PJ>Бесплатно? Нет. Да еще и хрен найдешь кого, заказывали как-то внешний аудит кода — туфта на выходе. PJ>На РСДН FP считается чем-то средним между лженаукой и черной магией, а DDD бесполезной штукой. Нахрен такие оценщики?
Вот видите, вам уже оценки не нравятся.
S>>Отчего же? Именно так и написано. В Entity-Relationship терминологии "связь" с такой кардинальностью означает наличие not null атрибута. PJ>В базе данных. А причем тут API? Вы че базу данных напрямую выставляете?
ER — это не про базу данных. Это формализация описания модели; очень часто используется для моделирования благодаря своей простоте.
PJ>Опять рояль в кустах? Из требования "ордер всегда привязан к подписке" никак не следует требование ид подписки во внешнем апи.
А, вы хотите прямо так? Не, из бизнеса выпадают требования вроде "обеспечить возможность выгрузки ордеров со всеми атрибутами для синхронизации во внешнюю систему". С учётом того, что никакой внешней системы ещё нет, более детальных требований вы не получите. Просто сейлзы говорят "мы обсуждали с проспектом нашу систему, они спросили 'а у вас есть возможность выгрузки ордеров со всеми атрибутами для синхронизации во внешнюю систему', и мы сказали 'да', потому что на кону сделка на 700k, и конец квартала".
PJ>Ну если все доводить до идиотизма, то можно и так. А можно сделать один метод GetAvailableProperies где все вернуть в виде списка.
И получаем те же яйца, вид сбоку. Вы всего лишь отложили проблему до вызова GetAvailableProperties, и по-прежнему оставили N+1 вызов API вместо 1. PJ>Да вообще пальцем в небо.
PJ>Т.е. даже зная, что вокруг вас одни идиоты, вы закладываетесь на такие риски, вместо радномизации паттернов, что вам стоило ровно один дополнительный вызов функции? Месье понимает только в извращениях.
Мы — нет. Но нам не всегда доступна роскошь переписать огромную систему целиком только потому, что в 2005 году у архитекторов не было того опыта, который есть у нас в 2020.
PJ>Я не верю, что вы можете угодить всем с таким подходом. Через какое-то время это все просто встанет колом не позволяя добавить даже то, что очень нужно.
Конечно. И тогда мы перейдём к другим методикам. А пока мы извлекаем деньги из этой скважины — наиболее эффективным методом.
PJ>Да?! А у нас, у каждого подразделения, есть специальный как минимум один специальный людь, который общается заказчиками и выясняет, что им реально надо, и что для них сакрально, а что нет. И ты представляешь, не врут. А всячески готовы идти на встречу и помогать, потому что наш успех это и их успех тоже. И вообще люди с друг-другом могут договариваться и сотрудничать. Здорово, правда? Может вам тоже попробовать?!
У нас тоже есть люди, которые общаются с заказчиками. И у многих заказчиков есть технические менеджеры, которые отвечают за поддержание всего бегемота на плаву.
И тем не менее, всегда есть какие-то моменты, которые выяснить не удаётся. Есть клиенты, которые сами в технике ни бум-бум, код интеграции писал какой-то бодишоп в тропическом поясе, но нам показать его не могут, потому что NDA и IP Rights — и мы по полгода и больше занимаемся "согласованием намерений". Есть клиенты, которые думают, что у них одно, а на самом деле — другое.
А есть клиенты, с которыми у нас прекрасное взаимодействие, и регулярные технические звонки.
Просто обзвонить всех клиентов, которые могут пострадать от какого-либо изменения, займет больше трёх суток — это если делать это непрерывно, и пренебрегать разницей в часовых поясах, и предполагать, что все из них готовы разговаривать вот прямо сейчас, и что они готовы прямо сходу ответить на вопрос.
S>> Ну и что. Вот я вижу "пакет ордеров и контрольную сумму". Каким образом я при помощи этих данных пойму, что у меня после N вызовов на руках все ордера? PJ>Путем сравнение двух чисел результата GetTotalOrders и цепочки твоих. Это вот ровно то, что ты просил. Справишься? Если тебе надо знать в любой момент времени, то возвращать можно пару, текущую и ожидаемую полную.
Так. Я правильно понимаю, что GetTotalOrders возвращает только контрольную сумму?
А откуда я знаю, что из совпадения этого числа с какой-то формулой от нескольких результатов GetOrdersBatch(x) что-то следует? Откуда я знаю эту формулу?
PJ>Парой строчек выше. Это ты вот такое "инструкцией" называл? У вас в клиентах дурдом что ли? А как они поймут, что GetOrderTotal возвращает возвращает сумму всех ордеров? Для этого же нужна еще одна инструкция, надо же догадаться посмотреть в ответ...
Так я и думал. Сначала идёт бравада, а потом фейспалмы. Оказывается, никакая сигнатура не описывает соотношения между результатами разных вызовов — ну, кроме того, что результат одного можно подставить в другой.
Оказывается, всё ещё нужно писать API Guide, в котором описывать словами все эти соотношения. А без гайда этот API — всего лишь россыпь каких-то методов.
Оказывается, компилятор не станет проверять, вернули ли мы все ордера или часть потеряли.
PJ>Как там это называется "парадокс блабла" или как-то так. В общем, все что у нас нет — туфта и не работает.
Откуда ж я знаю, что у вас есть? Я вашего API не видел. А то, что вы предлагаете в качестве ответов на микро-вопросы, выдаёт ваш нулевой опыт в разработке и поддержании API для внешних клиентов.
Я верю, что вы можете придумать очень хорошую архитектуру замкнутой системы — в которой компилятор поможет вам контролировать инварианты. Но вот в вашу способность спроектировать приличный web API верится с трудом.
PJ>Да рыбаки тоже представляют какую рыбу они могут поймать, а врут напропалую.
Я думаю, на этом мы закончим беседу в связи с утратой конструктивности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.