Принципы - не субъективная вещь. SOLID объективен, и каждая буква в нем влияет непосредственно на вполне объективные метрики вашего кода.
В некоторых случаях можно отступать от того или иного принципа при разработке. Это можно делать по той или иной причине. Например dry можно пожертвовать для оптимизации, избавившись от абстракции. Или же на каком-то этапе рефакторинга, где есть дивергентный и конвергентный шаги при переходе к другому виду абстракции. Осознанно нарушить определенный принцип - совершенно не то же самое, что махнуть на принцип рукой, потому что тупо не понимаешь, что ты делаешь.
Эти принципы сформулированы так, что ваш код либо следует им, либо нет, и делая так или иначе вы придаете совершенно определенные свойства вашему коду. Это напрямую отражается на простоте и поддерживаемости кода, на объеме исполняемого кода, на параметрах производительности, модульности и возможности переиспользования. Вы не можете просто сказать - мой код вне этих категорий.
Есть люди, которые выше принципов - та же Барбара Лискова, которая впервые сформулировала LSP, названый ее именем, но даже эти люди не могут отменять принципы, хотя и могут сформулировать те же самые принципы в другой терминологии, так же как механика есть ньютоновская, а есть релятивистская, но там одни формулы не отрицают другие, а уточняют.
Хорошо подумайте, вы уже на том уровне понимания, чтобы закрывать законы и открывать новые?
Автор статьи - явно нет. Не убедил. Рассуждения абсолютно не логичные, строящиеся на неверных предпосылках. Довод типа показал двум программистам, и они нашли разные нарушения принципа srp - никак не отрицает наличия принципа. Вполне очевидно, что нарушение принципа единственной ответственности вводит как минимум две ответственности, и следовательно, двое всегда могут указать и то и другое в качестве нарушения - кто что выберет.
Точно такого же качества вся логика в этой статье - неверная предпосылка - неверный вывод - подтверждаем доводы, требуемые автору.
Мне этот пост интересен, потому что рецепт это метафора, которую я очень люблю приводить в качестве объяснения принципа работы процессора и стека новичкам в программировании.
Повар - процессор. Разделочная доска - регистры процессора. Рецепт - программа... ну и в таком духе.
И вот к сожалению декларативный стиль программы тут совсем не катит. Ну или по крайней мере - тут не хватает концепции хронометрирования, и нужен компилятор в уже нормальный рецепт, который может исполнить процессор (повар).
В оригинальном рецепте, который вы приводите, есть "Пока вода греется", "Охладите овощи". Если вы думаете, что достаточно просто овощи в любой момент на любое время снять с огня - ошибаетесь.
Винегрет это не бог весть что, но представьте себе хотя бы овощи аль денте или стейк, где дорога каждая секунда, я уже не говорю о чем-то более сложном. Вы пассируете там что-то со специями 30 секунд, а потом засыпаете рис (который в этот момент как раз дошел до кондиции) и тут вы понимаете, что рис вам еще предстоит только начать варить, вариться он будет 6 минут, и к тому времени овощи в пассировке превратятся в кашу (они горячие, и процесс готовки не останавливается с выключением огня - нужно очень быстро все охладить), и чтобы этого не произошло вам нужно выкинуть все в помойку, разобрать ваш декларативный рецепт, прохронометрировать его, превратить в императивный, и тогда уже приступать заново, чтобы все секунда в секунду сварилось и пассировалось, прежде чем охладить овощи...
Человек до мозга костей императивен, и ему как раз очень удобно получать пошаговые инструкции, именно в таком виде, в котором, обычно, публикуют рецепты.
Кстати, если вы решились готовить по рецепту из интернета, потрудитесь подготовиться как следует, проанализировать все фазы готовки, чтобы для вас посреди рецепта не стало неожиданностью, что вам не хватает ковша или сковородки. Чтобы получилось вкусно, нужно досконально следовать рецепту с секундомером наготове, со всеми нужными приборами, конечно, если только вы не гений кухни, но тогда вам не нужен рецепт.
Все это наводит на мысль о том, что нужно анализировать предметную область вместе с экспертами, и у них не случайно свой DSL.
Да, совершенно верно, синхронные приложения так же имеют ряд проблем.
Пул потоков с точки зрения Concurrency играет еще одну злую шутку с приложением.
Поначалу он ограничивает конкурентность, но при накоплении запросов на обработку, начинает расти по «умному» алгоритму, там даже применяется примитивный Machine Learning.
Это значит, что пул сначала защищает приложение, отчасти выполняя роль Bulkhead, но через некоторое время эта защита снимается, и это никак нельзя проконтролировать, пул разрастается непомерно. Например, за 10 минут он может вырасти до 1200 threads. Кроме проблемы Concurrency, это приводит к проблеме см. предыдущую статью День, когда Dodo IS остановилась. Синхронный сценарий
Действительно, можно запутаться, если смешивать эти термины, именно поэтому их и предлагается четко разделять. В своем докладе Роб Пайк упоминает о том, что во вселенной параллельно крутится каждый атом, и можно долго рассуждать о границах параллелизма. На практике вполне достаточно осознать, что параллелизм вычисления в современных компьютерах (не считая кубитные) определяется электрическим контуром, образуемым транзисторами центрального процессора, которые образуют одно единственное логическое состояние за один такт процессора. Все остальное — конкурентные модели, накрученные поверх.
Параллели (простите за каламбур) из других областей знания не особо полезны, я предлагаю ограничиться теорией массового обслуживания, и тут пример с маршруткой в тему.
Асинхронный таргет NLog не означает одновременной попытки записывать что-либо в файл, да это и невозможно, файл здесь — последовательное устройство. То, что в NLog назывется асинхронной записью, на самом деле просто очередь, которая сбрасывается в файл через временные интервалы. Поэтому порядок сохраняется. Сами логи не нужно ускорять, и keepFileOpen ничего не прибавляет, потому что логи сбрасываются раз в несколько секунд. Скорость асинхронного лога становится в десятки раз больше, потому что на скорость в основном влияет не скорость записи на диск, а latency доступа к диску, то есть все упирается в количество обращений к диску.
Конечно мы ждем улучшений когда привносим async, но конечный результат нужно тестировать, чтобы ответить на вопрос об «ускорении». Первый же, и самый очевидный результат, который можно предсказать без всякого тестирования, это то, что TPL привносит свой overhead, и не стоит его игнорировать.
В случае с NLog — у него синхронный интерфейс, поэтому thread, выполняющий логирование будет ждать завершения метода, например Logger.Info, и проблема будет общей как для блокирующего кода, так и async/await. Конфигурация асинхронного логгера будет означать, что метод не будет ожидать записи в файл, а просто поставит сообщение в очередь. Это решает проблему и для блокирующего кода, и async/await. Пропускная способность логгера с такой конфигурацией возрастает в десятки раз.
Круто! Хотелось бы иметь возможность создавать симулятор распределенной системы не в коде, а визуально. Есть такие планы?
Так это чтобы показать, как он должен выглядеть, потому что такое в gif сделать нельзя из за кривой реализации.
Станиславский прям)
Принципы - не субъективная вещь. SOLID объективен, и каждая буква в нем влияет непосредственно на вполне объективные метрики вашего кода.
В некоторых случаях можно отступать от того или иного принципа при разработке. Это можно делать по той или иной причине. Например dry можно пожертвовать для оптимизации, избавившись от абстракции. Или же на каком-то этапе рефакторинга, где есть дивергентный и конвергентный шаги при переходе к другому виду абстракции. Осознанно нарушить определенный принцип - совершенно не то же самое, что махнуть на принцип рукой, потому что тупо не понимаешь, что ты делаешь.
Эти принципы сформулированы так, что ваш код либо следует им, либо нет, и делая так или иначе вы придаете совершенно определенные свойства вашему коду. Это напрямую отражается на простоте и поддерживаемости кода, на объеме исполняемого кода, на параметрах производительности, модульности и возможности переиспользования. Вы не можете просто сказать - мой код вне этих категорий.
Есть люди, которые выше принципов - та же Барбара Лискова, которая впервые сформулировала LSP, названый ее именем, но даже эти люди не могут отменять принципы, хотя и могут сформулировать те же самые принципы в другой терминологии, так же как механика есть ньютоновская, а есть релятивистская, но там одни формулы не отрицают другие, а уточняют.
Хорошо подумайте, вы уже на том уровне понимания, чтобы закрывать законы и открывать новые?
Автор статьи - явно нет. Не убедил. Рассуждения абсолютно не логичные, строящиеся на неверных предпосылках. Довод типа показал двум программистам, и они нашли разные нарушения принципа srp - никак не отрицает наличия принципа. Вполне очевидно, что нарушение принципа единственной ответственности вводит как минимум две ответственности, и следовательно, двое всегда могут указать и то и другое в качестве нарушения - кто что выберет.
Точно такого же качества вся логика в этой статье - неверная предпосылка - неверный вывод - подтверждаем доводы, требуемые автору.
Мне этот пост интересен, потому что рецепт это метафора, которую я очень люблю приводить в качестве объяснения принципа работы процессора и стека новичкам в программировании.
Повар - процессор. Разделочная доска - регистры процессора. Рецепт - программа... ну и в таком духе.
И вот к сожалению декларативный стиль программы тут совсем не катит. Ну или по крайней мере - тут не хватает концепции хронометрирования, и нужен компилятор в уже нормальный рецепт, который может исполнить процессор (повар).
В оригинальном рецепте, который вы приводите, есть "Пока вода греется", "Охладите овощи". Если вы думаете, что достаточно просто овощи в любой момент на любое время снять с огня - ошибаетесь.
Винегрет это не бог весть что, но представьте себе хотя бы овощи аль денте или стейк, где дорога каждая секунда, я уже не говорю о чем-то более сложном. Вы пассируете там что-то со специями 30 секунд, а потом засыпаете рис (который в этот момент как раз дошел до кондиции) и тут вы понимаете, что рис вам еще предстоит только начать варить, вариться он будет 6 минут, и к тому времени овощи в пассировке превратятся в кашу (они горячие, и процесс готовки не останавливается с выключением огня - нужно очень быстро все охладить), и чтобы этого не произошло вам нужно выкинуть все в помойку, разобрать ваш декларативный рецепт, прохронометрировать его, превратить в императивный, и тогда уже приступать заново, чтобы все секунда в секунду сварилось и пассировалось, прежде чем охладить овощи...
Человек до мозга костей императивен, и ему как раз очень удобно получать пошаговые инструкции, именно в таком виде, в котором, обычно, публикуют рецепты.
Кстати, если вы решились готовить по рецепту из интернета, потрудитесь подготовиться как следует, проанализировать все фазы готовки, чтобы для вас посреди рецепта не стало неожиданностью, что вам не хватает ковша или сковородки. Чтобы получилось вкусно, нужно досконально следовать рецепту с секундомером наготове, со всеми нужными приборами, конечно, если только вы не гений кухни, но тогда вам не нужен рецепт.
Все это наводит на мысль о том, что нужно анализировать предметную область вместе с экспертами, и у них не случайно свой DSL.
Удачной готовки!
Пул потоков с точки зрения Concurrency играет еще одну злую шутку с приложением.
Поначалу он ограничивает конкурентность, но при накоплении запросов на обработку, начинает расти по «умному» алгоритму, там даже применяется примитивный Machine Learning.
Это значит, что пул сначала защищает приложение, отчасти выполняя роль Bulkhead, но через некоторое время эта защита снимается, и это никак нельзя проконтролировать, пул разрастается непомерно. Например, за 10 минут он может вырасти до 1200 threads. Кроме проблемы Concurrency, это приводит к проблеме см. предыдущую статью День, когда Dodo IS остановилась. Синхронный сценарий
Параллели (простите за каламбур) из других областей знания не особо полезны, я предлагаю ограничиться теорией массового обслуживания, и тут пример с маршруткой в тему.