Это просто каждому понятный пример, не требующий погружения в конкретную предметную область. Кроме того была и побочная цель — заронить идею, что многие привычные функции, которыми мы не задумываясь пользуемся в повседневности, на самом деле могут реализовывать тот или иной принцип или паттерн. Поэтому, это хороший знак, что читая статью, в голове что-то щелкнуло, и вы узнали функцию. В этом и была цель использования именно ее — дать читающему ощутить насколько вездесущ IoC, при том что обычно мы можем не обращать на него внимания.
Да, это так. Но есть решение с помощью JSDoc:
/** @type {import(’./services/Log’)} */
this.log = container.cradle.log;
Или при передаче в конструктор:/** @param {{ express: import(’express’).Express }} express */
constructor({ express }) {}
Кроме того в VSCode есть возможность ввести строгие проверки типов в стиле TS с помощью директивы @ts-check, например, в начале файла:// @ts-checkИ обратная ей директива @ts-nocheck.
Я так не думаю. Это не должно быть попыткой сделать исключение для айтишников, потому что иначе получим только больше ненависти в нашу сторону.
Достаточно, если ЗСУ будут пополняться ровно так, как и сообщал Резников (наш минобороны) во вчерашнем интервью. Т.е. в порядке военного опыта, а не грести всех переселенцев в ЗУ беспорядочно, включая и тех, кто по состоянию здоровья даже не служил и вряд ли знает с какой стороны держаться за автомат, не говоря уж об эффективности таких «бойцов». Особенно на фоне толп желающих поступить в ТРО.
Думаю, нам, нашей стране и самим ЗСУ нужен именно порядок в этом вопросе, а не особый статус айтишников, что выглядело бы, мягко говоря, дискриминационно.
Именно в такой реализации придется своими руками наследовать класс логгера всякий раз, когда понадобится скоуп.
Можно ее улучшить и вынести наследование в метод scoped. Но тогда всякий раз когда вызывается метод scoped() будет создаваться новый инстанс логгера, что приведет к ошибке, когда он попытается открыть уже открытый другим логгером файл.
Поэтому это должен быть не просто потомок, а имплементация паттерна прокси. Тогда всё будет работать как задумывалось. Но паттерн прокси наследует интерфейс, а не реализацию (в случае JS, где интерфейсов нет, это просто анонимный класс-обертка), поэтому нужно будет имплементировать все методы вывода лога таким образом, чтобы они вызывали нужные методы оборачиваемого класса. В итоге, строк кода это займет несколько больше.
Ну, лямбды есть в плюсах. А функции высшего порядка для работы с контейнерами реализованы в библиотеках стл и бусте. Я это упоминаю не к тому, что плюсами можно заменить питон, просто самой функциональной парадигме уже почти полвека давности и за это время многие нефункциональные языки давно адаптировали большинство тех фич, которые считаются преимуществом функционального подхода.
А что делать, если у вашего компонента со стороны заказчика три разные продуктовые команды и каждая пользуется немного различной терминологией описывая бизнес логику? Пойдете к СЕО заказчика и будете требовать навести порядок в бизнес-процессах?)
Речь совсем не о терминологии. Или вы о том неправильно переведенном слове в моем примере? Про то что «кинокартина» != «киносеанс»? Но там это далеко не самое важное.
На это я обратил внимание вообще только потому что бросилось в глаза, ведь обычно подобные ошибки — признак более комплексной проблемы. Часто именно плохое знание английского языка и не позволяет автору называть методы ёмко, как и писать вменяемую документацию. А вовсе не какой-то «особый грязный уличный стиль» программирования =)
расшибания лбов перед иконой мартина да, популярное занятие.
Это вообще повсеместная беда, когда на какую-то генерализацию одни начинают молиться и трактовать неукоснительно и непременно в буквальном смысле, словно святое писание. А другие, посмотрев на первых, решают, что вся парадигма — туфта.
Я ещё в самом начале утверждал, что не следует самодокументирование кода отождествлять с требованием полного отсутствия комментариев.
Комментарии должны описывать неочевидные, сложные места в коде или вносить, например, пояснения о причине какого-нибудь странного решения.
Но комментариями не снабдишь вызов каждой функции. Функции должны иметь нормальные, понятные не только автору в момент написания имена. Также как и переменные. И классы. Конечно, бывают исключения, когда хорошее имя никак не придумать. Но это именно исключение, т.е. встречается редко. Но бывает. И даже когда сталкиваешься с ним, стоит ещё раз подумать, а нельзя ли переписать код каким-то таким образом, чтобы подобная ситуация исключалась. Потому что это признак возможной архитектурной ошибки. И опять же. Контекст. Если такая «не ошибка» случается в одном месте из ста, переписывать придется слишком много, а сама она сокрыта где-то в редкоиспользуемой части интерфейса — то и ладно, это того не стоит. Но когда чуть ли каждая функция называется черте-как, то это совсем другое дело.
Или, например, не следует каждый блок, осуществляющий некое отдельное действие в коде функции, пытаться обернуть в собственную функцию, как это делается в примерах Мартина. Это просто пример, а не непреложное правило. Маркер, который оповещает о такой возможности. Что о ней стоит задуматься. Возможно, она имеет смысл, а, может, и нет. Потому как куча приватных функций с длинными дурацкими именами определенно не сделают код читабельнее. А ведь смысл как раз в этом.
Каждое правило, парадигму, паттерн или конвенцию нужно применять в разумных пределах и осмысленно.
Я бы не стал называть деятельность, которая отнимает менее 5% времени, но в дальнейшем даёт профит в 100% и выше, именно перфекционизмом.
Когда добавление простенькой фичи отнимает в несколько раз больше времени, чем она того стоит, из-за высокой связанности вермишелеподобного кода, обычно всё начинается с простого — с неочевидных имен, пропущенного рефакторинга, непродуманной архитектуры.
Потом кто-то вмешивается со своим таском, совершенно ничего не понимает в коде, и тоже решает по-быстрому тыкнуть костыль. Запутанность раз за разом множится. И в итоге можно прийти к ситуации, когда время на поиск места, куда бы ткнуть новый костыль в сумме с отладкой получившегося добра, превышает время непосредственно написания кода в несколько раз. Ну и стоила того эта экономия в самом начале?
Обо всем этом когда-то тоже говорил Роберт, и, на мой взгляд, это не перфекционизм, а профессионализм.
Менеджер никогда не поймет, что воткнутый костыль сегодня = сниженная скорость разработки завтра. Что скорость работы с кодом обратнопропорциональна количеству костылей в нем. А если и поймет, то это, как верно заметили, будет не его проблема.
Поэтому, лично на мой взгляд, это полностью ответственность программиста — писать код качественно с самого старта проекта.
И поторапливание сверху — такое себе оправдание. Инженер оперирует непреложными фактами, физическими законами, если хотите. Если менеджер спрашивает «закипел ли там чайник?» и «можем ли мы закипеть при 80 градусах?», единственный верный ответ — нет. Потому что только инженер знает этот факт достоверно. Менеджер же сомневается, и если слышит нечто неуверенно-философское на тему «ну мы могли бы, но...», то слышит только часть «могли бы» =)
но даже такое, идеальное, ничего не скажет — почему эти ЧТО и КАК такие, а не другие.
программирование не математика ж, можно было и по другому сделать
Под КАК я имел в виду не детали реализации, а подробности самого действия. В приводимом примере это название метода, просто содержащее глагол «обновить». В зависимости от контекста, какому-нибудь классу может быть достаточно и метода с названием «update()», но только если это не приводит к путанице и кристально ясно что и каким образом этот метод делает. Например, метод update() у модели ORM. Из того, что существует команда SQL с таким же именем, то можно свободно допускать, что одноименный метод будет выполнять именно её, а не, скажем, обновлять свойства объекта в памяти. Но в конкретном случае примера совершенно не ясно КАК метод будет обновлять список: что-то пересчитывать, изменять сам список, писать из памяти — в базу, из базы — в память, из сервиса — в память и прочие комбинации.
Автор кода не в курсе, какие куски проекта не будет знать n-й читатель кода. Терминология-то развивается, а на больших проектах фиг новичок узнает терминологию, используемую разработчиками разных модулей.
Помните шутку о том, что качество кода определяется по частоте восклицаний WTF при ревью? Так вот в жизни код тем читабельнее, чем реже ревьюверу приходится открывать доки или искать по исходникам вычитывая комментарии. Это не булево значение, четко разделяющее «читабельный код» и «резко нет».
От терминологии предметной области, конечно, не уйдешь. Но речь немного о другом, о случаях когда классы называют AppInit вместо AppStartupConfigurator или методы вида updateRequests() вместо deleteTimedOutRequests(). Такие вещи находятся полностью во власти программиста и их нельзя оправдать «терминологией проекта».
Вообще, если честно, меня от одного этого словосочетания бросает в холод. Потому что зачастую оно мало связано с предметной областью, а служит эдаким фиговым листочком на непродуманном коде. А это в свою очередь маркер того, что в компании никто не заботится о будущем, и задача каждого — по-быстрому воткнуть костыль сегодня, а завтра — хоть трава не расти.
про самодокументований код топить здається Мартін. і, насправді, я б в рота йому не дивився. і розумів так: чим менше код потребує коментування — тим він кращий
Именно это, насколько я понимаю, и имеет в виду Мартин.
Как часто вы встречали названия методов вида «updateScenes()»? Когда вы смотрите на вызов этого вот в каком-то месте чужого кода и совершенно не понимаете, что имел в виду автор.
Какие такие «scenes»? Что значит «update»? Потом разбираешься в коде метода, и оказывается, что «scenes» — это автор так криво перевел слово «киносеанс». Но всё ещё не понятно что значит «update». Загрузить ИЗ базы? Положить В базу? Синхронизировать с удаленным АПИ? А ведь такая возможность тоже имеется. И если так, то в какую сторону. Или, быть может, модели сеансов нуждаются в пересмотре, может там какие-то вычисляемые поля обновляются. Или там что-то происходит с самим списком этих моделей? Пока не прочитаешь код — не поймешь.
Понятно, автор этого метода сократил, чтобы не писать километровые имена. Но Мартин как раз говорит о том, что так делать не нужно. Название метода, в идеале, должно говорить о том ЧТО он делает и давать представление о том КАК он это делает, хотя бы приблизительно. Как по мне, в этом вся суть.
Вот это именно в точку, что как на С++. Потом ревьювишь код на каком-нибудь пхп или джаваскрипте и с удивлением обнаруживаешь там повсюду венгерскую нотацию =)
Первый вопрос: почему не вынести чувствительные сеттинги отдельно? Аппсеттингс файл огромный был.
По идее, если никто в проекте не начудил, и не разместил в файле настроек то, что в идеале должно быть константами, то его содержимое, разделяй его или нет, все равно будет меняться от инстанса к инстансу. А значит, оба файла конфигов в идеале не должны попадать в репозиторий. Все же, на вашем месте я бы предпочел какой-нибудь шелл-скрипт, выполняющийся на стадии cd и заполняющий сеттинги инстанса по шаблону.
Почему не зашифровать их и не расшифровывать on the fly?
Потому что симметричный ключ не сложно выковырять, имея весь исходный код на руках.
Я сделал то о чем вы говорите, причем в явном виде
Ну, не совсем. Я ведь писал о «поговорить», а не делать за Александра его работу. А перед этим узнать мнение коллег. Как-то ведь ваш начальник узнал о такой мелочи? Притом, судя по всему, в негативном русле. А значит, кому-то ваши действия не пришлись по душе =)
Что лучше: иметь в установочном гайде пункт «После скачки солюшена попроси у тимлида копию appSettings.development.json и добавь в солюшен» или просто сделать так, чтобы этот файл изначально был частью солюшена?
Со стороны выглядит так, словно в этом файлике конфигов хранятся чувствительные данные, вроде ключей, паролей, адресов и прочего. Отправлять его в репозиторий — очень плохое решение как с точки зрения безопасности, так и удобства пользования гитом, и, вероятно, поэтому в гит-проекте он просто заигнорен. Получается, Вашей задачей было в первом пункте гайда по развёртке просто описать процесс создания такого файлика с нуля. Хотя я бы ещё подумал о возможности написания шелл-скрипта для его генерации (если это возможно, конечно). В общем, из того что написано в статье, все выглядит как обычная рутина. Странно, что подобное могло создать сложность для лида.
кофе
Тут тоже странно. Почему тимлид занимается вопросом выбора поставщика кофе в офис, притом, судя по всему, ещё и через голову того, кто этим занимался раньше, мне решительно непонятно. Но если так сильно захотелось «поменять марку кофе», то почему бы сначала не узнать мнение остальных коллег (вдруг, именно это кофе тут в основном предпочитают — кто знает), а потом найти человека, который этим занимается, и поговорить с ним?
Такая же проблема и у меня. Вы заполняли ту заяву, что по форме 5ДР?