Pull to refresh

Comments 292

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

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

Нет, автор хотел сказать, что в принципе невозможно написать хорошо расширяемый код.
Я про это и говорю. Расширять под заранее неизвестные требования сложно. Угадать, какие будут требования — тоже. Это прекрасно известный факт, не какое-то открытие.
Математически невозможно доказать (для произвольной программы) даже то, что она корректно завершит свое выполнение. Про то что будет получен корректный результат для всех входных данных и не говорю.
Без полной смены парадигмы вычислительной техники и принципов программирования тут не обойтись, проблема именно в самой парадигме.
Думаю программистам следует готовиться к потере всех накопленных знаний и умений за пределами программирования, старенькие на пенсию, молодые в торговлю (у большинства нет практически пригодных знаний и умений, да и с физической силой для работы на «стройке» тоже проблемы).

Минусаторам — понимаю обидно, когда начинаешь понимать свою проблему (даже бессмысленность своих усилий в программировании), но ответить нечем )))))
бессмысленность своих усилий в программировании

Хм, "бессмысленность усилий в программировании", когда успешно долгие годы зарабатываешь этим деньги — это любопытно, да. Расскажете поподробнее, что же такого бессмысленного?

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

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

Попробую пояснить свою позицию «на пальцах» — местное «население» плохо относится к философии.
В настоящее время программирование похоже на вязание, каждая команда связывает некоторое количество данных в результат, при этом ничего кроме именно этих конкретных данных не учитывается. Человеческий мозг устроен так что не может одновременно анализировать (принимать во внимание взаимосвязи) больше чем 5-7 сущностей.
В реальности, вычислительная машина должна обрабатывать на много порядков больше данных (объектов), и в геометрической степени больше их свойств и сочетаний.
С практической точки зрения это приводит к невозможности написать код гарантирующий корректность исполнения. Даже если взять идеального программиста, то результатом его работы будет программа практически бесконечного размера (ее просто не получится сохранить на любом реальном накопителе).
Квалифицированные программисты это понимают и потому даже не пытаются писать «идеальную программу», а просто закладывают некоторый объем финального тестирования (или вероятность сбоя).
Кроме того вероятность краха возрастает с увеличением размера взаимодействующего кода, и приводит к тому что практически невозможно написать программу размером больше определенного. Надежность такой программы падает ниже «плинтуса», а трудо-затраты улетают в небеса и никакое тестирование не спасает ситуацию (из программистского фольклора известно, что исправление одной ошибки порождает две новых).
В настоящее время программистов и их работу терпят как меньшее зло, но как только появится новая вычислительная парадигма их отправят на «свалку», как в свое время поступили с трудом ткачей, пахарей и тд.

Все нытье про стили программирования, скорее относится к воспитанию конкретных исполнителей, что бы они уж совсем не расслаблялись. Программирование труд во многом коллективный, значит в нем раздолье в плане обвинить в своих ошибках соседа )))

Если кратко то ситуация примерно такая.
это никак не сказывается на практической ценности результата их работы.

Ммм, то есть то, с помощью чего вы сейчас со мной общаетесь — это не практическая ценность? Ну ок, хорошо, если так.


Ну или вот вам другой пример: раньше люди тратили на обработку складских документов два часа в день, а после того, как там поработал программист — стали тратить пять минут в день. Это не практическая ценность?


В настоящее время программирование похоже на вязание, каждая команда связывает некоторое количество данных в результат, при этом ничего кроме именно этих конкретных данных не учитывается.

Я так понимаю, этот вывод вы делаете на основании собственного опыта?


С практической точки зрения это приводит к невозможности написать код гарантирующий корректность исполнения.

Неа, не приводит. Нет никакой связи между "человеческий мозг может одновременно обрабатывать не более" (кстати, это тоже не совсем правда) и "машина должна обрабатывать на много порядков больше".


С практической точки зрения это приводит к невозможности написать код гарантирующий корректность исполнения.

Отнюдь. Вполне возможно написать код, гарантирующий корректность исполнения в заданных условиях.


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

… а зачем мне писать программу "размером больше определенного"?


как только появится новая вычислительная парадигма

Нуууу… когда появится, тогда и поговорим. Пока что лично я не слышал ни о каких теоретических обоснованиях для новой, как вы выражаетесь, "вычислительной парадигмы", которая была бы лишена описанных выше проблем.

Извините, меня здесь не «любят» и потому я не могу сильно часто писать.
Я так понимаю, этот вывод вы делаете на основании собственного опыта?

Это математически доказанные выводы, к сожалению быстро ссылку на доказательство предоставить не могу.
… а зачем мне писать программу «размером больше определенного»?

Для решения поставленной задачи.
Отнюдь. Вполне возможно написать код, гарантирующий корректность исполнения в заданных условиях.

Уже лучше, но тогда ваша задача никогда не будет исполнена — условия для исполнения не подходящие, а если сильно ослабить «условия» вернемся к исходному состоянию отсутствия надежности.
Нуууу… когда появится, тогда и поговорим.

Думаю вы на пенсию не успеете — придется в центре занятости переучиваться.
Это математически доказанные выводы

Извините, я вам не верю. Я считаю подобное "математическое доказательство" невозможным. Вы читали "The Leprechauns of Software Engineering"?


к сожалению быстро ссылку на доказательство предоставить не могу.

К сожалению, пока вы ее не предоставите, я буду продолжать думать, что это исключительно ваше личное мнение.


Для решения поставленной задачи.

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


тогда ваша задача никогда не будет исполнена — условия для исполнения не подходящие

Вы ничего не знаете о моей задаче, но уже говорите, что она не будет исполнена. Как так?


если сильно ослабить «условия» вернемся к исходному состоянию отсутствия надежности

Что такое "отсутствие надежности"? Надежность — это не булева величина, это спектр. Можно написать такую программу, которая будет достаточно надежна для ее использования в заданных условиях. Скажем, человек допускает одну ошибку на 1000 строк гроссбуха. Программа — 1 на миллион. Это не 100% "надежность", но это в тысячу раз надежнее человека. Человек работает 8 часов в сутки, 5 дней в неделю. Программа работает, скажем, 23 часа в сутки и 6 дней в неделю (это, заметим, на несколько порядков ниже, чем требования, предъявляемые к современному LoB) — это все равно больше чем в три раза дольше, чем человек.


Думаю вы на пенсию не успеете — придется в центре занятости переучиваться.

А я думаю, что это ваше ожидание не основано ни на чем, кроме вашего личного мнения.

ermak.cs.nstu.ru/cprog/html/038.htm
Естественным источником алгоритмически неразрешимых проблем является самоприменимость алгоритмов, т.е. применение программ к анализу свойств других программ. К программированию имеют отношение самые неутешительные выводы теории алгоритмов. Начинается все с проблемы остановки машины Тьюринга: невозможно создать МТ, которая, получив на вход программу любой МТ, решает, останавливается она или «зацикливается». В двух словах, доказательство базируется на том, что такая МТ с некоторыми изменениями предъявляется на вход самой себе, что приводит к противоречию. В переводе на «естественный язык» это означает, что нельзя написать программу, которая по тексту другой программы (не исполняя ее) определяет такое ее свойство. Научно выражаясь, это алгоритмически неразрешимо.

У человеческого мозга есть еще одно свойство — он старается забыть или сгладить неприятные воспоминания (ощущения, знания). и будет отрицать надвигающиеся проблемы вплоть до их реализации в проблемы для собственного седалища )))

Думаю диспут закончен?
Думаю диспут закончен?

… похоже, книжку вы не читали. Жаль.


Так вот, приведенная вами цитата (а) вообще не является математическим доказательством (а только ссылается на проблему останова), и (б) не имеет никакого отношения к сделанному вами выше утверждению "в настоящее время программирование похоже на вязание, каждая команда связывает некоторое количество данных в результат, при этом ничего кроме именно этих конкретных данных не учитывается", в отношении которого вы и написали "это математически доказанные выводы".


Какой уж тут "диспут"...

Хорошо — тогда предлагаю возродить старинный обычай.
При первом прохождении поезда по мосту — под пролетом стоял инженер спроектировавший мост.
В вашем случае — гранату на шею, которая взорвется при некорректной работе вашей программы?

Ага, то есть от "математически доказано" переходим к аргументации "на слабо". Не, такой уровень "дискуссии" меня не интересует.

Да согласен не современно — тогда вот так: Вы платите страховой компании взносы на покрытие издержек от ошибок.

А то повадились писать: Разработчик не несет ответственности за ущерб понесенный из-за приобретенной программы.
Как спросили, так в «кусты» — Но данная проблема очень актуальна и решить ее как то нужно, представьте на автомобилях что то подобное будут писать?
Вы платите страховой компании взносы на покрытие издержек от ошибок.

… в объеме, не превышающем расходы пользователя на программу. Идет?


Прямо скажем, многие сервисные контракты включают этот пункт в том или ином виде. Не новость.


Как спросили, так в «кусты»

Это в смысле — я у вас спросил про доказательства вашим утверждениям, а вы ушли в кусты?


представьте на автомобилях что то подобное будут писать?

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


Так чем программа, которая не более чем инструмент, отличается от других инструментов?

представьте на автомобилях что то подобное будут писать?

О, кстати, автомобили. На каких автомобилях нынче пишут "мы возместим вам ваши убытки, если вы не сможете доставить ваш груз в срок с нашим автомобилем"?

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

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

Хорошо докажите, что есть возможность математически проверить, что произвольная программа корректна (всегда дает правильный результат и не виснет хотя бы по не зависящим от аппаратуры причинам)?
Хорошо докажите, что есть возможность математически проверить, что произвольная программа корректна

Я этого никогда не утверждал. Почему я должен это доказывать?

Вы оспорили мое мнение про невозможность анализа свойств программы, значит остается два варианта у Вас нет своего мнения (это опровергается вашими постами) или вы придерживаетесь другой точки зрения (согласно формальной логике вы считаете что это сделать можно).
Тогда конкретизируйте свою точку зрения и докажите ее ссылкой на научные материалы.
Отправлять ссылки на «методики» смысла нет, я могу вам тоже отправить кучу методик вызывания дождя бегающими по полю девственницами. Важны научно доказанные факты, озвученная проблема есть и ее доказали математики (пусть даже в самом простом варианте, как невозможность доказать «завершаемость» программы)
Вы оспорили мое мнение про невозможность анализа свойств программы

Где?


Тогда конкретизируйте свою точку зрения.

Я свою точку зрения уже озвучил: возможно написать программу, которая будет приносить пользу. Быть достаточно полезной и достаточно надежной, чтобы оправдать ресурсы, потраченные на ее написание.

Квалифицированные программисты это понимают и потому даже не пытаются писать «идеальную программу», а просто закладывают некоторый объем финального тестирования (или вероятность сбоя).
Кроме того вероятность краха возрастает с увеличением размера взаимодействующего кода, и приводит к тому что практически невозможно написать программу размером больше определенного. Надежность такой программы падает ниже «плинтуса», а трудо-затраты улетают в небеса и никакое тестирование не спасает ситуацию (из программистского фольклора известно, что исправление одной ошибки порождает две новых).

Тогда понятно, вы согласны с моим мнением, но вы считаете что проблема невозможности написать программу без потенциальных ошибок или не решаема или не существенна.
Тогда понятно, вы согласны с моим мнением

Я вполне четко описал с чем конкретно в ваших комментариях я не согласен. В частности, я не согласен с тем, что приведенная цитата как-то говорит о бесполезности работы программистов.


проблема невозможности написать программу без потенциальных ошибок или не решаема или не существенна.

Она, весьма очевидно, нерешаема, просто потому, что всегда есть потенциальная ошибка в задаче. Так что эту часть мы отметем. Перейдем ко второй: я не понимаю, что вы имеете в виду под "существенностью". Надо ли думать о том, что в программе могут быть ошибки? Да, надо. Надо ли делать вывод, что программы бесполезны, потому что в них могут быть ошибки? Нет, не надо. Надо думать, как уменьшить (а) вероятность и (б) последствия ошибок.

Ладно — степень важности проблемы это личное дело каждого, но для понимания наличия проблемы ее принято выделать на фоне всего остального.
Считаем что я гиперболизирую проблему, что бы ее выделить и показать границы ее влияния.

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

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

Что значит "принято"? Кем принято? Где принято?


Почему вы вообще считаете, что программисты не знают о наличии этой проблемы?


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

Соглашусь. Поэтому ПО для домашнего компьютера и космической станции разрабатывается с разными требованиями.


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

Почему это вдруг "становится невозможным"? На каких фактах и исследованиях основано это ваше утверждение?


Ну и самое главное: даже если предположить, что ПО сложнее определенного порога пока еще невозможно разработать, почему вдруг из этого вытекает, что усилия программистов по разработке ПО бессмысленны, как вы утверждали в первом своем комментарии? Есть множество ПО со сложностью меньше этого порога.

Думаю вам стоит подумать над проблемой серьезно, а то чем сейчас занимаются программисты (да и вся отрасль) это бессмысленный бег в колесе. Причем колесо ускоряется, если рань ошибки фиксировались новой версией ПО, то сейчас приходится постоянно качать обновления.
то чем сейчас занимаются программисты (да и вся отрасль) это бессмысленный бег в колесе.

Вот ровно с этим утверждением я и не согласен. И я пока не видел от вас никакого его доказательства.


По моим личным наблюдениям, конечные пользователи ПО получают, простите за тавтологию, пользу от использования. Кто-то гуляет по интернету, кто-то слушает музыку в удобных условиях, кто-то ведет бухгалтерию. Без ПО это было либо невозможно вовсе, либо требовало намного больше сил. Вы считаете производство этого ПО бессмысленным бегом в колесе? Я — нет.

UFO just landed and posted this here
Смотрите на проблему шире.
Еще один локальный пример
В процессе вычислений никак не контролируется корректность математических операций в разделе потери точности.
Вычисление среднего, вроде бы все просто. Просуммировал и поделил, но тут появляется проблема — корректно это сделать можно только для целых чисел.
Если к большому дробному числу прибавить малое, то точность малого ухудшится (а может и вообще исчезнуть). И такого рода проблем очень много.
Такие проблемы как то проверяются в средствах формального доказательства?
В процессе вычислений никак не контролируется корректность математических операций в разделе потери точности.

В смысле — не контролируется?


Если к большому дробному числу прибавить малое, то точность малого ухудшится (а может и вообще исчезнуть).

Или не ухудшится. Зависит от реализации дробных чисел, очевидно.

Выделите в выдаче компилятора предупреждение о потери точности — может я и правда отстал от жизни.
Какими служебными словами задается точность результата (не число бит в переменной а именно результата)
Выделите в выдаче компилятора предупреждение о потери точности — может я и правда отстал от жизни.

Гм, а в какой момент вы перешли от "в процессе вычислений" к "выдача компилятора"?


Какими служебными словами задается точность результата (не число бит в переменной а именно результата)

Что такое "точность результата", раз уж вы это противопоставляете "числу бит в переменной"?

Сейчас это прочно забыто, но примерно 100 лет назад при обучении инженеров уделялось достаточно большое внимание правилам выполнения математических вычислений (относительная и абсолютная точность, число значащих разрядов и тд) — к сожалению резко не ищется (выдача забивается вопросами чисел с плавающей запятой и тд)
Если интересна проблема, то сами поищите.
правилам выполнения математических вычислений

Правила выполнения математических операций (включая точность) прекрасно существуют и сейчас в рамках как специализированного ПО, так и ПО общего назначения.


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

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

Нет.


И как называется — с удовольствием прочитаю.

Не откажу себе в удовольствии, извините: "если интересна проблема, то сами поищите".

UFO just landed and posted this here
Ахах, да ты кажется не понял, что такое проблема остановки, которую сам же приводишь как аргумент

Создать машину которая решит эту проблему для произвольной программы — невозможно

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

Я именно поэтому, собственно, и спрашиваю регулярно "а как эта конкретная проблема относится к обсуждаемому вопросу". Обычно выясняется, что никак, потому что приводящий ее человек проблему понимает… превратно.

Выполнить эту задачу?
А если проблема возникает только в при определенных данных.
Но это не важно, я хочу обратить внимание на то что сложность (объем взаимодействующих объектов) типичной программы столь велико, что программист не может гарантировать их корректное взаимодействие.
А если проблема возникает только в при определенных данных.

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


программист не может гарантировать их корректное взаимодействие.

Определите "гарантировать" и "корректное".

Вы читали «The Leprechauns of Software Engineering»?


Ворвусь в ваш диалог.

Советуете почитать?

Очень советую. Начало и первый кейс или два вообще прекрасны, дальше она начинает повторяться, потому что подход один и тот же, но все равно поучительно.

Для использования в корпоративной «религии» и воспитания кадров вполне подойдет, что бы все шагали «в ногу».
С точки зрения решения проблемы никак, какие бы методики управления вы не применяли это не поможет например обойти законы физики и сконструировать «вечный двигатель».
А вы читали?
Я вроде не собирался обходить законы физики, или вам вообще не принципиально с кем спорить и кого убеждать в неправоте?
Что такое "отсутствие надежности"? Надежность — это не булева величина, это спектр. Можно написать такую программу, которая будет достаточно надежна для ее использования в заданных условиях. Скажем, человек допускает одну ошибку на 1000 строк гроссбуха. Программа — 1 на миллион. Это не 100% "надежность", но это в тысячу раз надежнее человека. Человек работает 8 часов в сутки, 5 дней в неделю. Программа работает, скажем, 23 часа в сутки и 6 дней в неделю (это, заметим, на несколько порядков ниже, чем требования, предъявляемые к современному LoB) — это все равно больше чем в три раза дольше, чем человек.

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

Проблема скорее в том, что мы стали доверит машинам абсолютно.

Это проблема не машин, а ожиданий. И да, ожидания надо правильно формировать (и лично я, в рамках своей работы, стараюсь это делать).


а если они происходят в одном случае из миллиона, но при этом от этого может зависеть жизнь человека?

А что, если от незаметной ошибки человека зависит жизнь другого человека? Кто-то где-то чуть-чуть ошибся в составе цемента, через 30 лет обрушилось здание, из-за ошибки конкретного человека, который уже может и помер давно, погибло несколько сотен людей. И?..

А что, если от незаметной ошибки человека зависит жизнь другого человека?

для этого есть ответственность. В случае людей — все понятно. По сути кто накосячил — тот и виноват. Когда в это вмешивается машина — все становится сложнее. Кто виноват? Оператор, который пользуется ПО (и проглядел ошибку в выходных данных), или разработчик ПО (который допустил погрешности в алгоритме)? А тут все становится еще интереснее, учитывая, что весь софт предоставляется AS IS

В случае людей — все понятно.

Ах если бы.


Когда в это вмешивается машина — все становится сложнее. Кто виноват? Оператор, который пользуется ПО (и проглядел ошибку в выходных данных), или разработчик ПО (который допустил погрешности в алгоритме)?

Замените ПО на "инструмент". Любой инструмент. Газовую плиту. Кто виноват в пожаре — производитель плиты, у которого не сработал клапан безопасности при задувании пламени, или повар, который не заметил, что пламя задуло?

Проблема в том, что в случае плиты неисправность очевидна. Ну, или почти. Я уж не говорю о том, что существует допуск к работе с ней (сданные нормативы по противопожарке и все прочее). В случае ПК — все считается само собой разумеющимся. На фоне тотальной деградации уровня сотрудников любого класса (в первую очередь — операторов колл-центра и прочих сотрудников, работающих с клиентами).

Проблема в том, что в случае плиты неисправность очевидна. Ну, или почти. Я уж не говорю о том, что существует допуск к работе с ней (сданные нормативы по противопожарке и все прочее).

Прекрасно. Так кто виноват-то?


А потом перейдем к немножко более сложному примеру: арифмометру. Все то же самое, только арифмометр иногда слегка заедает и ошибается на один знак. Кто виноват — производитель или пользователь?


В случае ПК — все считается само собой разумеющимся.

Считается. Может быть, виноват тот, кто так считает? Как раз?

Извините, меня здесь не «любят»


Вот ведь удивительно, да?
Согласен — а кто будет любить человека рушащего воздушные замки (мир фантазий в котором так хорошо жить) и напоминающего что все мы живем в реальном мире. Но периодически это нужно делать, за жизнь в выдуманном мире кто то все равно платит и в конце концов это приводит к «крушению» самоощущения самого человека.
Думаю многое из темы про «профессиональное выгорание эльфов» появляется в результате конфликта с реальным миром.
К сожалению люди не любят думать — это энерго-затратно, а значит вредно.

Единственный способ заставить человека думать, это причинить ему «боль» пропорциональную степени его заблуждения (звучит не очень, но реально это единственный метод).
Простите, вы ничего не рушите и не напоминаете — вы просто вываливаете на собеседников массу голословных «подрывающих основы» утверждений и призываете остальных попросту верить в них, потому что… ну вот даже не знаю, почему. Соответственно, никакой «боли» никому и не причиняете, потому что кто ж в здравом уме будет принимать всерьёз идеи космического масштаба без какого-либо обоснования?

А если по существу, у меня складывается ощущение, что вы ознакомились с массой интересных (и ни для кого не новых) фактов вроде неразрешимости проблемы останова или затруднительности разработки 100% корректных программ, а дальше уже делаете на их основе довольно парадоксальные выводы. Примите за данность, что другие тоже в курсе существования неразрешимости, NP-полноты, понимают, что такое формальная верификация и почему она не так уж часто используется и т.п. И всё равно занимаются тем, чем они занимаются, и не считают, что их работа под угрозой.
А вы сможете понять это самое обоснование?
Вот как пример сложности «детский сад», скажите мне к каким последствиям приведет внедрение описываемой технологии.
habr.com/ru/post/512652

Если можете, то будет описание вычислительной парадигмы, свободной от описываемой проблемы. Правда, да в ней программиста как такового нет.
А вы сможете понять это самое обоснование?

Ну вы приведите, а там посмотрим. Никакого другого способа это узнать не существует.

Привести то я приведу, так понять то вы все равно не сможете.
Детский пример прочитали?
Что можете сказать?
После нового года появится такое же простое описание процессора, вы сможете взлететь со своей локальной кочки и осмотреть хотя бы ближайшие окрестности болота? Про принять участие в «разворачивании» базовой идей в глобальную систему я и не говорю.
Привести то я приведу, так понять то вы все равно не сможете.

Вы приведите, а там посмотрим.


Что можете сказать?

Что он не имеет отношения к "вычислительной парадигме, свободной от описываемой проблемы".

После следующей статьи продолжим разговор.

Вот и вся ваша доказательная база. Показательно, но печально.

А вы сможете понять это самое обоснование?

Откуда я знаю? Наверно, это зависит от качества изложения обоснования. Так что это к вам вопрос, а не ко мне.

к каким последствиям приведет внедрение описываемой технологии.

Поскольку вы предлагаете взять и всё переделать с нуля, то в идеале это приведёт к более качественной передаче данных за меньшую цену. Тут даже вдаваться в детали не надо: отброс «легаси» всегда позволяет избавиться от определённого оверхеда. Но это же чисто гипотетическая тема для рассуждений: вы спросили, я ответил.
Про переделать с нуля — не требуется (для предлагаемой парадигмы связи, все существующие на данный момент являются «частными случаями», а значит могут быть прозрачно эмулированны).

А теперь вспомните все что вы знаете по теме «DataFlow процессор» и посмотрите на прочитанное еще раз. Учтите что производительность предлагаемой сети может на порядок превосходить имеющиеся сейчас у процессоров (вместе с интерфейсом к модулям динамической памяти)
Такой подход радикально сократит число ног у процессора, их может стать вообще две (+ Питание и — Питание), а с торца выходят оптические волокна сети. Сам процессор зажат между теплоотводами и одновременно проводниками питания.
Попробуйте «помечтать» при таких вводных.
Это всё очень интересно, но давайте вернёмся к теме текущего разговора. Я не против обсудить различные сетевые технологии, но сегодня вечером у меня было настроение ответить в данном треде, так что не особенно хотел бы с него переезжать.
Предыдущий разговор…
Вы думаете, что «баг» к которому привыкли это «фича».
Я понимаю что вы мыслите внутри текущей вычислительной парадигмы, я пытаюсь указать на то что она не самая лучшая и очень скоро ей на смену придет новая, гораздо более эффективная. Попытки искать «золотую пилюлю» обречены на провал из-за ошибок именно в самой парадигме.
Ну ведь в эту игру можно играть и вдвоём: я, конечно, понимаю, что вы мыслите в рамках своего выдуманного мира, в котором волшебная эффективная парадигма решит все проблемы, и в этом случае разговоры о наших бренных делах попросту лишены смысла; при коммунизме-то и денег не будет, зачем же нам обсуждать какие-то тонкости монетарной политики?

Такого рода разговор в принципе контрпродуктивен. Если вы по какой-то причине общаетесь со «старопарадигматиком», бесполезно обсуждать новый технокоммунизм. Хотите результативного общения — постарайтесь найти некое множество идей, которое будет пересекаться одновременно с нынешним миром и вашим новым миром тоже, а потом уже прыгайте целиком.
тогда ждите все описания последовательно и периодически перечитывайте все как единый документ, ну или забудьте.
Потом, когда АХО купит вам комп с новой парадигмой, предприятие Вас отправит переучиваться, там все узнаете (если раньше не сократят по ненужности — зависит от специфики работы).
очень скоро ей на смену придет новая, гораздо более эффективная

Вы все обещаете...

Я не понимаю о каких крушениях речь. Программист пишет код, который решает проблемы бизнеса или иногда даже помогает людям, получает за это хорошие и иногда даже отличные деньги. И вся эта парадигма в обозримом будущем не то, что не исчезнет — она будет только укрепляться, тк даже банально локдаун очень хорошо показал НАСКОЛЬКО для бизнеса важны цифровые сервисы. Я правда не понимаю о чем вы говорите. Вы вообще к IT какое-то отношение имеете, или так, потусить на огонек зашли?
А ну ка мил человек поведай из чьих будешь…
НГТУ АВТФ вычислительные комплексы системы сети.
Специализация fpga (Verilog).
Занимаюсь разработкой (в инициативном порядке) альтернативой архитектуры фон Неймана.
Считаю (полученного образования для предварительной оценку хватает) что получены обнадеживающие результаты (инет похожими идеями не отзывается) и скоро придется их внедрять в практику.
С программистами нужно общаться. по той причине что на первом этапе именно им придется внедрять, разворачивать и переносить все накопленные знания в новую систему. Потом правда профессия программист исчезнет, но это мелочи.
Про важность и необходимость не спорю.
Про все остальное покажет время.
Потом правда профессия программист исчезнет, но это мелочи.

А что будет выполняться на этой вашей "альтернативной архитектуре"?

Что сейчас представляет программирование (в большинстве случаев): составление списка данных и последовательности операций над этими данными.
Иными словами, программист говорит вычислительной системе прими данные и выполни определенную последовательность команд и будет получен результат.
Только есть проблема — то что получится (если вообще получится) будет ли корректным результатом?
Если программа выполняется в контролируемой среде (все параметры известны и учтены программистом на этапе написания программы), то проблем нет все нормально (ошибки именно программиста не учитываем, считаем что программист идеальный). А вот если параметров много или среда вообще другая (отличная от той для которой писал программист), то полученный результат для текущих условий очень может быть и не корректным.
Как создавать ПО для таких систем. Дальше будет тяжелый для понимания текст.
Мое мнение делать это нужно таким образом описывать программный объект не как последовательность действий, а как последовательность свойств получаемых данных для входных данных (тоже обладающих некоторыми свойствами).
В процессе программирования описывать только те свойства, которые важны для конкретной программы.
Пример, какая разница с точки зрения программирования написать выполнить суммирование двух переменных или получить новые данные обладающие свойством суммы двух переменных.
Для программиста особой разницы нет, но для вычислительной системы разница огромная. Если в первом случае это просто действие никак не связываемое с другими действиями (кроме результата), то во втором это свойство действующее в пределах всего объекта.
Тоже самое можно сделать и для групп объектов, например объявить что результат всех математических операций не должен иметь например точность хуже 1%.
Если задать все важные для решения задачи условия (свойства), то таким образом мы определяем не просто конкретный исполняемый файл для конкретной машины, а вообще все возможное множество программ для всех теоретически возможных машин и окружающих условий.
Задача компилятора добавить значение текущих условий (это неизвестно в момент написания программы) и сгенерировать программу соответствующую описанию. Если результат исполнения не соответствует заданным условиям, то необходимо обновить текущие условия и повторить компиляцию.

Описывать всю теорию на «блокнотных листочках» не буду — например достаточно полное описание процессора и потенциальных веток развития занимает около 120 страниц — сейчас пытаюсь уложить все прозрачный и краткий текст в пределах 5-10 старниц с картинками (без комиксов понимания нет)

Если я не ошибаюсь, вы сейчас описали декларативное программирование. Ничего нового в нем нет. Что важно — это все равно программирование, и для него все равно нужны программисты. Так что никуда профессия не исчезнет.

а если сделать так что бы это мог делать каждый
а если исходной точкой будут общественные базы описаний
а если они будут постоянно изменяться, мне что то не понравилось, я на естественном языке озвучит изменение.
Ну вы озвучиваете стандартные фантазии совсем лохматых годов — «каждый» делать этого в принципе не может, или напомнить вам анекдот про «купи батон хлеба, если будут яйца — возьми десяток»?
а если сделать так что бы это мог делать каждый

То программисты все равно останутся. Сейчас каждый (в разумных пределах) может готовить, но профессия повара никуда не делась.


а если исходной точкой будут общественные базы описаний

То кто-то должен будет их поддерживать.


а если они будут постоянно изменяться, мне что то не понравилось, я на естественном языке озвучит изменение.

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

Да пахарь и ткач остались, только в рамках домашнего хобби.
Повара так никто и не автоматизировал, были проекты но до практической ценности не дотянули.
Да пахарь и ткач остались, только в рамках домашнего хобби.

Я тут как раз недавно прогуливаясь нашел неподалеку ткацкую фабрику, так что снова вам не поверю. Да и с пахарями неловко.


Повара так никто и не автоматизировал, были проекты но до практической ценности не дотянули.

Казалось бы, повод задуматься, что некоторые профессии полностью не автоматизируемы (или выигрыш от автоматизации не перевешивает стоимость автоматизации).

На фабрике девушки с веретеном сидят и пахарь прямо в лаптях за лошадкой идет )))
По своему смыслу это операторы ткацкой машины и водитель трактора (как там правильно) и вместо половины страны этим занять — меньше процента от населения и то в сезонно.

С автоматизацией все просто — на одну чашу весов затраты, на другую результат работы автомата (робота).
Самыми первыми автоматизировались простые и массовые продукты (гвозди, крепеж, патроны и тд).
Постепенно (по мере развития технологий) наступает очередь все более сложных и редких задач.
Финиш в этом поставит антропоморфный робот — который заберет на себя все оставшиеся задачи (пока удачных проектов нет, но осталось недолго — первые десятки лет). И именно программирование виновато в отсутствии прогресса — пока не получается написать программу для работы в неконтролируемой среде, да еще и самообучающуюся (ну или адаптирующуюся) к параметром среды и это не ИИ.
UFO just landed and posted this here
Ошибаетесь — они как писали последовательности команд, так и пишут. А уж как это делать дырочками на бумаге, тумблерами, кнопками на клавиатуре или пиктограмками с мышью не важно.
Кому не важно? Если бы было так, щёлкали бы и дальше тумблерами.
Кстати интересный момент — могу ошибаться, но объем написанного (собственноручно) и отлаженного в течении одного дня кода с тех времен не увеличивается. Вроде писали про 5 строчек кода в день?
Не путать с размером программы — если туда сложить все существующие библиотеки и ресурсы и тд — объем может быть любым.
Неважно потому, что принципиально ничего не изменилось, ну разве что с Ада Фортрана и Паскаля перешли на СИ J и еще какую то хрень (при этом в основном меняются командные слова и стили)
Не могу сказать, сколько они писали, но в любом случае 5 строк на Python и 5 строк на ассемблере — это разные вещи. Однако из личного опыта — «5 строк на ассемблере в день» — это абсолютно нереальная цифра, потому что 5 строк у вас банальное перекидывание аргументов из памяти в регистр, выполнение простой операции, и закидывание обратно займёт. (Это по сути атомарный кусок кода, который вряд ли содержит ошибки).

Неважно потому, что принципиально ничего не изменилось,

У нас разные представления о принципиальном. Вы тут выше пишете, что девушка с веретеном и девушка с ткацким станком — это «принципиально разные вещи», но ведь там тоже никакой разницы — что было плетение ниток, что осталось. Ну и тракторист тоже ничего нового не добавил по сравнению с лошадью. Так что давайте определяться, где граница принципиального.
Да наверное про 5 строк это про языки высокого уровня
UFO just landed and posted this here
Вроде писали про 5 строчек кода в день?

Писать-то можно что угодно, только (а) как теперь это написанное проверить и (б) какие из этого выводы?


А то неплохо бы помнить, что пять строчек могут быть очень разными.


(у меня, в те дни, когда я код пишу, явно больше, чем пять строчек)

Так вы предлагаете заменить написание последовательности команд написанием последовательности свойств. Суть от этого не меняется. Я очень сомневаюсь, что каждый сможет легко описать таким образом программу, которая его сразу полностью удовлетворит. Ну и кто-то ведь должен писать и поддерживать этот самый универсальный «компилятор»?
Вообще, по-моему, это похоже на генетическое программирование.
Разница очень большая
Команда это здесь и сейчас, это бесконечно малая точка, не пересекается с другими командами (кроме малой части свойств результата исполнения, большинство из которых программист не может контролировать).

Свойство действует в определенных интервалах и может пересекаться с другими свойствами, программа в каждой своей части может зависеть от неограниченного количества свойств.
Автоматический контроль на этапе программирования и исполнения как раз и сделает ПО максимально надежным — результат исполнения ни при каких обстоятельствах (хоть аппаратных, хоть программных, хоть алгоритмических) не будет некорректным (понятное дело в пределах знаний программиста о правилах корректности для для всех возможных результатов)

Да есть параллель с генетическим программированием — компилятор может выглядеть как генератор случайной последовательности команд (или внесения изменений), с последующим анализом полученного результата. Правда в реальности такое работать не будет — проверить результат можно только методом исполнения (теоретики говорят что анализ алгоритма используя другой алгоритм невозможен).

Есть еще один интересный момент — в современной парадигме программирования библиотечный элемент (функция) по существу статична — применяй как написали. Для случая со свойствами — есть возможность задать задавать дополнительные внешние по отношению к библиотечному элементу свойства, что сделает его гибким к условиям применения. Сейчас такой функционал используют посредством различных Define, но это ограниченное применение да еще и требует заранее предусмотреть подобный случай.
программа в каждой своей части может зависеть от неограниченного количества свойств

И в этот момент для ее выполнения необходимо неограниченное время.


теоретики говорят что анализ алгоритма используя другой алгоритм невозможен

Нет, не говорят. Вы неправильно понимаете теорему Райса.


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

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

Выглядит как-то утопично. Хотелось узнать подробности реализации такого чудо компилятора. А то очень много вопросов возникает. Я так понимаю, по сути, он будет сам генерировать эти команды. Но как удостовериться, что он будет делать это правильно для любых возможных задачь во всех возможных случаях при любых возможных условиях?
Звучит примерно как:
Подскажи по быстрому, в двух словах, о чем написано
в Войне и Мире.

Следующая статья будет про процессор (сейчас написал и опубликовал статью про коммуникационную основу вычислительной системы habr.com/ru/post/512652 )
Думаю символьная синхронная коммутация она является идеальной для реализации процессора типа DataFlow, да и для общего применения на голову выше всего существующего.
Только после нее будет будет статья про «алгоритм решения произвольной задачи». Давайте до того времени отложим конкретику, кратко я могу описать только «идеи». Если есть вопросы по конкретике, то пока только по сетевой основе вычислительной системы.
Процессор вообще не обсуждается — статья ожидается сразу после нового года.
Ну тогда подожду статью. Сеть это лишь способ передачи данных, не так интересно. Особенно до реализации хотя бы на уровне прототипа.
Про не интересность сети это сложный вопрос.
Например она является главной проблемой на пути проектирования DataFlow систем, скорость передачи и коммутации сводит на нет все плюсы данного подхода к вычислениям (понятно кроме описываемой в статье).

Доступ к данным соседних вычислителей главная проблема (главный ограничивающий производительность) фактор современных грид систем.
Доступ к данным соседних вычислителей главная проблема (главный ограничивающий производительность) фактор современных грид систем
Я не понимаю, куда вы движетесь.

Насколько я понял, ваша цель — декларативное программирование (говорим что хотим, а не как делать). А средство — DataFlow. И как средство соответствует цели? Это же совсем про другое…

DataFlow это идеальное средство когда нет единственной нити вычислений. Для моего случая можно сказать, что запускается параллельная проверка или обеспечение соответствия большого числа свойств одновременно.
Программа состоящая из набора свойств (утверждений законов) не содержит явной последовательности действий и может быть исполнена параллельно.
В пределе, такой подход используется в базовой идеи DataFlow и не оптимально для практического применения, может выглядеть как проверка соответствия свойств на каждое изменение данных.
Видимо, вы на практике не встречались с проблемой экспоненциального взрыва.

Я как-то в школе узнал об алгоритме перебора с возвратом. И подумал: ну, теперь-то любые олимпиадные задачки можно будет щёлкать как орехи, алгоритм-то универсальный, решает всё.
Я и написал, что «в пределе».
В реальности необходимо наращивать объем обрабатываемых данных пока не будет достигнут затребованный результат.

… а поскольку мы не знаем, не изменят ли пока не обработанные данные существующий результат, придется обрабатывать все.

Программа состоящая из набора свойств (утверждений законов) не содержит явной последовательности действий и может быть исполнена параллельно.

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


И да, в этот момент оно ничем радикально не отличается ни от декларативного, ни от (чистого) функционального программирования.

Давайте до того времени отложим конкретику, кратко я могу описать только «идеи».

Занятно, как это не мешает вам уверенно говорить, что ваши "идеи" будут работать.

По своему смыслу это операторы ткацкой машины и водитель трактора (как там правильно) и вместо половины страны этим занять — меньше процента от населения и то в сезонно.

Нет, по смыслу это ткачи и пахари. А вот каким конкретно образом они решают поставленную задачу — не очень важно.

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

Если программирование будет выглядеть как
Если задать все важные для решения задачи условия (свойства), то таким образом мы определяем

то абсолютно необходимо оценить трудозатраты на такую работу. Если они окажутся сравнимы с нынешними, то и прогресса нет.

Ну и кроме того, имейте в виду, что
Только есть проблема — то что получится (если вообще получится) будет ли корректным результатом?

данная «проблема» — в общем виде не особенно-то и проблема. Все наши беседы о будущем разработки ПО — это не более чем узкопрофессиональная дискуссия атоматизаторов о тонкостях процесса автоматизации. Они за пределами нашей среды вообще никого не волнуют.

В современном мире есть задачи, которые как-то решаются и которые не решаются вообще. Под «не решаются» я подразумеваю что-то достаточно глобальное типа невозможности на сегодняшний день создать аккумулятор для ноутбука, который на одной зарядке проработает месяц. Если же задача решается, то надо сначала удостовериться, что улучшение процесса вообще кого-либо интересует, то есть снижение издержек или повышение точности решения востребовано и достижимо. Если же мне как заказчику в принципе годится решение, которое работает в 99% случаев как надо и получается в результате недели работы специалиста за мелкий в масштабах фирмы прайс — то по определению улучшение процесса мне ничего не даёт.
Месяц на одной зарядке, проще простого — емкость аккумулятора должна соответствовать возможности поддерживать канал связи достаточный для нормального функционирования RAdmin.
Сами вычисления производить на стационарной машине.
Какая разница где считать, если не сказать об этом потребителю, то он даже узнать об этом не сможет.
Что то похожее сейчас появилось для игр на слабых машинах.

Но только фиг вам — потребитель должен покупать дорогие ноутбуки а не дешевые терминалки и арендовать время на серверах.
Ну это любимый аргумент «тебе это не надо». Мне надо, а если кому хочется сидеть на тонком клиенте — его дело. Лично я хочу хороший аккумулятор, которого бы хватило для полностью автономной работы на месяц при любых нагрузках.

В любом случае, кстати, что-то с расчётами у вас не так: одна только смена экрана с Full HD на 4K способна вдвое уполовинить батарею; да и просто работа с ноутом в режиме печати текста уводит заряд в ноль за несколько часов.
В любом случае, кстати, что-то с расчётами у вас не так

Что-то как-то да: беспроводной канал + хотя бы FullHD-дисплей, да на месяц — не верится.

Ну да если считать что будете пользоваться непрерывно в течении 8 часов в день 30 дней устройством потребляющим 25 Вт (18Вт потребление обычного монитора и 7 Вт связь + мышь + клава). То потребуется аккумулятор 1700 А\Ч
Да 22 кг — да многовато.
Но на неделю и с учетом энергосберегающего режима Вполне можно вписаться в 2-3 кг- вес ноутбука.
Если с покрытием сетью проблемы то да ноут актуален.
Месяц на одной зарядке, проще простого
[...]
Но на неделю и с учетом энергосберегающего режима Вполне можно вписаться

И вот так каждый раз.

Сделать специализированную микросхему (по энергосберегающей технологии), оптимизировать экран для работы в режимах в переменными частотами развертки (это фантазии делетанта) и будет вам месяц при весе устройства 5 кг.
А если еще солнечными батарейками обклеить ))).
Да, я читал как-то жалобу одного юзера на электросамокат. Дескать, разряжается гораздо быстрее, чем заявлено производителем. А на запросы производитель легко ответил: ну так чего вы хотите. Катаетесь по городу с остановками (тормоз отъедает батарею), температура у вас ниже 20 градусов, да ещё и весите вы больше 75 кг — чего ж удивительного? Вот сделайте всё как в лаборатории — и будет как заявлено.

Можно как угодно играть в фантазии, но понятно, что когда я сказал, что хочу иметь ноутбук с батареей на месяц, речь шла не о том, что будет ЦП на 100МГц с пассивным охлаждением и ч/б монитор 640x480 c солнечными батареями и аккумулятором в половину рюкзака.

Короче говоря, с позиции юзера не решается эта задача, а если кто захочет на слабо такую модель изготовить — то лишь в рамках такого соревнования она и будет существовать.
Сочувствую, мы живем в реальном физическом мире.
И пока не умеем двигать значения физических констант.

Кстати нашел решение как раз в рамках вашего запроса
ozlib.com/814093/himiya/pryamoy_metanolnyy_toplivnyy_element_pmtz
Заливаете раз в месяц два килограмма метанола и пользуйтесь свои ноутом (именно ноутом) целый месяц.
Да еще и можно систему охлаждения улучшить — не люблю гудяций вентилятор.
Экскьюзе муа, это вы мне говорили, что «аккумулятор на месяц — проще простого». Или там дальше стояла скрытая звёздочка, а снизу сноска (*) с помощью заливки 2 кг метанола?
Не будете капризничать и будет все просто, а так любой каприз за ваши деньги )))
это фантазии делетанта)

Nuff said.

А что сделать предположение и сказать что оно исходит от дилетанта в области проектирования ЖК матриц — зазорно?
Кстати поискал про энергосберегающие мониторы и сразу нашел про 7Вт
А что сделать предположение и сказать что оно исходит от дилетанта в области проектирования ЖК матриц — зазорно?

Зазорно говорить "проще простого" в области, в которой вы знаете, что вы дилетант.

Про матрицы я этого не говорил.
Про технические решения: я не супер спец, но вы вот зарабатываете написанием программ, я зарабатываю разработкой электроники и около-электронных моментов.
Тот кто решит сделать такой девайс придет к таком как я.
По поводу батарейки на 30 дней — посмотрел на эту проблему со стороны безопасности. Хранить 20 МДж энергии в бытовом устройстве весьма опасно и потому нужно идти по пути сокращения потребления или что то типа топливного элемента.
Похожие проблемы решают в геофизике (мой основной источник доходов) — там необходимо на две недели отправить в скважину прибор с похожим потреблением (там только еще и температура 150С и больше, а это печаль для разработчиков почти эпических масштабов).
Кстати, проблема надежности ПО встает во весь рост: час работы буровой это море денег (всей моей зарплаты даже на один час не хватит).
Про матрицы я этого не говорил.

Говорили про комплекс, их включающий.


По поводу батарейки на 30 дней — посмотрел на эту проблему со стороны безопасности. Хранить 20 МДж энергии в бытовом устройстве весьма опасно и потому нужно идти по пути сокращения потребления или что то типа топливного элемента.

Ну вот видите. Пришли ровно к тому, с чего начинали: задача "аккумулятор для ноутбука на месяц" сейчас находится в категории "не решается". Потому что все предлагаемые вами варианты — они обходят эту задачу и пытаются решить какуюю-нибудь другую. Я не спорю, что иногда это валидный подход, и приносящий конечному потребителю пользу. Но иногда, не всегда.

Вы «заряжаете» автомобиль бензином и на попытки заставить заряжать от розетки реагируете без энтузиазма.
Ноутбук и аккумулятор — это просто привычка.

Пользователь получивший в пользование качественный топливный элемент будет очень негативно реагировать на призывы вернуться «к розетке».

То чем вы занимаетесь сейчас называется — софистика (в народе: троллинг).
Если следовать вашей логике, то самолет это не решение проблемы и перемещаться по воздуху необходимо с использованием ковра самолета, драконов и безумных волшебных карликов.
Вы «заряжаете» автомобиль бензином и на попытки заставить заряжать от розетки реагируете без энтузиазма.

Да, и у меня есть конкретный набор примеров, почему в моем случае зарядка от розетки не подойдет.


Ноутбук и аккумулятор — это просто привычка.

Нет, это условия задачи.


То чем вы занимаетесь сейчас называется — софистика

Nope. Это попытка держать дискуссию в приличных рамках, а не уползать от поставленных вопросов в удобную вам область.


Если следовать вашей логике

Nope. Это если следовать той логике, которую вы мне приписываете.

Мое мнение — решать необходимо только востребованные проблемы.
По поводу «программистов» я из хулиганских побуждений постараюсь направить развитие вычислительных систем на путь, где сегодняшние знания (в области программирования) не будут востребованы — даже умение создавать алгоритмы ))))
Мое мнение — решать необходимо только востребованные проблемы.

Это никак не делает описанную проблему решаемой. О чем, собственно, и шла речь с самого начала.


По поводу «программистов» я из хулиганских побуждений

Вот именно, что из хулиганских. Ничего конструктивного в вашей деятельности я не вижу. "Не умею разобраться, как сейчас, поэтому скажу, что все плохо, и все надо сломать".

По первому вопросу — упертость в области достижения практически ненужного результата — основной способ потерять море времени и денег.

Статью с описанием коммуникационной парадигмы вы понять не смогли, ну какой смысл вам что то объяснять?

Проблемы современной вычислительной техники вы не понимаете, а то что понимаете считаете не решаемыми.

Так что ждите когда Вас направят на переподготовку — самостоятельно «приближать» будущее вы не можете.
По первому вопросу — упертость в области достижения практически ненужного результата — основной способ потерять море времени и денег.

Не вам решать, нужен ли результат, если вам поставили конкретную задачу. Вы можете сказать, что задача не решаема, это да.


Статью с описанием коммуникационной парадигмы вы понять не смогли, ну какой смысл вам что то объяснять?

… а с чего вы взяли, что я ее не понял? А, главное, как уже говорилось выше, она не имеет отношения к обсуждаемому вопросу.


Проблемы современной вычислительной техники вы не понимаете

Какие-такие проблемы? Пока что каждая "проблема", которую вы озвучиваете, упирается в отсутствие фактологии.


то что понимаете считаете не решаемыми.

Вы точно меня ни с кем не путаете?


самостоятельно «приближать» будущее вы не можете

Я его, правда, двадцать лет вполне успешно приближаю, но вам, конечно, виднее.


А оснований для переподготовки я как не видел, так и не вижу. Даже обещанная вами декларативная парадигма, в общем-то, переподготовки не требует.

Последнее интересно — последние двадцать лет вычислительная техника стагнирует (не буду говорить что начал понимать почему).
Можете рассказать чем занимались все это время, чего достигли?
Про себя могу сказать — примерно 35 лет назад меня заинтересовала вычислительная техника. Постепенно я выбрал ее как объект исследований (с философской точки зрения)
Меня интересовали вопросы — почему постоянно изменяются архитектуры, «операционные системы», почему нужно постоянно все «переписывать».
Можно ли создать «идеальную вычислительную систему», ПО в которой можно просто дописывать по мере надобности.
И почему такие попытки постоянно приводили к провалу, и кто (что) виноват в этих провалах. Причины крайне низкой эффективности труда программистов и тд.
Постепенно сформировал решение проблем — полностью новую вычислительную парадигму. Сейчас начинаю публиковать «слои» — Первый «слой» коммуникационная основа. Следующий «слой» — распределенный параллельный «процессор».
последние двадцать лет вычислительная техника стагнирует

Я так не считаю. Объективные факты есть?


Можете рассказать чем занимались все это время, чего достигли?

Мое резюме вполне доступно и легко находимо. Равно как и происходящие два раза в год презентации новой функциональности в ПО, в разработке которого я принимаю участие (и за последние несколько лет в каждой такой презентации я мог показать пальцем на кусок, за который я отвечал).

Когда последний раз покупая компьютер и устанавливая на него новое ПО (как пример операционную систему) вы смогли сказать:
Блин вот это прогресс, то что у меня было до этого…

По второму вопросу:
Я и сам много раз «дослуживался» до руководящих должностей и результат моей работы (то что было создано) успешно (в том числе и коммерчески) работает до настоящего времени. Информационная система противопожарной области Новосибирской области — самый первый комплексный проект инициированный именно мной. Когда я пришел туда работать — моим первым заданием было оживить неработающие машины СМ1420 и поддерживать их работоспособность. Когда я ушел оттуда — была создана специализированная информационная система (про FoxPro можете даже не говорить Oracle for Solaris) и это практически без финансирования — тогда были проблемы с финансами. Ну и так далее. Ушел из пожарки потому, что меня стали переводить в совсем уж бюрократическую должность.
Я не могу работать на конвейере — мой идеал это забраться повыше в «гору и сесть там на пенек» и заниматься поиском закономерностей в происходящем вокруг. Поэтому в программировании меня интересуют только базовые законы и их влияние — самое главное куда они в своем пределе приведут.
Когда последний раз покупая компьютер и устанавливая на него новое ПО (как пример операционную систему) вы смогли сказать:
Блин вот это прогресс, то что у меня было до этого…

В 2019, когда покупал и настраивал сначала Fire TV, а потом Shield TV.


По второму вопросу:

Не помню, чтобы я вас спрашивал, чего вы добились. Но не суть. На мои успехи это, к счастью, никак не влияет.


Я не могу работать на конвейере

А я вот могу. Возможно, именно поэтому я могу потихоньку, медленно, шаг за шагом делать мир лучше.

К сожалению инкрементальный поиск максимума, приводит лишь к нахождению локального максимума (должности руководителя направления в данной конкретной организации), можете по этому вопросу проконсультироваться у специалистов по нейронным сетям.
Остается два варианта (если вы хотите большего):
— случайный прыжок.
— попытка понять, а что за безумие тут происходит в целом (посмотреть на все из «космоса» и понять что делать).
к нахождению локального максимума (должности руководителя направления в данной конкретной организации)

Какие у вас занятные представления о максимумах.


можете по этому вопросу проконсультироваться у специалистов по нейронным сетям.

Спасибо, но градиентный спуск был придуман приблизительно в XIX веке, так что можно и без нейронных сетей обойтись. Собственно, даже в курсе по машинному обучению градиентный спуск (обычно) преподают раньше, чем сети.


Остается два варианта (если вы хотите большего):

А зачем мне "большее"-то? Как вы "большее" меряете?


… впрочем, все это снова очень показательно в контексте того, насколько все это не имеет отношения к исходному обсуждению.

те Вы готовы получить «синицу» и успокоиться?
У меня ближайшая вершина, которую я должен достичь
описана тут: habr.com/ru/post/489068
Довольствоваться крохами я не готов.

Все что я пишу — ложится в одну «канву», вы просто не понимаете всей проблемы. Вам не хватает кругозора, поймите изучение технологий из списка «модных» не значит что вы все понимаете. Последние действительно новые идеи в вычислительной технике были сформулированы в 70х годах прошлого века, сейчас только бантики привязывают.
те Вы готовы получить «синицу» и успокоиться?

Нет, я готов приносить людям пользу теми способами, которые мне доступны.


Довольствоваться крохами я не готов.

… поэтому будете всем рассказывать, как то, что они делают — бесполезно и бессмысленно, да.


Все что я пишу — ложится в одну «канву», вы просто не понимаете всей проблемы.

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


Вам не хватает кругозора

… вы-то, конечно, все знаете про мой кругозор.


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

Я подозреваю, что это утверждение упрется в невозможность объективно определить, что же такое "действительно новая идея".


Ну и да, каминг-аут — меня не очень интересует вычислительная техника, я все больше по программному обеспечению. А ВТ меня интересует ровно в том объеме, в котором она влияет на ПО.

Люди никогда и ничего кроме «дубины» (или ее угрозы) не слушают и предупреждать их бесполезно.
Общение необходимо для понимания, а не заблуждаюсь ли я в каких то вопросах.
Наиболее эффективным является общение по принципу колокола — посильнее ударил, он (колокол) и все расскажет. Заодно проверю сформулированные идеи — например в сетевой парадигме никто не нашел ни одной ошибки.
Сформулирую нужным образом новую вычислительную парадигму — что бы программистам в ней не нашлось места — они будут искать пробелы, что бы доказать что теория ошибочна(кушать то всем хочется)
Ладно — думаю все пустышка — ждите перемен )))
Люди никогда и ничего кроме «дубины» (или ее угрозы) не слушают и предупреждать их бесполезно.

Это утверждение как минимум недоказуемо (а попросту говоря — ложно).


например в сетевой парадигме никто не нашел ни одной ошибки.

Ммм...


Сформулирую нужным образом новую вычислительную парадигму — что бы программистам в ней не нашлось места

Как уже говорилось выше, пока вам это не удалось даже на концептуальном уровне. Не то что на уровне "есть пробелы", а пока что на уровне "нет никакой парадигмы".


ждите перемен

Вот как раз перемен-то я давно жду, только их все нет и нет.

пора спать — а то начал делать грамматические ошибки))
UFO just landed and posted this here
Мое мнение делать это нужно таким образом описывать программный объект не как последовательность действий, а как последовательность свойств получаемых данных для входных данных (тоже обладающих некоторыми свойствами).

Мне вот что-то любопытно стало. Проведем простенький мысленный эксперимент, (возможно, то, что я не могу с ним справиться, и показывает мою непригодность для новой парадигмы?).


Есть, значит, чек на бумаге. Обычный такой чек из магазина. А есть человек, который хочет учитывать свои расходы. И хочет он простого: хочет он, чтобы можно было взять мобильник, сфотографировать чек, и сумма/дата этого чека появились где-то, где он учитывает свои расходы, туда же записался продавец и проставилась категория расходов (ну там, продукты или товары для дома, скажем).


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


А вот как эту занимательную задачу выразить в "последовательность свойств выходных данных", таким образом, чтобы нечто смогло на основании такого описания это осуществить?

Чек — изначально это набор цифровых данных с сенсоров.
Причем не именно сенсоров фотоаппарата, а еще и позиционирования, времени, даты, наличия с покупателем знакомых и незнакомых людей вообще в идеале все что сопутствовало получению чека. Вот это и будет набором входных данных. Еще добавлю, что данными будут и все что ассоциируется с чеком, покупками и тд.

Через некоторое время (возможно что такого намерения у человека изначально и не было) человек решил привести свои «финансы в порядок» и сформировал соответствующий набор данных примерно по той же методике что и чек. Только в нем в основном будут свойства исходных «чеков» и свойства результата который хочется получить.

Заметьте изначально нет никакого приложения по анализу чека, а значит это вообще не ПО и писать его не нужно (значит и программист не нужен).

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

Напишу в духе анекдота про физиков теоретиков, потерявших несколько листков с доказательствами:
— А ты напиши: Из этого однозначно следует…

Я напишу так: Далее вычислительная система «перемножает» эти наборы данных (свойств) и производит заполнение (вычисление)неизвестных в начальный момент данных (свойств).
Чем больше работает такая система, тем все большее число исходных данных подвергается анализу и тем точнее результат.

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

Чек — это бумажка. Она передо мной на столе лежит.


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

Ну то есть, на самом деле, нет такого описания, кроме "у нея внутре неонка".


Окей, я без работы не останусь.

У Вас нет фантазии, вы просто исполнитель, идеальный сотрудник для иерархических систем — это проблема работающих на «конвейере».

Надежда на авось ложна — так или иначе неэффективно действующее звено будут исправлено или вообще удалено (в запущенных случаях).

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


Да, кстати, вот вам еще:


человек решил привести свои «финансы в порядок» и сформировал соответствующий набор данных
[...]
Заметьте изначально нет никакого приложения по анализу чека, а значит это вообще не ПО и писать его не нужно (значит и программист не нужен).

… а где же человек "сформировал набор данных"?

Потом правда профессия программист исчезнет, но это мелочи.

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

Я не помню, когда мы перешли на «ты», но не суть — я учился в каком-то вузе, потом писал код на каких-то работах, в итоге дорос до тимлида/руководителя отдела разработки в какой-то компании с 10+ филиалами по стране. Звезд с неба не хватаю, занимаюсь в целом любимым и интересным делом и получаю за это какую-то зарплату. Не рефлексирую по поводу «предназначения» и «будущего» программирования, тк прекрасно понимаю что еще мои дети или даже внуки, если захотят, смогут как и я пристроить свою жопу в айти и неплохо себе поживать.
А ну ка мил человек поведай из чьих будешь… — это цитата и приведена она по поводу вопроса от том кто я такой )
Квалифицированные программисты это понимают и потому даже не пытаются писать «идеальную программу», а просто закладывают некоторый объем финального тестирования (или вероятность сбоя).

Вы бы сначала поняли сами, что такое проблема останова, а потом бы рот открывали на публике. Никому (кроме абстрактных теоретиков) не вперлось проверять тотальность всех программ в мире. А для одной конкретно взятой программы ее проверить внезапно можно, и современные языки программирования, типа идриса, даже позволяют указать директиву %default total, что на практике заставит компилятор проверить тотальность.


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

Мы совершаем ошибки и платим за них. Везде. Кроме ИТ-индустрии. И это ужасно страшно.

Знакомая фраза?

Эта фраза немножко (на самом деле, полностью) неправда.

Это фраза из статьи на хабре — автор Chapuza

Я в курсе. Моего мнения по ее поводу это не меняет.

UFO just landed and posted this here
После нового года собираюсь опубликовать статью с описанием альтернативы фон Нейману.
Про программирование там особо ничего не будет, но буден показан способ организации вычислений позволяющий увеличить производительность типичной машины на 3-6 порядков от существующих аналогов. Вот потом и нужно будет говорить о новой парадигме программирования пригодной для использования в «неконтролируемом» пространстве (для обеспечения гибкости и безошибочности работы программ с объектами реального физического мира — как пример универсальные антропоморфные роботы).
А вообще я сильно хочу вот это: habr.com/ru/post/489068

UFO just landed and posted this here

Невозможность решить проблему останова в общем случае не означает, что ее нельзя решить в частных случаях. И мы можем рассмотреть мир, в котором частные случаи покрывают 100% полезных программ. И вопрос только в том живём ли мы в этом мире или каком-то близком к нему. Так что не унывайте, ещё не все потеряно.

Без полной смены парадигмы вычислительной техники и принципов программирования тут не обойтись, проблема именно в самой парадигме.
Думаю программистам следует готовиться к потере всех накопленных знаний и умений за пределами программирования, старенькие на пенсию, молодые в торговлю
Парадигмы в программировании периодически обновляются. Объектная, функциональная, декларативная… Никаких проблем с этим нет: кто, как не существующие программисты, будут разбираться с новыми парадигмами и применять их.

А ваши фантазии, что программисты будут не нужны, потому что любой человек сможет получить нужный результат без квалификации, равносильны созданию сильного ИИ. Тут уже проблемы будут вообще у всех профессий, у программистов в последнюю очередь.
Про ненужность я может быть и «загнул», но думаю специалистам в области программирования мало не покажется.
ИИ действительно натурально убьет человека, не как «терминатор» — он лишит человека стимула к обучению и тем самым обречет на деградацию.
Мое представление о самом оптимальном будущем я описал здесь:
habr.com/ru/post/489068
но думаю специалистам в области программирования мало не покажется
А что должно измениться? Вы так и будете писать никому не понятные тексты на Хабре, а программисты так и будут работать в своих банках, заводах, галерах…

Мое представление о самом оптимальном будущем я описал здесь
Трансгуманистическая фантастика — это хорошее и нужное дело. Но это литература, а не наука или инженерия.
Программирование сильно упростится и из самостоятельной профессии трансформируется в простой навык (примерно как читать и писать).
Примерно как умение пользоваться текстовым редактором, ну или сегодняшнее требование — «Уверенный пользователь ........»

По второму вопросу — думаю это слишком поверхностное суждение. И да это направление тоже сильно зависит от информационных технологий.

Мое мнение: Необходима вычислительная парадигма родственная человеческому мозгу и одновременно являющаяся оптимальный инструментом для проектирования и исследований в этом направлении. С современной производительностью вычислительных машин (и самих программистов) нечего и думать о значимых успехах в области вычислительной биологии и практического применения полученных наработок в практике трансгуманизма. Если простыми словами — необходим пакет разработчика для проектирования биологических информационных структур и биомашин, ну и биологический синтезатор.
Да эти технологии предельно опасны, особенно для тех у кого их нет.
Программирование сильно упростится и из самостоятельной профессии трансформируется в простой навык (примерно как читать и писать).
Не вижу к этому никаких предпосылок
Мое мнение: Необходима вычислительная парадигма родственная человеческому мозгу и одновременно являющаяся оптимальный инструментом для проектирования и исследований в этом направлении
Мое мнение: сложность из задач никуда не денется, её необходимо будет осмысливать, переводить на формальные языки, тратить «мыслетопливо». Парадигма всего лишь инструмент и поможет лишь немного, ну примерно как средства рефакторинга в IDE.
Про формальные языки — вот они и уйдут в первую очередь.
Пока не могу внятно описать, но (мое мнение) ПО превратится из набора операторов в набор знаний (не экспертная система), а программирование в редактирование «базы знаний» производимое на естественном языке (все естественные языки практически сразу станут частью этой базы знаний) или вообще с помощью визуальных образов.
Про формальные языки — вот они и уйдут в первую очередь.

А как вы без формальных языков собираетесь знания описывать? Как вы без формальных языков собираетесь снимать противоречия в требованиях?

а как без формального описания картинки распознают?
как без формального описания птицы летают?
Или обезьяна прыгая с ветки на ветку — перед прыжком пишет программу на формальном языке?

Поймите наконец — современная вычислительная техника создана математиками, что бы автоматизировать труд «вычислителей» (данная профессия умерла) и только.
Да, потом используя возможность «вычислять» произвольные математические (логические) модели, вычислительную технику и прикрутили к «гражданским» задачам.
И все эти формальные языки, совершенно неэффективные принципы программирования и есть плата за это «прикручивание».
а как без формального описания картинки распознают?

Люди или машины? Машины — никак.


И все эти формальные языки, совершенно неэффективные принципы программирования и есть плата за это «прикручивание».

Вы, я так понимаю, не в курсе, что формальные языки существуют за пределами программирования, и практически в каждой дисциплине?

а как без формального описания картинки распознают? как без формального описания птицы летают?
Или обезьяна прыгая с ветки на ветку — перед прыжком пишет программу на формальном языке?
А вот так — без пониманию, что и как делается. Когда появились формализмы, анализ и синтез, возможности по летанию и прыганию возросли на порядки. Стало понятно, какое решение оптимальное, какие есть ограничения.

А вы предлагаете отказаться от всего этого, от интеллекта, от языка, вернуться к методам работы мозга животного?
Я предлагаю сочетать их, причем в правильном порядке — по мере увеличения сложности и соответственно времени вычисления.
Примерно таки образом человек учится (животные просто подсматривают желаемое у других членов стаи(родителей), да и множественное повторение с случайными отклонениями постепенно сформируют некий локальный оптимум).
Примерно таки образом человек учится (животные просто подсматривают желаемое у других членов стаи(родителей)

То есть вы игнорируете тот факт, что человек, вообще-то, учится еще в образовательных учреждениях? Которые опираются на построенные за долгое время формализмы?

Программирование сильно упростится и из самостоятельной профессии трансформируется в простой навык (примерно как читать и писать).

Вы не обращали внимания, что профессия "писатель" никуда не делась?


необходим пакет разработчика для проектирования биологических информационных структур и биомашин

… и откуда же он возьмется?

Писатель существует и его только сейчас пытаются автоматизировать (временами весьма успешно). А вот профессия машинистки стала просто опцией.

Пакет разработчика…
Сначала я «придумаю его необходимость и принципы функционирования», а потом профильные специалисты реализуют в новой вычислительной парадигме и «накачают» его всеми знаниями которые до этого были получены человеком.

Как «гипотеза» для построения синтезатора:
С синтез белков в биологическом организме происходит с использованием большой молекулы, которая с одной стороны перебирает нить РНК с другой (по данным РНК) синтезирует белок.
А давайте сделаем микросхему, которая сверху заканчивается площадками электродов, если подать определенный рисунок потенциалов, то к конкретному месту «прилипнет» строго определенная молекула в определенном положении.
Изменяя потенциалы мы можем изменять типы, положение молекул и даже изменять ее геометрию.
Если не напрямую, то через молекулу посредника можно собирать молекулярные структуры.

Понятно что все не так просто, но идея (вернее пул идей) натолкнет профильных специалистов на путь для построения реального устройства.
Писатель существует и его только сейчас пытаются автоматизировать (временами весьма успешно). А вот профессия машинистки стала просто опцией.

Так почему вы считаете, что программист — это машинистка, а не писатель?


потом профильные специалисты реализуют в новой вычислительной парадигме

Подождите, так "профильные специалисты" — это и есть те самые программисты, которые, по вашим словам, не будут нужны.


«накачают» его всеми знаниями которые до этого были получены человеком.

Уиии, мы нормальную энциклопедию-то не можем сделать, а вы говорите — пакет разработчика "накачать всеми знаниями". Одно это — задача на несколько поколений.

Писатель всегда пишет что то новое, а машинистка всегда одинаковые слова русского языка. Новизна в работе программиста исчезающе мала — в больших проектах он опирается на ТЗ, в остальных случаях копирует куски кода из учебников и гитхаба. Очень часто не решает, даже на каком расстоянии иконки располагать.

Профильные специалисты — это химики, физики, биологи и тд.
Программирование у таких специалистов является просто навыком.

Косвенно вот над этим и работаю.
Писатель всегда пишет что то новое, а машинистка всегда одинаковые слова русского языка

Нет, писатель тоже пишет слова русского языка.


Профильные специалисты — это химики, физики, биологи и тд.
Программирование у таких специалистов является просто навыком.

В таком случае кто-то должен будет дать им инструментарий для применения этого навыка. Мы, собственно, об этом инструментарии и говорим. Откуда он возьмется?

Печаль )))
Кто напишет: JMP (PC-<несколько комментариев назад>)

Я же Вам написал — Пустышка.
Смиритесь и просто ждите перемен.

Йеп, так и запишем: инструментарий зародится сам собой, как мышь в сене.

Как я понял этого автора, исследователи и программисты-учёные, пишущие чудо-инструменты, останутся. А вот прикладники, которые клепают формочки, логику веб-страничек, типичный складской и бух. учёт, исчезнут.

А вот как этого предлагается достичь, мне непонятно. Может, тупо переименованием всех программистов в другой термин, как здесь.

Может, тотальным повышением алгоритмической грамотности населения (на это наталкивает пример с машинистками). Но это на практике сложно будет сделать, хотя и возможно.
исследователи и программисты-учёные, пишущие чудо-инструменты, останутся

… но при этом программистами он их называть не хочет, ага.

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

А что останется работать 1% «истинных программистов», уже не важно в рамках всей индустрии.

Есть у меня на эту тему любимый анекдот: "и вы говорите".

Программирование сильно упростится и из самостоятельной профессии трансформируется в простой навык (примерно как читать и писать).


Я, конечно, не иксперт, но даже читать и писать не всегда сейчас умеют нормально, уже не говоря про считать, пример — недавнее видео от россия 24 (или москва 24, не помню), в котором выпускники некого ВУЗ по специальности бухгалтера не могил квадратный корень из 100 взять и говорили, что такой не существует (!). Да и «Уверенный пользователь» это не тот, кто знает, что системный блок — это не процессор, а тот, кто знает как он устроен, что в нем зачем, как это все собрать и обслужить так, чтоб оно заработало, и как затем на него установить ОС и прочее ПО, и как это все настроить под себя. Т.е. знание в любом случае не повседневные и недоступные большинству (как физика, например).
Получается сколько методов не напиши — всегда когда-нибудь, при изменении бизнес-требований будет ошибка.

Нет, не получается. Получается, что ошибки возможны. Ну да, люди вообще совершают ошибки, так бывает.


А еще ошибки можно минимизировать — например, используя автоматизированные тесты.

Насчет автотестов — отличная мысль.
А еще ошибки можно минимизировать — например, используя автоматизированные тесты.

Ага, и потом чинить ошибки ещё и в тестах:)

Я в среднем считаю, что лучше чинить ошибки в тестах, чем ошибки в проде.

Выглядит так, будто вам нужен один метод, умеющий возвращать данные по параметрам, а все остальные методы должны реализовываться через него.
Для склада, кстати, тоже отдельный метод.
И никогда не вызывать базовый метод в клиентском коде (в c++ его можно вообще сделать private).
Тогда реализация методов-обёрток будет минимальной (вызов базового с полным набором параметров) и ошибки из статьи станут маловероятными (при изменении требований надо будет только поправить параметры методов).

Это лишь отодвинет ошибку (ситуация №1 с тем, что мы забыли внедрить параметр в какой-то метод повториться на более высоком уровне), но к сожалению не исключит ее.

Да понятно, что когда требования меняются на ходу – рано или поздно влипнешь.
Но тут ситуация типовая, так что, если использовать типовое же решение (метод решает одну задачу, не две разных для разных модулей) – шансы попасться минимальны.


Я, собственно, не спорю с тезисом статьи (если бы вы были абсолютно неправы – программистов можно было бы заменить роботами, но пока нет, тут думать надо), просто пример не совсем удачный при нынешнем развитии практик программирования.

Если метод вызывается из нескольких мест, например каталог, акции, статьи (назовет места № 1,2,3), то при дальнейшем дроблении метода (например ввели еще один флаг, наподобие active), например на места — 1,3 и другое — 2, опять может возникнуть ошибка, что мы где-то забудем посмотреть (например 1 и 2 посмотрели, а 3 — забыли). Мест может быть и 50.
задумайтесь об архитектуре, проведите рефакторинг.

Кстати, а как можно забыть посмотреть, если при введении нового флага нужно во всех местах, где метод вызывается, подставить значение для нового параметра?

Было Product::getProducts. Мы заменили вызов в части кода на Product::getActiveProducts. Вы уверены что мы везде заметили, где надо, а где не надо — не заменили? Т.е. нам надо найти все вызовы Product::getProducts и вручную всё просмотреть. Что не всегда возможно (если метод вызывается через рефлексию например), человеческая ошибка и т.д. Т.е. именно через архитектуру кода, т.е. организацию методов и классов, такая ошибка не решается.
Мы заменили вызов в части кода на Product::getActiveProducts. Вы уверены что мы везде заметили, где надо, а где не надо — не заменили?

Очень просто: делаете вызов getProducts невозможным.

Да, отличная идея, указал в UPD к статье.
Т.е. именно через архитектуру кода, т.е. организацию методов и классов, такая ошибка не решается.
Естественно! Ведь решать этот вопрос через архитектуру кода — костыльный подход. Архитектура не должна отвечать за забывчивость программиста (во втором случае) — за это отвечает уже IDE.

То есть метод должен быть один (иначе тогда вообще ничего не поможет), а информация о вызывающих его местах выносится на другой уровень, за пределы кода.

(про это уже написали, но тем не менее)
А кстати, если запретить вызов функций/методов с указанием произвольного количества параметров (когда остальные устанавливаются по умолчанию), то компилятор выдаст ошибку (когда вызывать будут для склада). Это как ошибки типов в динамических языках.
Так что автор не прав в том, что это непреодолимое препятствие.

Сразу почему-то пришла идея через цепочку фильтров. В общем, нужно сделать набор композабельных друг с другом фильтров и фабрику, собирающую фильтры под наши нужды. Я бы тут начал топить за ФП и легкость композиции всего со всем, если бы хорошо его знал :). Картинки под спойлером, уж простите за псевдографику


Допустим, у нас есть сайт с товарами. У нас есть метод Product::getProducts — возвращает массив товаров.

Заголовок спойлера
Products Store
|
Products 

class ProductsSelector : IProductsSource
{
    public ProductsSelector(IProductsSource) { /* ... */ }
}
...
class PublicProductsViewer
{
    public PublicProductsViewer(IProductsSource) { /* ... */ }
}

А чтобы централизованно иметь возможность настроить этот самый source примени какую-нибудь фабрику или IoC контейнер...


Затем к нам пришел менеджер и сказал: хотим сделать акции на сайте… и сказал что нужны еще статьи, к которым прикреплены товары.

Заголовок спойлера
Products Store
|_________________________
|             |          |
Products   By Action   By Article

к нам пришел менеджер и говорит — мы хотим иметь возможность отключать товары на сайте

Заголовок спойлера
Products Store
|
Visible Products
|_________________________
|             |          |
Products   By Action   By Article

Окей, добавляем еще один Source и перенастраиваем фабрику.


хотим показывать товары в складской программе.

Заголовок спойлера
Products Store
|
Visible Products   
|_________________________
|             |          |
Products   By Action   By Article

Окей, наш WarehouseViewer будет в качестве IProductSource использовать ProductsStore, в котором есть все продукты


На шарпе это, наверное, можно сделать более лаконично с каким-нибудь LINQ.


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

При внедрении VisibleProducts, вы уверены, что найдете все места, где Products надо будет заменить на VisibleProducts? В том и ошибка, что можно где-то пропустить (человеческая ошибка). И такие места, где можно что-то пропустить могут встретиться всегда, независимо от иерархии, и иерархией (архитектурой кода) именно такая проблема, не решается. И результат — идеальной архитектуры — не бывает.
При внедрении VisibleProducts, вы уверены, что найдете все места, где Products надо будет заменить на VisibleProducts?

Вот именно поэтому надо формулировать в терминах бизнеса. Все, что касается логики магазина должно работать через одну дырку, которая возвращает доступные для магазина продукты. Не visible/all, а именно "productsInStore".

Если расщепить Products на VisibleProducts и AllProducts и запретить вызов Products снаружи – пропустить будет сложнее.
Правда, захочется зарефакторить чуток, чтобы имена не бредовые были.

Отличная идея! Сделаю Update.

Возможно, я не очень понятно выразил мысль. Нигде VisibleProducts не используется как есть, везде интерфейс. Соответственно, заменить нужно только в одном месте — в фабрике или в настройке IoC контейнера. Ну, быть может, при попытке это реализовать, я бы понял, что тут что-то не так.


Можно пойти дальше, и оперировать разными типами. В одном месте Product, в другом месте WarehouseProduct итп итд, чтобы компилятор следил.


И результат — идеальной архитектуры — не бывает.

Не спорю

Вроде как Роберт Мартин и говорил об этом — ответственность одного актера. Бэк-офис со складом — это один актер, а фронт-офис с сайтом — это другой. То что менеджер приходит один и тот же — издержки производства.

И проблема тут в том, как правильно распределить ответственность. Задними умом то мы все горазды. Как это сделать заранее? Никак, мы не телепаты. Все равно придется перекраивать. А вот насколько легко перекроить — это в наших силах. Каждый случай уникальный, рассмотрю на конкретно этом примере в статье:

1. Фронт-офис, показать все продукты, метод getProducts, без доп. условий.
2. Фронт-офис, показать продукты по акциям getProductsByActionId, ссылается на getProducts, внутри содержит доп. условие
3. Фронт-офис, показать продукты по статья getProductsByArticleId, ссылается на getProducts, внутри содержит другое доп. условие
4. Бэк-офис, показать все продукты — пока что используем getProducts
5. Фронт-офис, показать только активные продукты, бэк-офис тут ж не причем? значит делаем getFrontOfficeProducts и getBackOfficeProducts, они оба ссылаются на getProducts, для getProductsByActionId и getProductsByArticleId меняем ссылку на getFrontOfficeProducts, а для бэк-офиса начинаем использовать getBackOfficeProducts, при этом только внутри getFrontOfficeProducts ставим условие where IsActive = true
6. Допустим дальше будет признак soft delete и надо запретить показывать удаленные и на складе и на сайте — тогда есть смысл сложить его в getProducts, если только для сайта — кладем в getFrontOfficeProducts

Т.е. получается иерархия условий и они постоянно меняются. Но если дробить их на мелкие кусочки, которые легко компоновать (и сами эти кусочки остаются максимально стабильными и неизменными) — то потом легче адаптировать ПО под новые требования.

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

"Приходит менеджер и говорит: хотим показывать товары в складской программе. Ок. Мы уже поняли, что будет, если мы добавим метод Store::getProducts — в какой-то момент доработки программы мы можем просто про него забыть, и не внести в него необходиму логику. По-этому переиспользуем метод Product::getProducts."


Я бы тут не переиспользовал. Забыть целый модуль не получится, так как он, чаще всего, фигурирует в т. з.

Не везде есть тз, заказчик одной фичи может вообще не знать про другие, про тот же бэкофис
Если вас попросили «сделать лучше», то вам придется искать все вызовы начиная с бд. После этого спросить заказчика, какие модули ему нужны. А мой подход позволяет 1. не беспокоиться о том, что что-то сломается в этом модуле, если завтра в другом модуле опять возникнет необходимость изменить Product::getProducts 2. когда вас попросят изменить конкретный модуль, вам не нужно будет идти по вызовам совсем. За счет проигрыша в DRY.

Не вижу проблемы.Пишем private метод в который на вход подаем данные и фильтр и потом уже можем написать необходимые нужные нам public методы в которых мы будем вызывать наш private метод с необходимым нам фильтром.

Отличный способ, добавил в UPD статьи.
Кажется автору следует изучить паттерн Спецификация и больше не думать ни о разных методах, ни об одном методе. Входная точка всегда будет определять спецификацию товаров, которые необходимо выдавать

Как мне кажется, в данном случае нужно не плодить методы getProducts***(), а использовать классический шаблон Спецификация.


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

Тут два варианта есть: как уже было сказано выше — паттерн Спецификация.


Второй (похожий) вариант это простейшая композиция (тоже в комментариях выше было упомянуто), т.е. есть интерфейс ProductProvider, базовая реализация возвращает все объекты, и её можно завернуть в другую реализацию интерфейса — фильтрующая/авторизующая прокси/middleware, которая вызывает другой ProductProvider и убирает ненужные элементы на основе известных ей специфичных правил (но тогда, правда, из БД будет всё тянуться в память).


Пихать кучи аргументов в функции, или множить функций (раздувая класс), так себе вариант. Штуки вроде Product::getProductsForCatalog тоже неудачный вариант, так как сущность Product начинает знать про какой-то специфичный каталог, хотя скорее должно быть наоборот (каталог знает про Product)

Вот я тоже о чём-то таком подумал. Выделение отдельного слоя для какой-то провайдер, например TableGateway или Collection, который уже работает напрямую с хранилищем.

1. Сущность «репозиторий», которую использует клиентский код ProductRepository::getList(SearchCriteriaInterface searchCriteria)

2. Внутри репозитория используется например коллекция
IF (searchCriteria::getActionId()) {
ProductCollection::addFilter(action_id = ...)
}
IF (searchCriteria::getArticleId()) {
ProductCollection::addFilter(article_id = ...)
}

3. Тогда где-то здесь легко будет добавить дефолтный фильтр
ProductCollection::addFilter(is_active = 1)
Который применится для всех вызовов ProductRepository::getList()
Второй (похожий) вариант это простейшая композиция (тоже в комментариях выше было упомянуто), т.е. есть интерфейс ProductProvider, базовая реализация возвращает все объекты, и её можно завернуть в другую реализацию интерфейса — фильтрующая/авторизующая прокси/middleware, которая вызывает другой ProductProvider и убирает ненужные элементы на основе известных ей специфичных правил (но тогда, правда, из БД будет всё тянуться в память).

Это от особенностей языка и фреймворка зависит, будет ли все тянуться в память. На C# с ORM Entity Framework, если для фильтров обойтись только LINQ, можно воспользоваться возможностями интерфейса IQueryable — который умеет передавать условия фильтров в ORM, который сконструирует запрос SQL по этим условиям.

Не только идеальной архитектуры не существует — также нет идеального рассмотрения проблем, как и идеальной критики — ложные умозаключения, логические неувязки в выводах и прочее.
Как писал Пит Хейн в своих груках
The road to wisdom? — Well, it's plain
and simple to express:
Err
and err
and err again
but less
and less
and less.
Главное стремление к идеалу, и качественные программные продукты этому стремлению соответствуют.

То, что нам надо поправить код не в 1 месте, порождает ошибки — в каком-то месте забыли поправить.

Бывает.

Что же, давайте сделаем так, чтобы у нас было только 1 место, откуда доставать товары. Тогда такой ошибки не будет.

Зато появится другая.

Получается что написать 1 метод — это приведет в определенной ситуации к ошибке, и написать несколько методов — это приведет в другой ситуации к ошибке.

Что и требовалось доказать!

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

«Безвыходных ситуаций не бывает, даже если вас съели. Как минимум, есть три выхода!» :)

У меня, кстати, неделю назад возникла подобная проблема. Я начинал делать несколько проектов на С++, как любитель, но рано или поздно возникали проблемы развития и модифицирования кода. Что-то забывал, что-то не до конца понимал и т.п.

В итоге решил, что надо менять свой подход к программированию. После некоторых размышлений остановился на идее итерационного модульного (секционного) программирования. Идея простая, нужно вносить изменения только во внешние файлы данных, как я их называю, «реплики изменений». А первоначальный файл, с псевдокодом для проекта, пишу вручную, в так называемом файле «предисходников». Затем пишу скрипт на Питоне, который из нулевой итерации предисходников и первой итерации реплик изменений формирует, как первую итерацию предисходников, так и первую итерацию файлов проекта, которые уже будет компилировать С++. Затем процесс итерации повторяется.

За неделю изучения Питона, у меня появилась первая реальная программа, которая умеет генерировать первую итерацию предисходников (некий псевдокод, типа С++) и реальных исходников на С++. Завтра, надеюсь, перейти уже ко второй итерации.

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

Это решается легко при наличии квери билдера. Передаете в.метод getProducts набор фильтров или критериев, которые добавляют в квери билдер необходимые условия и все. Можно еще ивент листенарами сделать, тогда править код надо будет в одном месте независимо от того где был вызван getProducts

А почему программисты должны все эти случаи помнить? Они что, тесты не пишут? Добавили новое поле, в тестовых данных дали поле части данных — получили пачку красных тестов. Если они не красные — разбираемся почему. Получили все тесты красными — дописали ещё тестов (что в ТЗ написано), после этого пошли писать код.


А кто тестов не пишет, red-green не практикует, того забодает-забодает! (с) детская песенка.

Комменты по диагонали глянул, вроде не повторяюсь

В комментариях указали, что если сделать 1 метод: Product::getProducts, и затем при изменении в нем назвать его например Product::getProductsV2, а Product::getProducts вообще запретить вызывать, то тогда тогда мы точно найдем все места, где этот метод вызывался, и исключим ошибку.

Если просто делать Product::getProductsV2, то потом появится Product::getProductsV999, и из этой тысячи могут работать условно 2, 105, 365, 875, 999. Боль.
Если просто кидать эксепшен — то какой в этом вообще смысл? Не проще сделать поиск по всему коду? Тем более многие IDE штатно умеют показать все вызовы функции.
Через класс выглядит интереснее, но если задача решается не на С++ то могут быть языковые нюансы.

Более универсальный подход (имхо) — тесты. Причём сначала пишем тест по новому требованию, и если сразу собрать — будет ошибка (кода же нет). И правим под новые требования именно тесты, а потом правим все места где тесты упали. Если код вменяемый, это несложно. При этом весь старый код, который не трогает новый функционал, работать будет нормально (и при правильном написании «появился active, тест 'склад' упал»). Конечно, тесты тоже не панацея, и 100% случаев не покрыть, и на поддержание нужно больше сил и времени, но жизнь оно упорядочивает. Да и вообще, очень сильно помогает от краевых случаев, а для рефакторинга вообще 100% польза.
Мой вариант решения — по шаблону проектирования «Декоратор»
Для своего личного удобства пример напишу на C#.
1. Класс с информацией о продукте
class Product {
  //Набор свойств продукта 
}

2. Интерфейс для возврата списка продуктов
interface IProductList {
   IQueryable<Product> GetProducts();
}

3. Класс для извлечения списка продуктов из хранилища
class BaseProductList: IProductList {
      public IQueryable<Product> GetProducts() {
        //Вытаскивает данные из хранилища, например через Entity Framework
     }
}

abstract class ProductFilter: IProductList {
  protected m_SourceList;
  protected ProductFilter(IProductList SourceList) {m_SourceList=SourceList;}
  protected abstract IQueryable<Product> PerformFiltering(IQueryable<Product> Source);
  public IQueryable<Product> GetProducts() 
  {
     return PerformFilter(m_Source);
  }
}


<code>


… случайно нажал отправить, сейчас допишу продолжение
Короче, не успел дописать. Излагаю общую идею:

Определить класс продукта Product интерфейс для возврата списка продуктов с одним методом IQueryable GetProducts(), и набор классов, реализующих этот интерфейс: базовый класс для извлечения из хранилища (с помощью ORM Entity Framework из БД к примеру) и набор классов-фильтров, имеющих входной параметр — этот интерфейс и реализующих этот интерфейс (собственно, они и являются теми самыми декораторами). Реализацию фильтров — делать через LINQ по возможности. Если целесообразно, то можно создать промежуточный класс, возвращающий список в соответствии с неким предопределенным набором фильтров (например — только активные продукты) и использовать его в нескольких местах.
А далее всем классам, которые что-то обрабатывают или отображают — передавать этот интерфейс как параметр конструктора.
Какую именно реализацию интерфейса передать в конструктор — либо написать нужную комбинацию фильтров руками для каждого отобрающего класса, либо вообще воспользоваться DI-контейнером, чтобы он сам конструировал отображающие классы, использующие нужный набор фильтров — тогда вообще красота, менять нужно только настройки DI-контейнера.
А еще использование IQueryable имеет то преимущество, что он позволяет не вытягивать весь список продуктов в память, чтобы их фильтровать, а передать параметры фильтров в ORM, чтобы тот сконструировал нужный SQL-запрос.
PS И все это хорошо, если изначально понятно, что задача будет усложняться таким вот образом.
А далее всем классам, которые что-то обрабатывают или отображают — передавать этот интерфейс как параметр конструктора. Какую именно реализацию интерфейса передать в конструктор — либо написать нужную комбинацию фильтров руками для каждого отобрающего класса, либо вообще воспользоваться DI-контейнером, чтобы он сам конструировал отображающие классы, использующие нужный набор фильтров

В этот момент понять по коду, с какими данными работает класс-потребитель, будет практически невозможно. Равно как и протестировать, что он работает именно с теми, с которыми мы ожидаем.


Так что не очень понятно, в чем профит от этого решения по сравнению с нормальными именованными интерфейсами.

В этот момент понять по коду, с какими данными работает класс-потребитель, будет практически невозможно. Равно как и протестировать, что он работает именно с теми, с которыми мы ожидаем.

Не понял, почему невозможно тестирование. Тестовый метод вполне может запросить интерфейс аналогично тому, как он запрашивается для передачи в конструктор класса-потребителя, и проверить, что он через этот интерфейс возвращается нужное подмножество данных из порождаемых базовым классом (обычно фиктивным, который специально для тестов). Это по-любому делать стоит, ибо необходимо тестировать правильность настройки DI-контейнера (или — работы используемого вместо него своего велосипеда).
Классу-потребителю вообще-то знать, с какими именно множеством данных он работает, знать не надо: это находится вне области его ответственности.
Однако если есть обоснованные подозрения, что тут высока вероятность ошибки при дальнейшей разработке, то для каждого класса-потребителя (или функционально сходной их группы) можно изначально завести свой интерфейс для передачи в конструктор — со своим именем, но одинаковыми методами: тогда даже компилятор не пропустит «не тот» интерфейс. Плюс — класс-фильтр для преобразования обобщенного интерфейса списка в конкретный для передачи в класс. Но это лучше делать именно что сразу — иначе легко пропустить, какие именно классы менять. Однако и у такого решения есть обратная сторона: снижается функциональность класса-потребителя: например, если нужно подсчтитыватать что-то сходное (упрощенный пример — количество позиций на складе и в продаже), потребуется практически дублирующийся код этого подсчета (хотя в упрощенном примере выше — это всего лишь вызов Count(), но тем не менее). С этим тоже можно бороться — если все такие интерефейсы унаследовать от общего предка, и в такие классы общего назначения передавать этого общего предка.
Короче, простора для вариантов тут много, и в каждом конкретном случае думать нужно отдельно.
Тестовый метод вполне может запросить интерфейс аналогично тому, как он запрашивается для передачи в конструктор класса-потребителя

Вы в этом случае тестируете механизм инъекции, и это, по опыту, чрезвычайно муторное (и обычно весьма бесполезное) занятие.


Это по-любому делать стоит, ибо необходимо тестировать правильность настройки DI-контейнера

… а зачем? Для большей части случаев у вас тестирование контейнера должно сводится к "на каждую запрошенную зависимость есть регистрация", а это сравнительно тривиально.


Классу-потребителю вообще-то знать, с какими именно множеством данных он работает, знать не надо: это находится вне области его ответственности.

Это почему вдруг? Сервис бизнес-логики для склада должен явно знать, что он работает с множеством данных о складе, а не о магазине, иначе мы будем постоянно путаться.


потребуется практически дублирующийся код этого подсчета

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

Вы в этом случае тестируете механизм инъекции, и это, по опыту, чрезвычайно муторное (и обычно весьма бесполезное) занятие.

Не механизм, а результат работы.
… а зачем? Для большей части случаев у вас тестирование контейнера должно сводится к «на каждую запрошенную зависимость есть регистрация», а это сравнительно тривиально.

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

Когда я писал, то у меня в голове было про контроллер (точнее — возвращаемое им представление), задача которого — не логикой заниматься, а отобразить то, что ему дали. С бизнес-логикой могут быть варианты, да.
Вот это как раз не так: чтобы подсчитать количество элементов во множестве, вы работаете с этим множеством, а у него нормальный универсальный интерфейс.

Т.к. пример был упрощенным, такое возражение возможно (и я его, кстати, предвидел и написал про него). Но ведь может быть и более сложная общая для разных частей логика (хотя я ее не придумал — но ведь может же), и тогда одного факта того, что потребитель работает с IEnumerable («множеством») для ее реализации может не хватить.
Вопрос в том, как вы получаете это множество, и здесь, если мы хотим избежать ошибок, описанных в статье, явные выделенные интерфейсы (или методы одного интерфейса) намного выгоднее.

Ситуация неоднозначного выбора. Выигрывая в одном (избегаем ошибок) — проигрываем в другом(порождаем ненужные зависимости: контроллеру, к примеру, они явно ни к чему). Короче, тут надо выбирать для конкретной задачи.
А если регистрация неправильная — это пропускаем?

А не должно быть возможности сделать "неправильную" регистрацию (не считая случаев, когда у нас настраиваемое ПО, но его конфигурация тестируется отдельно в таких случаях).


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

В том-то и дело, что не надо делать нетривиальные зависимости. Это почти никогда себя не оправдывает — в моем, конечно, опыте.


Когда я писал, то у меня в голове было про контроллер, задача которого — не логикой заниматься, а отобразить то, что ему дали.

А кто определяет, что ему "дали"? Бизнес-слой. Не DI-контейнер, нет — иначе у вас инфраструктура начинает заниматься бизнесом.


порождаем ненужные зависимости: контроллеру, к примеру, они явно ни к чему

Я вот что-то не вижу никаких ненужных зависимостей. Если у вас специализированный контроллер (отдельно StoreController, отдельно WarehouseController), то совершенно нормально, что он говорит со специализированным API — один с StoreService, другой с WarehouseService. У каждого контроллера ровно по одной зависимости, ничего лишнего. Если у вас обобщенный контроллер (EntityDisplayController<TEntity>), то, опять же, нормально, что он говорит с обобщенным сервисом EntityService<TEntity>, но только надо понимать, что в этом случае у вас должны быть разные сущности для склада и магазина, иначе никак. Но зависимость все равно остается одна, ничего лишнего.


Explicit is better than implicit, ничего нового.

А не должно быть возможности сделать «неправильную» регистрацию (не считая случаев, когда у нас настраиваемое ПО, но его конфигурация тестируется отдельно в таких случаях).

Ну, строго говоря, однажды написанную и работающую программу можно вообще больше не тестировать — программы сами по себе не ломаются.
Но мы ведь тут про ошибки программиста при доработке программы, не так ли? А у программиста возможность сделать неправильную регистрацию отнять, так скажем, сложно. Потому тестировать приходится.

В том-то и дело, что не надо делать нетривиальные зависимости. Это почти никогда себя не оправдывает — в моем, конечно, опыте.

А кто определяет, что ему «дали»? Бизнес-слой. Не DI-контейнер, нет — иначе у вас инфраструктура начинает заниматься бизнесом.

Чувствую, надо определиться с терминологией: мы с вами под одним названием явно подразумеваем разные вещи. Предлагаю избавиться от слова «DI-контейнер», потому что мы тут обсуждаем сущность, которая определяет какую реализацию интерфейса вернуть, исходя из большего числа параметров, нежели используется для типичного применения DI-контейнера (хотя по моей первой прикидке на том же Ninject, вроде как, можно реализовать все, что написано в обсуждаемой статье).
То есть, наверное, тут вы правы — по функциям это лучше считать частью именно слоя бизнес-логики, ничему тому, что я написал в исходном комментарии это не противоречит.
Если у вас обобщенный контроллер (EntityDisplayController>TEntity>), то, опять же, нормально, что он говорит с обобщенным сервисом EntityService>TEntity>, но только надо понимать, что в этом случае у вас должны быть разные сущности для склада и магазина, иначе никак. Но зависимость все равно остается одна, ничего лишнего.

Почему вы считаете, что сущность, с которой работает контроллер, может быть передана только как параметр-тип для обобщенного класса контроллера? Есть ведь альтернативный путь — передать ее как параметр конструктора экземпляра класса контроллера: как конкретную реализацию интерфейса, с которым контроллер работает. В ASP.NET MVC, к примеру, это как раз стандартная практика, а вот делать обобщенный контроллер там как раз неудобно — из-за того, что привязка контроллеров в маршрутизации запросов часто делается по именам их классов.
Разделить же сущности понятным для статической проверки образом, если это так уж требуется, тоже можно: сделать по своему интерфейсу для каждой сущности с одинаковым (или сходным) набором методов — и я об этом писал раньше.
Explicit is better than implicit, ничего нового

Это не всегда так: явная зависимость снижает степень гибкости. А какая степень гибкости оптимальна в данном конкретном случае — это вопрос, который решается при проектировании конкретной системы.
А у программиста возможность сделать неправильную регистрацию отнять, так скажем, сложно.

Легко: если у вас для любого интерфейса есть ровно одна реализация (кроме тестовых, которые находятся в проектах, которые недоступны из точки сборки), то неверная регистрация просто невозможна.


Почему вы считаете, что сущность, с которой работает контроллер, может быть передана только как параметр тип для класса контроллера?

Не "может быть", а "следует". Потому что это позволяет работать со статической типизацией со всеми ее достоинствами.


В ASP.NET MVC, к примеру, это как раз стандртная практика

Ни разу не видел "стандартной" практики в этом фреймворке (а я на нем прилично писал), где в зависимости от роута передавались бы разные зависимости. В стандартной поставке такой функциональности нет, придется делать свою имплементацию фабрики, а дальше уже пофиг, что туда вкручивать.


Это не всегда так: явная зависимость снижает степень гибкости.

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

Легко: если у вас для любого интерфейса есть ровно одна реализация (кроме тестовых, которые находятся в проектах, которые недоступны из точки сборки), то неверная регистрация просто невозможна.

Переформулирую: программисту сложно запретить сделать другую реализацию этого интерфейса. И не сомневайтесь: у него найдется куча обоснований, почему надо так сделать.
Ни разу не видел «стандартной» практики в этом фреймворке (а я на нем прилично писал), где в зависимости от роута передавались бы разные зависимости.

Я про обобщенные классы для контроллеров писал. И про стандратную практику передавать параметр-интерфейс в конструкторе контроллера. Ну, а разные реализации этого интерфейса — они появляются в разных версиях программы, по мере ее доработки, вон прямо как в обсуждаемой статье описано.
В стандартной поставке такой функциональности нет, придется делать свою имплементацию фабрики, а дальше уже пофиг, что туда вкручивать.
Напромните, а в «стандартной поставке» там когда DI-контейнер вообще появился? В MVC4 его точно не было, к примеру, нужно было что-то дополнительное, что через NuGet ставится. Правда, без собственной фабрики контроллеров обойтись было можно, ибо цеплялось оно все чаще в другой точке: к DependencyResolver.
Не «может быть», а «следует». Потому что это позволяет работать со статической типизацией со всеми ее достоинствами.

Йеп, это именно то, что меня интересует: я считаю, что в общем случае система должна иметь минимально возможную степень гибкости.

Я понял и запомнил вашу точку зрения. Но как вы знаете, она не универсальная. И даже не самая популярная — как я заметил, евангелисты от IT сейчас, наоборот, пропагандируют максимальную гибкость. Например: не надо никаких вручную написанных SQL запросов в слое хранения — а вдруг мы захотим перейти на NoSQL? Ну а уж как не любят статическую типизацию те, кто привык обходиться без нее — фронтэндщики, например — я думаю вы знаете.
У меня же личной точки зрения, которую я готов отстаивать по личным соображениям, на все это нет: я просто добавляю ещё одну альтернативу в свой список имеющихся, ещё один инструмент — в свой набор. А чем потом воспользоваться в конкретном случае — это, я считаю, вопрос уже чисто конкретный. Не для рассуждений про вообще, типа комментариев к этой статье.
Собственно, мой исходный комментарий был вызван как раз желанием показать еще один возможный способ решения проблемы из статьи.
Переформулирую: программисту сложно запретить сделать другую реализацию этого интерфейса.

Да нет, тоже легко. Статический анализатор с этим прекрасно справляется.


Ну, а разные реализации этого интерфейса — они появляются в разных версиях программы

… так как выяснить, какую передавать-то?


Напромните, а в «стандартной поставке» там когда DI-контейнер вообще появился?

Не помню.


евангелисты от IT сейчас, наоборот, пропагандируют максимальную гибкость

Евангелисты — они разные. Я слышал разные точки зрения.


Например: не надо никаких вручную написанных SQL запросов в слое хранения — а вдруг мы захотим перейти на NoSQL?

Омфг. Сколько раз я это слышал, и сколько раз выяснялось, что переход на NoSQL там невозможен по совершенно другим причинам, никак не связанным с вручную написанными SQL в слое хранения (т.е. ровно в том месте, которое будет заменено при переходе на NoSQL).


Ну а уж как не любят статическую типизацию те, кто привык обходиться без нее — фронтэндщики, например — я думаю вы знаете.

Да пусть не любят, мне-то какое до этого дело? В вашем примере C#, я тоже пишу на C#, это статически типизированный язык.


Собственно, мой исходный комментарий был вызван как раз желанием показать еще один возможный способ решения проблемы из статьи.

… который сам не решает проблему возникновения ошибок в статье. О чем, собственно, и речь.

Да нет, тоже легко. Статический анализатор с этим прекрасно справляется.

Статический анализатор не запрещает. Он всего лишь обнаруживает. А дальше наступает черед той самой упомянутой мной кучи обоснований. Можно, конечно, запретить плодить реализации директивно. Но иногда это действительно оказывается нужным
… так как выяснить, какую передавать-то?

Вариантов — много: по имени класса-потребителя или класса/интерфейса в его иерархии наследовния (знаете, к примеру, такой прием — маркерные интерфейсы, которые без методов, да?), по типу/значению дополнительного параметра в конструкторе… Но вот идеального, позволяющего избежать всех ошибок — нет.
который сам не решает проблему возникновения ошибок в статье. О чем, собственно, и речь

Решить эту проблему в виде «устранить возможность ошибок при модификации программы вообще», наверное, невозможно. По крайней мере — на практике. По крайней мере — я о таком не слышал (а если мне расскажут, как — с удовольствием воспользуюсь: я тоже не люблю делать ошибки).
Но можно решить похожую проблему «снизить вероятность возникновения ошибок при модификации программы до приемлемого уровня». Один из типовых способов решения — локализация: связанные изменения должны затрагивать небольшой участок кода. Вынесение в одно место всех точек принятия решения о том, какое множество данных использовать в каждом конкретном блоке логики — в место, где определяется, какая реализация описывающего это множество интерфейса будет использоваться в других местах — это как раз реализация этого способа.
Да пусть не любят, мне-то какое до этого дело? В вашем примере C#, я тоже пишу на C#, это статически типизированный язык.
Не совсем. В нем такие есть dynamic. И человек, обучавшийся программированию, к примеру, на Питоне, с удовольствием им воспользуется.
Статический анализатор не запрещает. Он всего лишь обнаруживает.

Это вопрос того, как вы процесс настроите. У нас вот некоторые вещи просто упадут на билд-машине, потому что низя.


Но иногда это действительно оказывается нужным

Ну вот когда нужно, там и будет поставлено специальное исключение. После обсуждения и обоснования, а не просто так.


Вариантов — много: по имени класса-потребителя или класса/интерфейса в его иерархии наследовния (знаете, к примеру, такой прием — маркерные интерфейсы, которые без методов, да?), по типу/значению дополнительного параметра в конструкторе…

И почти все они (а в случае контроллера — просто все) требуют разных классов-потребителей. А это значит, что технически уже ничего не мешает сделать выделенный интерфейс.


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

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


В нем такие есть dynamic. И человек, обучавшийся программированию, к примеру, на Питоне, с удовольствием им воспользуется.

Ну, у меня такой код просто не пройдет code review и не будет вмержен.

Ну вот когда нужно, там и будет поставлено специальное исключение. После обсуждения и обоснования, а не просто так.

Однако это случится практически непремено. И что-то мне подсказывает, что за основание сойдет и «некогда переделывыть, сроки горят». Не, это конечно, отправится в долгий ящик (AKA backlog) и будет даже переделано «когда-нибудь», не спорю. Но «временно» оно существовать будет.
И почти все они (а в случае контроллера — просто все) требуют разных классов-потребителей. А это значит, что технически уже ничего не мешает сделать выделенный интерфейс.

Почему в случае контроллера — обязательно все? Это такой же класс, и даже не запечатанный: и он может унаследовать любой интерфейс, и от него можно интерфейс унаследовать… Ну, а то, что выделенный интерфейс не мешает сделать ничто, так в с этим я изначально был согласен: ничто не мешает — кроме желания сохранить гибкость и легкость переиспользования кода.
вот только SRP нарушается, потому что у вас на этот блок влияет сильно больше одного потребителя.

Ну почему же нарушается? Выдать потребителю правильную реализацию — это как раз и есть ответственность этого блока, и эта ответственность — она у него единственная (если других не навесить, конечно). Ну а потребитель жрет, что даютработает с теми данными, которые ему выданы, а на выдающего не влияет.
Ну, у меня такой код просто не пройдет code review и не будет вмержен.
Ну, если все PR идут только через вас — вы счастливый человек. Или — все же несчастный (потому что PR — их может быть много, очень)?
PS Если вы не сильно против, думаю, что я на этом завершаю обсуждение: все, что я хотел сказать, я уже сказал, и все основное, что мог услышать в ответ — полагаю, уже услышал.
А ещё у меня пальчики устали.
. И что-то мне подсказывает, что за основание сойдет и «некогда переделывыть, сроки горят».

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


Почему в случае контроллера — обязательно все? Это такой же класс, и даже не запечатанный: и он может унаследовать любой интерфейс, и от него можно интерфейс унаследовать…

Потому что все ваши примеры требуют разных классов-потребителей. Хотите вкинуть разный сервис в зависимости от маркерного интерфейса на контроллере? Вам нужно два разных класса контроллера, иначе никак.


кроме желания сохранить гибкость и легкость переиспользования кода.

Вот только гибкость и легкость переиспользования здесь находятся в противоречии. Гибкость у варианта с двумя интерфейсами выше, потому что у вас два разных потребителя, зависящих от разных интерфейсов, могут развиваться совершенно независимо, и это как раз гибкость. А вот переиспользование — это да, это проблема, оно здесь ухудшается, если не предпринимать дополнительных мер.


Ну почему же нарушается? Выдать потребителю правильную реализацию — это как раз и есть ответственность этого блока, и эта ответственность — она у него единственная

Потому что причин для изменения больше одной. Меняется набор данных, используемых складским контроллером? Поменяли ваш код. Меняется набор данных, используемых магазинным контроллером? Поменяли ваш код. Добавляется новый контроллер, которому нужен очередной набор данных? Опять поменяли ваш код.


Ну, если все PR идут только через вас — вы счастливый человек.

Зачем мне все? Мне нужны те, которые в моей зоне ответственности. Они, да, идут через меня.

Возможно тут стоит упомянуть про книги Дядюшки Боба из "прачечной" серии: "Чистая архитектура", "Чистый код" и т.п.
На мой взгляд чтение таких книг весьма полезно для более лучшего понимания архитектуры кода :)

ProductManager::for_each_product(функтор)
и передавайте туда любые предикаты которые хотите
И получим дичайшие тормоза, когда нужно выбрать 10 продуктов из базы в 100 миллионов.
я на самом деле не очень шарю в веб программировании. мне оно всегда казалось очень скучным, так как просто сводится к отображению части информации базы данных на экран. и не то, чтобы ты сам реально писал код select_by_product_name, это все равно все сводится к ручной настройке ключей, построению правильного селекта и передачу всего этого реальному коду, который и делает всю работу.
мне оно всегда казалось очень скучным, так как просто сводится к отображению части информации базы данных на экран

Веб-программирование не сводится к отображению части информации на экран. Не больше, чем любое другое программирование для line-of-business.


передачу всего этого реальному коду, который и делает всю работу.

А этот "реальный код" — он где, простите, живет?

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

(как я люблю такой уровень дискуссии)


Ну вот давайте на наглядном примере. Хабр, на которомы мы с вами друг другу пишем. Это веб-программирование, совершенно типовое. И очевидно, что к отображению информации он не сводится, потому что я эту информацию прямо сейчас ввожу.


(Это не считая того, что какой-нибудь там Гугль — это "просто" отображение информации из "БД" на экран. Просто?)


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

Удивительно, но это вообще в программировании так, веб тут не специфичен.


У меня, правда, вопрос: если все так просто и скучно, то зачем инструменты-то менять приходится?


И да, мне продолжает быть интересно:


передачу всего этого реальному коду, который и делает всю работу.

А этот "реальный код" — он где, простите, живет?

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

Вот только веб не ограничивается задачей "select по критерию из большой базы". Вот нифига не ограничивается.

Вообще субъективно. Для кого-то кодеки «совершенно узенькая конкретная задача», что мы там не видели из теории информации: моделирование, кодирование. Модели все описаны в литературе, способы кодирования тоже, всё 100 раз жёвано-пережёвано, садись и пиши типовый шаблонный код.
и тут я согласен. просто автор статьи дает пример, как он думает, достаточно абстрактной задачи по дизайну, демонстрирующей некие фундаментальные проблемы, но по факту никаких проблем нет из-за узости этой задачи. это примерно если бы кто-то жаловался, что у него дома на клавиатуре клавиша enter залипает и на основании этого бы делал вывод о неудобстве современных устройств ввода информации
автор предлагает, как ему кажется разумный код, но на самом деле лично мой бы code review он бы не прошел, начиная вообще с первой строчки Product::getProducts — что это за фигня вообще? почему один продукт может выдавать список продуктов?
Action::getProductsByActionId(actionId)
— тоже хрень. что, action должен иметь switch чтоли по action id внутри? и так далее. ну там просто фундаментальные ошибка на ошибке в дизайне
На эту тему нет единого мнения.
Я бы предпочёл ProductManager::getProducts, но где-то видел жёсткую критику всех классов с названиями типа XxxxManager, XxxxService, XxxxUtil и т.п.
один один из классических косяков дизайна — смешение двух классов в один. наблюдается в основном у 23летних сеньеров. кто наткнулся потом на кучу грабель после никогда так больше не делает
по уму это xxxController, ну или хотя бы xxxManager. Util — тоже отстой, но самый чемпион отстоя это конечно же xxxHelper

Один из классических косяков дизайна — это называть классы словами, по которым не понятно, что класс делает. Manager — прекрасный пример такого слова.

А что делать, если в c# отобрали процедурное программирование. Функцию без класса уже не напишешь. Вот и делают классы-неймспейсы.

Ну во-первых, неймспейс с названием ...Manager — тоже штука странная.


А во-вторых, будем честными, если у вас код, отвечающий за получение продуктов из БД — функция, то может быть, надо писать уже не на C#.

Ну во-первых, неймспейс с названием ...Manager — тоже штука странная
Почему нет? Представим, что у нас есть подсистема работы с кучей в сферической-вакуумной ОС. Что мешает всё функции типа alloc/free положить в файлик MemoryManager?
А во-вторых, будем честными, если у вас код, отвечающий за получение продуктов из БД — функция
Пусть будет называеться «процедурой», чтобы не было путаницы с чистыми функциями. Так уж сложилось в си-подобных языках, что процедуры там называются фунциями, официально, а терминологии компилятора.
Почему нет? Представим, что у нас есть подсистема работы с кучей в сферической-вакуумной ОС. Что мешает всё функции типа alloc/free положить в файлик MemoryManager?

Потому что manager — это сущность. А неймспейс — он management (деятельность). В моем опыте в .net так принято.


Пусть будет называеться «процедурой», чтобы не было путаницы с чистыми функциями.

А вот процедур в C# лучше и вовсе избегать. Это все-таки ОО-язык в первую очередь.


И да, я понимаю, что обе рекомендации выше — они из области "неформализуемого дизайна", без какого-либо объективного критерия "правильно".

Как избегать, если любой вызов API — по сути процедура, то есть, функция с побочными эффектами.

Например, пишу я типичный CRUD.

Где должен быть update?
В Product::Put или в ProductManager::Put?
Как избегать, если любой вызов API — по сути процедура, то есть, функция с побочными эффектами.

Ну эта, ОО же. Объекты и методы, зачем процедуры?


Например, пишу я типичный CRUD.
Где должен быть update?
В Product::Put или в ProductManager::Put?

"Типичный" для какого языка? В C#/.net — в DbSet<Product>, потому что Entity Framework. Или в IRepository<Product>, если вы не хотите завязываться на EF.


Product::Put — это типичный Active Record, и их в .net я (к счастью) давно не видел.

Обычный API, через который я хочу получать события, например, события появления какого-то нового товара или заказа.

Это не Repository, потому что Repository по определению абстракция от хранилища, а у меня может быть чуть-чуть бизнес-логики (например, валидация или регистрация события в других системах). Потому и ProductService/ProductManager
Обычный API, через который я хочу получать события, например, события появления какого-то нового товара или заказа.

Что значит "получать события"? Подписаться на события?


Это не Repository, потому что Repository по определению абстракция от хранилища, а у меня можеть быть чуть-чуть бизнес-логики

Если у вас "немножко бизнес-логики", то у вас уже не "типичный CRUD", и модель начинает меняться. Без конкретных деталей говорить сложно, но в вашем примере, например, валидация может быть в самой сущности, а отправка сообщения о перзисте — в репозитории.


По мере усложнения вырастет у вас либо "сервис" (что, согласен, плохое название), либо "фасад" (по крайней мере понятно, что мы агрегируем сюда бизнес-функциональность), либо "агрегат" (привет, Эванс).

Что значит «получать события»? Подписаться на события?
Подписка подразумевает, что получателей несколько. А тут просто система A передаёт событие системе B.
Если у вас «немножко бизнес-логики», то у вас уже не «типичный CRUD», и модель начинает меняться
Оно всегда начинается с обычного CRUD — возможность создавать, редактировать и удалять сущности. А потом появляются требования, и CRUD обрастает логикой.
Подписка подразумевает, что получателей несколько. А тут просто система A передаёт событие системе B.

Не понимаю. Почему это тогда не просто вызов?


А потом появляются требования, и CRUD обрастает логикой.

Когда обрастает — тогда и меняется. Я выше уже описал, как.

Почему это тогда не просто вызов?
Это просто вызов. Вопрос, вызов метода какого класса? ProductManager/ProductService?

Эээ… ну от того, какой метод, зависит же. Вы зачем-то сказали "я хочу получать события". Значит, у вас уже есть какой-то класс, которому эти события нужны. Вот его метод и надо вызывать.


Или я чего-то фундаментально не понимаю в вашем вопросе.

Так проблема в том, что нигде не записаны «правильные» принципы ООП-дизайна, с которыми все были бы согласны, которые бы всех всегда устраивали. Код работает и так, и так, а как его написать, в какие классах какие ф-ции разместить — чистая вкусовщина с т.з. компилятора.
за много лет практики мне приходилось исследовать причины багов или странных поведений. я не знаю. ну, тысячи. и в итоге я как-то для по крайней мере уяснил, что хреновый дизайн это не вкусовщина, и именно неплохой такой стабильный источник багов. плохой код почти неподдерживаемый и в этом его основная проблема, а не в том, что он мне лично не нравится. соб-но автор и говорит, что пишет неподдерживаемый код. и причина этого — он ничего не понимает в дизайне.
я как-то для по крайней мере уяснил, что хреновый дизайн это не вкусовщина, и именно неплохой такой стабильный источник багов

Если это не вкусовщина, то как объективно определить, хороший дизайн или плохой?

Это, конечно, хорошо, но: вот у вас есть два проекта с (ну наверное) разной стоимостью поддержки. Как объективно оценить, за какую долю этой разницы отвечает дизайн?

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

Эм, в каком месте "некая генерализация" — это научный подход? Где у этой "некой генерализации" объективная воспроизводимость?


хреновый дизайн это не субьективное мнение. он создает хотспоты проблем.

Проблема, однако же, в том, что совершенно не понятно, как объективно определить, какой дизайн — хреновый. Ну то есть да, вот смотрим в код, который мы уже знаем, что вызывает проблемы, наверное, там хреновый дизайн. А если пока проблем не вызывает? По аналогии с "раньше вызывало"? А это объективно?

автор пишет: смотрите, я пишу вполне разумный код. мне выдвигают вполне разумные запросы на изменения. и тут я понимаю, что мои изменения потенциально опасные. хороший дизайн, это когда разумные изменения не являются потенциально опасными. есть люди, которые говорят — это невозможно, мой дизайн уже хорош. люди делятся на тех, кто считает, что такова жизнь и на тех, кто пытается все-таки разобраться, как делать так, чтобы изменения не вносили проблем. на это уходит ну минимум 10 лет опыта и минимум, там 30-40 проектов. + теория. и даже если у вас это есть, то не факт, что это будете уметь. нужен сначала волевой факт признания, как у автора, что есть проблема в том коде, который он пишет. он молодец, он признал проблему. еще 10 лет в ней будет разбираться и научится писать хороший код. и после этого он сам начнет сразу бить людей по башке за Action::getProductsByActionId(actionId)
хороший дизайн, это когда разумные изменения не являются потенциально опасными

Во-первых, как вы объективно определите "разумность" изменения?


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


И, наконец, в-третьих: а если изменений нет, тот же дизайн — плохой или хороший?

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

бывает, что проблемы возникают при любом дизайне. просто в хорошом их на порядок меньше. то есть грубо говоря у вас от мерседеса отвалится 1 гайка на 1000км, а от запорожца 100 гаек.

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

Это противоречит моему здравому смыслу.


И это еще раз демонстрирует, что объективного критерия нет.


просто в хорошом их на порядок меньше.

Это опять постфактумная оценка. В этом ПО одна проблема в год, а в этом — 10, наверное, у первого лучше дизайн. И даже это работает только если у вас все остальные качества ПО одинаковы (чего я в своей жизни почти не видел).


А вот как объективно оценить, хороший дизайн или плохой, просто глядя на него?


если изменений нет, то всем без разницы.

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

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

Это все очень хорошо и поучительно.


А вот теперь можете ли вы назвать хотя бы одно объективное, безоговорочное правило, которое делает дизайн объективно лучше и доказуемо уменьшает вероятность такого исхода?

такого правила нет. что, есть правило, которое однозначно позволяет сделать из запорожца мерседес?
такого правила нет.

Так это ровно то, о чем вам говорят с начала этой ветки: нет объективных общепринятых правил хорошего дизайна ПО. И все. Ничего больше.


Ура, вы наконец-то с этим согласились.

И то, и другое. Какой мне смысл в объективном правиле, с которым ни я, ни все мои коллеги не согласны?

то есть раз нет обьективных четких общепринятых правил, чем собаки отличаются от кошек, то и собак и кошек тоже нет? :)

если нет четких правил описания рукописных цифр, достаточных для четкого и однозначного их распознавания, то и цифр тоже нет?

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

Нет, этот вывод никак не вытекает из того, что я сказал.

И то, и другое…
этот вывод никак не вытекает из того, что я сказал......
А по-моему, как раз и вытекает…
Вы еще скажите, что слова хорошо-плохо ничего не значат, так как нигде про их четкие критерии не написано.
А по-моему, как раз и вытекает…

Если "по-вашему" вытекает, то себе и задавайте этот вопрос.

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

к тому же не то, чтобы я хотел спорить, я скорее хотел обьяснить. чтобы понять, почему я так борзо разговариваю, можете посмотреть на linkedin на мой опыт и откуда я вообще сделал подобные выводы.
Вы — ему нет четких однозначных правил, поэтому он не может существовать.

Я несколько раз перечитал свои высказывания в этом треде, и там "он не может существовать" нет. Вы не могли бы привести конкретную цитату?

Скорее всего, вы приводите любой код к привычным лично вам ментальным моделям. В которых у вас большой опыт, где вы знаете все типичные грабли и способы их обойти. А другой разработчик посмотрит на ваш код и скажет: это никуда не годится, нужно всё переписать (под свою собственную, привычную ему, ментальную модель).
А как насчёт ProductRepo(sitory)?
я не сталкивался с понятием репозитория в дизайне, может, это чисто вебовская штука, остальным понятная. бывают же там всякие датасорсы, например, viewmodel или dataprovider. это все как по мне исключительно вебовские велосипеды. если они понятны веб-программистам, почему бы и не использовать.
под «вебом» я имею в виду задачу, когда у нас есть база, к ней обращаются пользователи, которым нужно показать на экран или еще куда какое-то подмножество этой базы и дать потыкать по кнопочкам
Это Repository pattern. Веб вообще отношения к нему не имеет. Веб — это лишь способ отображения результата. Чисто вебовское это HTML, JS, CSS, и OSI.
под «вебом» я имею в виду задачу, когда у нас есть база, к ней обращаются пользователи, которым нужно показать на экран или еще куда какое-то подмножество этой базы и дать потыкать по кнопочкам

Ну это очень поверхностное представление о вебе. Никто в здравом уме не даст пользователям прямой доступ к базе. И мало кто из пользователей захочет иметь дело с чистым представлением даннах в этой базе. И тогда возникает потребность в логике (особенно когда надо ещё потыкать по кнопочкам), которая с вебом никак не связана.
я не сталкивался с понятием репозитория в дизайне

Ээээ. Вы не слышали про паттерн Repository? Не читали Фаулера и/или Эванса?


бывают же там всякие датасорсы, например, viewmodel или dataprovider. это все как по мне исключительно вебовские велосипеды

Совсем не только вебовские.


Но подождите...


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

… а, так вы под "вебом" понимаете не то, что "обычные люди" — приложение сделанное с помощью веб-технологий, — а что-то свое. Под ваше определение, скажем, попадают все учетные системы. Я бы даже сказал, что весь энтерпрайз туда попадает, чего уж.

И что самое забавное, под него не попадают чисто вебовские лэндинги)
А, кхм, ничего что в такой классификации вы в «веб» скопом записали весь десктоп с сохраняемым состоянием?
Любая игра с save/load имеет «базу» сейвов, а дальше
к ней обращаются пользователи, которым нужно показать на экран или еще куда какое-то подмножество этой базы и дать потыкать по кнопочкам"
.

А с какой-то точки зрения, вообще любое приложение является базой «ресурсов», и далее по цитате выше.
игра без сейва это все равно игра. хабр без базы статей, юзеров и комментов никому не нужен. всегда есть что-то центральное, вокруг чего все вертится, а остальное делается по остаточному принципу
У меня есть ощущение, что автор познал синтаксис языка поддерживающего парадигму ООП, но не умеет программировать в ООП парадигме.
Sign up to leave a comment.

Articles