Я прочитал книгу под названием « Чистый код » Роберта Мартина. В этой книге я видел много методов для очистки кода, таких как написание небольших функций, тщательный выбор имен и т. Д. Это, безусловно, самая интересная книга о чистом коде, которую я читал. Однако сегодня моему боссу не понравилось, как я написал код после прочтения этой книги.
Его аргументы были
- Написание маленьких функций - это боль, потому что это заставляет вас переходить к каждой маленькой функции, чтобы посмотреть, что делает код.
- Поместите все в основной большой цикл, даже если основной цикл содержит более 300 строк, его читать быстрее.
- Пишите только небольшие функции, если вам нужно дублировать код.
- Не пишите функцию с именем комментария, поместите сложную строку кода (3-4 строки) с комментарием выше; Точно так же вы можете изменить неисправный код напрямую
Это против всего, что я прочитал. Как вы обычно пишете код? Один главный большой цикл, нет маленьких функций?
Язык, который я использую, в основном Javascript. У меня действительно есть трудности с чтением, так как я удалил все свои маленькие четко названные функции и поместил все в большой цикл. Впрочем, так нравится моему боссу.
Один пример был:
// The way I would write it
if (isApplicationInProduction(headers)) {
phoneNumber = headers.resourceId;
} else {
phoneNumber = DEV_PHONE_NUMBER;
}
function isApplicationInProduction(headers) {
return _.has(headers, 'resourceId');
}
// The way he would write it
// Take the right resourceId if application is in production
phoneNumber = headers.resourceId ? headers.resourceId : DEV_PHONE_NUMBER;
Например, в книге, которую я читал, комментарии рассматриваются как неспособность написать чистый код, потому что они устарели, если вы пишете небольшие функции и часто приводят к необновленным комментариям (вы изменяете свой код, а не комментарий). Однако, что я делаю, это удаляю комментарий и пишу функцию с именем комментария.
Ну, я хотел бы получить совет, какой способ / практика лучше написать чистый код?
источник
isApplicationInProduction()
функции! У вас должны быть тесты, и тесты бесполезны, если ваш код ведет себя иначе, чем когда он работает. Это как намеренно иметь непроверенный / непокрытый код в производстве: это не имеет смысла.Ответы:
Взять примеры кода в первую очередь. Вы поддерживаете:
И ваш босс напишет это так:
На мой взгляд, у обоих есть проблемы. Когда я читал ваш код, я сразу подумал: «Вы можете заменить
if
это троичным выражением». Затем я прочитал код вашего босса и подумал: «Почему он заменил вашу функцию комментарием?».Я хотел бы предложить оптимальный код между двумя:
Это дает вам лучшее из обоих миров: упрощенное тестовое выражение и комментарий заменяются тестируемым кодом.
Что касается взглядов вашего босса на дизайн кода, хотя:
Если функция имеет правильное имя, это не так.
isApplicationInProduction
самоочевидно, и нет необходимости изучать код, чтобы увидеть, что он делает. На самом деле верно обратное: изучение кода показывает меньше намерений, чем имя функции (именно поэтому ваш начальник должен прибегать к комментариям).Сканирование может быть быстрее, но, чтобы действительно «прочитать» код, вам необходимо эффективно выполнять его в своей голове. Это легко с небольшими функциями и очень, очень сложно с методами длиной в 100 строк.
Я не согласен. Как показывает ваш пример кода, небольшие, хорошо названные функции улучшают читабельность кода и должны использоваться всякий раз, когда, например, вас не интересует «как», только «что» в части функциональности.
Я действительно не могу понять причину этого, предполагая, что это действительно серьезно. Это та вещь, которую я ожидал бы увидеть в пародии на твиттер-аккаунт Эксперта для начинающих . Комментарии имеют фундаментальный недостаток: они не компилируются / интерпретируются и поэтому не могут быть проверены модулем. Код изменяется, и комментарий остается один, и вы в конечном итоге не знаете, что правильно.
Написание самодокументируемого кода сложно, и иногда необходимы дополнительные документы (даже в форме комментариев). Но мнение «дяди Боба» о том, что комментарии являются ошибкой кодирования, слишком часто встречается.
Попросите вашего босса прочитать книгу «Чистый код» и постарайтесь не делать ваш код менее читабельным, просто чтобы удовлетворить его. В конечном счете, однако, если вы не можете убедить его измениться, вы должны либо встать в очередь, либо найти нового босса, который сможет лучше кодировать.
источник
Есть и другие проблемы
Ни один из этих кодов не годится, потому что оба в основном раздувают код с помощью отладочного теста . Что делать, если вы хотите проверить больше вещей по любой причине?
или же
Хотите добавить еще больше веток?
Существенной проблемой является то, что вы в основном дублируете часть своего кода, и, таким образом, вы фактически не тестируете реальный код. Вы пишете код отладки для проверки кода отладки, но не рабочий код. Это как частичное создание параллельной кодовой базы.
Вы спорите со своим боссом о том, как писать хитрый код более умно. Вместо этого вы должны исправить внутреннюю проблему самого кода.
Внедрение зависимости
Вот как должен выглядеть ваш код:
Здесь нет разветвлений, потому что логика здесь не имеет разветвлений. Программа должна вытащить номер телефона из шапки. Период.
Если вы хотите получить
DEV_PHONE_NUMBER_FROM_OTHER_COUNTRY
результат, вы должны поместить его вheaders.resourceId
. Один из способов сделать это - просто внедрить другойheaders
объект для тестовых случаев (извините, если это неправильный код, мои навыки JavaScript немного устарели):Предполагая, что
headers
это часть ответа, который вы получаете от сервера: в идеале у вас есть целый тестовый сервер, который предоставляетheaders
различные виды для тестирования. Таким образом, вы тестируете реальный производственный код как есть, а не какой-то наполовину дублированный код, который может работать, а может и не работать, как рабочий код.источник
На это нет «правильного» или «неправильного» ответа. Тем не менее, я предложу свое мнение, основанное на 36-летнем профессиональном опыте проектирования и разработки программных систем ...
Говоря непосредственно с примером, который вы предоставили ... Разумное
isApplicationInProduction()
(э) решение - это сделать самому. Сегодня этот тест является просто проверкой «заголовков» и может быть обработан в тернарном (?:
) операторе. Завтра тест может быть гораздо более сложным. Кроме того, «headers.resourceId» не имеет четкого отношения к приложению «в рабочем состоянии»; Я бы сказал, что тест на такой статус должен быть отделен от базовых данных; подпрограмма сделает это, а троичная - нет. Кроме того, полезный комментарий объясняет, почему resourceId является тестом для «в производстве».Будьте осторожны, чтобы не переборщить с «маленькими четко названными функциями». Подпрограмма должна заключать в себе идею больше, чем просто код. Я поддерживаю предложение Амона
phoneNumber = getPhoneNumber(headers)
и добавляю, чтоgetPhoneNumber()
следует выполнить тест «производственный статус» сisApplicationInProduction()
источник
Код должен быть максимально простым. Ошибки любят скрывать между сложностями, потому что их трудно обнаружить там. Так что же делает код простым?
Небольшие единицы (файлы, функции, классы) - хорошая идея . Маленькие юниты легко понять, потому что вы должны понимать меньше вещей одновременно. Нормальные люди могут жонглировать только ~ 7 понятиями одновременно. Но размер измеряется не только в строках кода . Я могу написать как можно меньше кода, «играя в гольф» (выбирая короткие имена переменных, выбирая «умные» ярлыки, разбивая как можно больше кода на одной строке), но конечный результат не прост. Попытка понять такой код больше похожа на реверс-инжиниринг, чем на чтение.
Одним из способов сокращения функции является извлечение различных вспомогательных функций. Это может быть хорошей идеей, когда она извлекает отдельную часть сложности . В отдельности этой частью сложности намного проще управлять (и тестировать!), Чем когда она встроена в не связанную проблему.
Но у каждого вызова функции есть когнитивные издержки : мне нужно не просто понимать код в моем текущем фрагменте кода, я также должен понимать, как он взаимодействует с внешним кодом . Я думаю, будет справедливо сказать, что функция, которую вы извлекли, вносит в нее больше сложности, чем извлекает . Это то, что ваш начальник имел в виду под « маленькими функциями [это] боль», потому что это заставляет вас переходить к каждой маленькой функции, чтобы посмотреть, что делает код. »
Иногда длинные скучные функции могут быть невероятно просты для понимания, даже если они состоят из сотен строк. Это обычно происходит в коде инициализации и конфигурации, например, при создании графического интерфейса пользователя без редактора с перетаскиванием. Там нет отдельной части сложности, которую вы могли бы разумно извлечь. Но если форматирование читаемо и есть некоторые комментарии, действительно нетрудно проследить, что происходит.
Есть много других метрик сложности: количество переменных в области должно быть как можно меньше. Это не значит, что мы должны избегать переменных. Это означает, что мы должны ограничить каждую переменную до минимально возможной области, где это необходимо. Переменные также становятся проще, если мы никогда не изменим значение, которое они содержат.
Очень важной метрикой является цикломатическая сложность (сложность МакКейба). Он измеряет количество независимых путей через кусок кода. Это число растет экспоненциально с каждым условным условием. Каждое условие или цикл удваивает количество путей. Есть основания полагать, что оценка более 10 баллов слишком сложна. Это означает, что очень длинная функция, которая может иметь оценку 5, возможно, лучше, чем очень короткая и плотная функция с оценкой 25. Мы можем уменьшить сложность, выделив поток управления в отдельные функции.
Ваше условное выражение является примером части сложности, которую можно извлечь полностью:
Это все еще очень полезно. Я не уверен, что это существенно уменьшает сложность, потому что это условное не очень условно . В производстве он всегда будет идти по одному пути.
Сложность никогда не исчезнет. Это можно только перемешать. Много ли простых вещей проще, чем несколько больших? Это очень сильно зависит от обстоятельств. Обычно есть какая-то комбинация, которая кажется правильной. Поиск такого компромисса между различными факторами сложности требует интуиции и опыта, а также немного удачи.
Знание того, как писать очень маленькие функции и очень простые функции, является полезным навыком, потому что вы не можете сделать выбор, не зная альтернатив. Слепое следование правилам или лучшим практикам, не задумываясь о том, как они применимы к текущей ситуации, в лучшем случае приводит к средним результатам, в худшем - к культу грузового культа .
Вот где я не согласен с твоим боссом. Его аргументы не являются недействительными, но и книга о чистом кодексе неверна. Вероятно, лучше следовать указаниям вашего босса, но сам факт того, что вы думаете об этих проблемах, пытаетесь найти лучший путь, очень перспективен. По мере накопления опыта вам будет легче найти хороший факторинг для вашего кода.
(Примечание: этот ответ частично основан на мыслях из поста в блоге « Разумный код» на The Whiteboard Джимми Хоффа , который дает общее представление о том, что делает код простым.)
источник
Стиль программирования Роберта Мартина поляризован. Вы найдете много программистов, даже опытных, которые находят много оправданий, почему разделение «так много» - это слишком много, и почему сохранение функций чуть больше - это «лучший способ». Однако большинство этих «аргументов» часто являются выражением нежелания менять старые привычки и узнавать что-то новое.
Не слушай их!
Всякий раз, когда вы можете сохранить комментарий путем рефакторинга фрагмента кода в отдельную функцию с выразительным именем, сделайте это - это, скорее всего, улучшит ваш код. Вам не нужно заходить так далеко, как это делает Боб Мартин в своей книге чистых кодов, но подавляющее большинство кода, который я видел в прошлом, вызывал проблемы с обслуживанием, содержал слишком большие функции, а не слишком маленькие. Так что пытайтесь писать меньшие функции с самоописывающимися именами - это то, что вы должны попробовать.
Инструменты автоматического рефакторинга позволяют легко, просто и безопасно извлекать методы. И, пожалуйста, не принимайте всерьез людей, которые рекомендуют писать функции с> 300 строками - такие люди определенно не способны рассказать вам, как вы должны кодировать.
источник
В вашем случае: вы хотите номер телефона. Либо очевидно, как вы получите номер телефона, тогда вы напишите очевидный код. Или не очевидно, как вы получите номер телефона, тогда вы пишете метод для него.
В вашем случае неясно, как получить номер телефона, поэтому вы пишете для него метод. Реализация не очевидна, но именно поэтому вы помещаете его в отдельный метод, поэтому вам приходится иметь дело с ним только один раз. Комментарий был бы полезен, потому что реализация не очевидна.
Метод isApplicationInProduction является совершенно бессмысленным. Вызов его из вашего метода getPhonenumber не делает реализацию более очевидной, а только усложняет выяснение того, что происходит.
Не пишите маленькие функции. Напишите функции, которые имеют четко определенную цель и соответствуют этой четко определенной цели.
PS. Мне не нравится реализация вообще. Предполагается, что отсутствие номера телефона означает, что это версия разработчика. Таким образом, если номер телефона отсутствует в производстве, вы не только не обрабатываете его, но подставляете случайный номер телефона. Представьте, что у вас 10000 клиентов, а у 17 нет номера телефона, и у вас проблемы с производством. Находитесь ли вы в производстве или разработке, следует проверять напрямую, а не из чего-то другого.
источник
Даже игнорируя тот факт, что ни одна из реализаций не настолько хороша, я хотел бы отметить, что это, по сути, вопрос вкуса, по крайней мере, на уровне абстрагирования одноразовых тривиальных функций.
Количество строк не является полезной метрикой в большинстве случаев.
300 (или даже 3000) строк совершенно тривиального чисто последовательного кода (программа установки или что-то в этом роде) редко представляет собой проблему (но может быть лучше автоматически сгенерирован или в виде таблицы данных или чего-то подобного), 100 строк вложенных циклов с множеством сложных Условия выхода и математика, которые вы можете найти в исключении Гаусса или инверсии матриц, могут быть слишком сложными для понимания.
Для меня я не написал бы функцию одноразового использования, если бы объем кода, требуемого для объявления этого, был намного меньше, чем объем кода, формирующего реализацию (если только у меня не было причины, например, сказать, что я хотел бы легко выполнить внедрение ошибок). Один условный редко подходит для этого счета.
Теперь я из небольшого ядра встроенного мира, где мы также должны учитывать такие вещи, как глубина стека и накладные расходы на вызов / возврат (что опять-таки противоречит видам крошечных функций, которые, похоже, здесь отстаиваются), и это может повлиять на мой дизайн. решения, но если бы я увидел эту оригинальную функцию в обзоре кода, он получил бы пламя usenet старого стиля в ответ.
Вкус - это дизайн, которому трудно учить, и он действительно приходит только с опытом, я не уверен, что его можно свести к правилам о длинах функций, и даже цикломатическая сложность имеет свои ограничения в виде метрики (иногда вещи просто сложны, как бы вы их не решали).
Это не означает, что чистый код не обсуждает некоторые хорошие вещи, он это делает, и об этих вещах следует думать, но о локальных обычаях и о том, что делает существующая база кода, следует также придавать вес.
Мне кажется, что этот конкретный пример разбирается в мельчайших деталях, меня больше волновали бы вещи более высокого уровня, поскольку это гораздо важнее для способности легко понимать и отлаживать систему.
источник
Не помещайте все в один большой цикл, но не делайте это слишком часто:
Проблема с большим циклом состоит в том, что очень трудно увидеть его общую структуру, когда он охватывает много экранов. Поэтому старайтесь извлекать большие куски, в идеале куски, на которых лежит одна ответственность и которые можно использовать повторно.
Проблема с крошечной функцией, приведенной выше, заключается в том, что, хотя атомарность и модульность в целом хороши, это может быть слишком далеко. Если вы не собираетесь использовать вышеупомянутую функцию, это снижает читабельность кода и удобство обслуживания. Чтобы углубиться в детали, вы должны перейти к функции, вместо того, чтобы читать подробности внутри строки, и вызов функции занимает чуть меньше места, чем сама деталь.
Очевидно, что необходимо найти баланс между методами, которые делают слишком много, и методами, которые делают слишком мало . Я бы никогда не выделил крошечную функцию, как описано выше, если бы она не собиралась вызываться из более чем одного места, и даже тогда я бы дважды подумал об этом, потому что функция просто не настолько существенна с точки зрения введения новой логики и как такие едва оправдывает свое существование.
источник
Кажется, что вы действительно хотите это:
Это должно быть самоочевидным для любого, кто его читает: установите
phoneNumber
в значение,resourceId
если оно доступно, или по умолчанию,DEV_PHONE_NUMBER
если это не так.Если вы действительно хотите установить эту переменную только в рабочей среде, у вас должен быть какой-то другой, более канонический метод для всего приложения (для которого не требуются параметры), чтобы определить, откуда вы работаете. Чтение заголовков для этой информации не имеет смысла.
источник
Позвольте мне сказать прямо: мне кажется, что ваша среда (язык / фреймворк / дизайн классов и т. Д.) На самом деле не подходит для "чистого" кода. Вы смешиваете все возможные вещи в несколько строк кода, которые не должны быть близко друг к другу. Какое отношение имеет одна функция к знанию, что
resourceId==undef
означает, что вы не работаете, что вы используете телефонный номер по умолчанию в непроизводственных системах, что идентификатор ресурса сохранен в некоторых «заголовках» и т. Д.? Я предполагаюheaders
, что HTTP-заголовки, так что вы даже оставляете решение о том, в какой среде вы находитесь, конечному пользователю?Факторинг отдельных частей этого в функции не поможет вам с этой основной проблемой.
Некоторые ключевые слова для поиска:
Вы можете достичь того, чего хотите (в других контекстах), с нулевыми строками кода, переместив обязанности кода и используя современные фреймворки (которые могут существовать или не существовать для вашей среды / языка программирования).
Из вашего описания («300 строк кода в« основной »функции») даже слово «функция» (вместо метода) заставляет меня предположить, что нет смысла в том, чего вы пытаетесь достичь. В этой среде программирования старой школы (т. Е. Базовое императивное программирование с небольшой структурой, конечно, без значимых классов, без шаблонов структуры классов, таких как MVC или что-то подобное), на самом деле нет особого смысла что- либо делать . Вы никогда не выйдете из отстойника без фундаментальных изменений. По крайней мере, ваш начальник, кажется, позволяет вам создавать функции, чтобы избежать дублирования кода, это хороший первый шаг!
Я знаю как тип кода, так и тип программиста, который вы описываете достаточно хорошо. Честно говоря, если бы это был сотрудник, мой совет был бы другим. Но так как это твой босс, для тебя бесполезно драться из-за этого. Мало того, что ваш босс может отвергнуть вас, но ваши дополнения кода действительно приведут к ухудшению кода, если только вы сделаете «свое дело» частично, а ваш босс (и, возможно, другие люди) продолжат, как и раньше. Это может быть лучше для конечного результата, если вы адаптируетесь к их стилю программирования (конечно, только во время работы над этой конкретной базой кода) и в этом контексте пытаетесь извлечь из этого максимум пользы.
источник
«Чистота» - одна из целей написания кода. Это не единственная цель. Еще одна достойная цель - это колокейство . Говоря неформально, словосочетание означает, что людям, пытающимся понять ваш код, не нужно прыгать повсюду, чтобы увидеть, что вы делаете. Использование хорошо названной функции вместо троичного выражения может показаться хорошим решением, но в зависимости от того, сколько таких функций у вас есть и где они расположены, эта практика может превратиться в неприятность. Я не могу сказать вам, переступили ли вы эту черту, за исключением того, что если люди жалуются, вам следует выслушать, особенно если эти люди имеют право голоса по поводу вашего статуса занятости.
источник
Использование небольших функций, в общем, хорошая практика. Но в идеале я считаю, что введение функции должно либо разделять большие логические блоки, либо уменьшать общий размер кода, высушивая его. Приведенный вами пример делает код длиннее и требует больше времени для чтения разработчиком, в то время как короткая альтернатива не объясняет, что
"resourceId"
значение присутствует только в производстве. Нечто простое, подобное этому, легко забыть и запутаться при попытке работать с ним, особенно если вы все еще плохо знакомы с базой кода.Я не скажу, что вы должны использовать троичный, некоторые люди, с которыми я работал, предпочитают немного дольше
if () {...} else {...}
, это в основном личный выбор. Я предпочитаю «одна строка делает один подход», но я бы в основном придерживался того, что обычно использует кодовая база.При использовании троичного типа, если логическая проверка делает строку слишком длинной или сложной, рассмотрите возможность создания переменной с переменным именем для хранения значения.
Я также хотел бы сказать, что если кодовая база распространяется на 300 строковых функций, то она нуждается в некотором подразделении. Но я бы посоветовал использовать более широкие штрихи.
источник
Пример кода, который вы дали, ваш начальник ПРАВИЛЬНО. В этом случае лучше использовать одну четкую линию.
В целом, разбивание сложной логики на более мелкие части лучше для удобочитаемости, обслуживания кода и возможности того, что подклассы будут вести себя по-разному (хотя бы незначительно).
Не игнорируйте недостатки: накладные расходы на функции, затуманивание (функция не делает того, что подразумевают комментарии и имя функции), сложная логика спагетти, возможность мертвых функций (когда-то они были созданы для цели, которая больше не вызывается).
источник
Я могу представить как минимум два аргумента в пользу длинных функций:
Это означает, что у вас много контекста вокруг каждой строки. Способ формализовать это: нарисовать график потока управления вашего кода. В вершине (~ = линия) между входом и выходом из функции вы знаете все входящие ребра. Чем длиннее функция, тем больше таких вершин.
Множество небольших функций означает, что существует более крупный и сложный граф вызовов. Выберите случайную строку в случайной функции и ответьте на вопрос "в каком контексте (ах) выполняется эта строка?" Это становится тем сложнее, чем крупнее и сложнее граф вызовов, потому что вам нужно смотреть на большее количество вершин в этом графе.
Есть также аргументы против длинных функций - на ум приходит юнит-тестируемость. Используйте t̶h choosinge̶ ̶f othero̶r̶c̶e̶ свой опыт при выборе между одним и другим.
Примечание: я не говорю, что ваш начальник прав, только то, что его точка зрения не может быть полностью лишена ценности.
Я считаю, что хорошим параметром оптимизации является не длина функции. Я думаю, что более полезной для понимания точки зрения является следующее: при прочих равных условиях желательно иметь возможность считывать из кода высокоуровневое описание как бизнес-логики, так и реализации. (Детали реализации низкого уровня всегда можно прочитать, если вы можете найти соответствующий бит кода.)
Комментируя ответ Дэвида Арно :
Название ясно показывает, что означает возвращаемое значение , но ничего не говорит о последствиях выполнения кода (= что делает код ). Имена (только) передают информацию о намерении , код передает информацию о поведении (из чего иногда могут быть выведены части намерения).
Иногда вам нужно одно, иногда другое, поэтому это наблюдение не создает одностороннего универсально действующего правила принятия решений.
Я согласен, что вы должны выполнить это в своей голове. Если у вас есть 500 линий функциональности в одной большой функции по сравнению с множеством мелких функций, мне не понятно, почему это становится проще.
Предположим, что в экстремальном случае 500 строк кода с прямым побочным эффектом и вы хотите знать, произойдет ли эффект A до или после эффекта B. В большом случае функции используйте Page Up / Down, чтобы найти две строки, а затем сравнить номера строк. В случае многих маленьких функций вы должны помнить, где в дереве вызовов происходят эффекты, и если вы забыли, вам нужно потратить нетривиальное количество времени, чтобы заново открыть структуру этого дерева.
Обходя дерево вызовов вспомогательных функций, вы также сталкиваетесь с проблемой определения, когда вы перешли от бизнес-логики к деталям реализации. Без доказательства * я утверждаю, что чем проще граф вызовов, тем легче провести это различие.
(*) По крайней мере, я честен об этом ;-)
Еще раз, я думаю, что оба подхода имеют свои сильные и слабые стороны.
Заинтересованы ли вы в том, «как» или «что», является функцией цели, для которой вы читаете код (например, получение общей идеи или отслеживание ошибки). Цель, для которой вы читаете код, недоступна при написании программы, и вы, скорее всего, будете читать код для разных целей; разные решения будут оптимизированы для разных целей.
Тем не менее, это та точка зрения босса, с которой я, вероятно, не согласен.
Компиляторы сравнивают имена только на равенство, они никогда не выдают ошибку MisleadingNameError. Кроме того, поскольку несколько сайтов вызовов могут вызывать данную функцию по имени, иногда бывает труднее и подвержено ошибкам изменять имя. Комментарии не имеют этой проблемы. Однако это несколько умозрительно; чтобы действительно решить эту проблему, возможно, понадобятся данные о том, будут ли программисты чаще обновлять вводящие в заблуждение комментарии или вводящие в заблуждение имена, а у меня этого нет.
источник
На мой взгляд, правильный код нужной вам функциональности:
Или, если вы хотите разделить его на функцию, возможно, что-то вроде:
Но я думаю, что у вас есть более фундаментальная проблема с понятием «в производстве». Проблема с вашей функцией
isApplicationInProduction
в том, что кажется странным, что это единственное место в системе, где важно находиться в «производстве», и что вы всегда можете рассчитывать на наличие или отсутствие заголовка resourceId. Должен быть общийisApplicationInProduction
метод илиgetEnvironment
метод, который непосредственно проверяет среду. Код должен выглядеть так:Тогда вы можете получить номер телефона с:
источник
Просто комментарий по двум пунктам
Многие редакторы (например, IntelliJ) позволят вам перейти к функции / классу простым нажатием клавиши Ctrl. Кроме того, вам часто не нужно знать детали реализации функции для чтения кода, что ускоряет чтение кода.
Я рекомендую вам рассказать своему боссу; ему понравится ваша адвокатура и он будет восприниматься как лидерство Просто будь вежливым.
источник