Когда функция слишком долго? [закрытый]

Вы добавляете пользователя ros в группу sudo, но пытаетесь apt-get update, не используя sudo. Поэтому вы запускаете команду непривилегированным и получаете permission denied.

Используйте действительно выполнить команду (t):

FROM ros:kinetic-robot-xenial

RUN whoami
RUN apt-get update
# create non-root user
RUN apt-get install sudo
RUN echo "ros ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
ENV USERNAME ros 
RUN adduser --ingroup sudo --disabled-password --gecos "" --shell /bin/bash --home /home/$USERNAME $USERNAME
RUN bash -c 'echo $USERNAME:ros | chpasswd'
ENV HOME /home/$USERNAME
USER $USERNAME

RUN whoami
RUN sudo apt-get update

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

Также рассмотрите возможность многоэтапной сборки, если вы хотите отделить подготовку образа от фактической работоспособной вещи:

https://docs.docker.com/develop/develop-images/multistage -Build /

125
задан 6 revs, 2 users 100%user58163 7 August 2010 в 14:48
поделиться

24 ответа

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

, Что "выполнение чего-то" могло все еще быть довольно многими строками, хотя, таким образом, я не уверен, много строк правильная метрика для использования :)

Редактирование: Это - одна строка кода, который я отправил по почте вокруг работы на прошлой неделе (для подтверждения точки зрения.. это не что-то, к чему я делаю привычку :)) - я, конечно, не хотел бы 50-60 из этих плохих парней в моем методе :D

return level4 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3) && (r.Level4 == (int)level4)).ToList() : level3 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3)).ToList() : level2 != null ? GetResources().Where(r => (r.Level2 == (int)level2)).ToList() : GetAllResourceList();
73
ответ дан 24 November 2019 в 00:56
поделиться

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

Каждый для цикла, если оператор, и т.д. тогда не рассматривается как ответвление в вызывающем методе.

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

, Если функция/метод только имеет три ответвления, это получит три на той метрике, которая очень хороша.

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

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

0
ответ дан 24 November 2019 в 00:56
поделиться

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

0
ответ дан 24 November 2019 в 00:56
поделиться

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

0
ответ дан 24 November 2019 в 00:56
поделиться

предположение, что Вы делаете один вещь, длина, будет зависеть от:

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

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

0
ответ дан 24 November 2019 в 00:56
поделиться

Я записал 500 функций строки прежде, однако они были просто большими операторами переключения для декодирования и ответа на сообщения. Когда код для единственного сообщения стал более сложным, чем единственный if-then-else, я извлек его.

В сущности, хотя функция была 500 строками, независимо сохраняемые регионы насчитали 5 строк.

1
ответ дан 24 November 2019 в 00:56
поделиться

Я подозреваю, что Вы найдете много ответов на этом.

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

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

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

0
ответ дан 24 November 2019 в 00:56
поделиться

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

2
ответ дан 24 November 2019 в 00:56
поделиться

Было некоторое полное исследование, проведенное по этой самой теме, если Вы хотите наименьшее количество ошибок, Ваш код не должен быть слишком длинным. Но это также не должно быть слишком коротко.

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

См. Оптимальный Размер Класса для Объектно-ориентированного программного обеспечения для дальнейшего обсуждения.

0
ответ дан 24 November 2019 в 00:56
поделиться

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

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

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

1
ответ дан 24 November 2019 в 00:56
поделиться

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

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

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

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

1
ответ дан 24 November 2019 в 00:56
поделиться

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

2
ответ дан 24 November 2019 в 00:56
поделиться

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

А у бывшего моего коллеги было причудливое правило, что функция/метод должна только содержать 4 строки кода! Он пытался придерживаться этого так твердо, что его имена методов часто становились повторяющимся & бессмысленный плюс вызовы стал глубоко вложенным & путание.

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

4
ответ дан 24 November 2019 в 00:56
поделиться

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

6
ответ дан 24 November 2019 в 00:56
поделиться

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

Теперь предполагают, что Ваш код не имеет никаких функций/методов; его всего одно огромное разрастание кода в форме графика.

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

Для определения то, чем размер методы должен быть с точки зрения количества блоков на метод, один вопрос, который Вы могли бы задать сами: сколько методов мне придется минимизировать максимальное потенциальное количество зависимостей (MPE) между всеми блоками?

, Что ответ дан уравнением. Если r является количеством методов, которое минимизирует MPE системы, и n является количеством блоков в системе, то уравнение: r = sqrt (n)

И можно показать, что это дает количество блоков на метод, чтобы быть, также, sqrt (n).

5
ответ дан 24 November 2019 в 00:56
поделиться

Размер приблизительно Вы размер экрана (поэтому идут, получает большой широкий экран центра и поворачивает его)... :-)

Шутка в стороне, одна логическая вещь на функцию.

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

/Johan

5
ответ дан 24 November 2019 в 00:56
поделиться

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

, Почему я могу разбить функцию:

  • Это слишком длинно
  • , Это делает код более удобным в сопровождении путем разбивания его и использования понятных имен для новой функции
  • , функция не связна
  • , Части функции полезны в себе.
  • , Когда трудно придумать понятное имя для функции (Это, вероятно, делает слишком много)
10
ответ дан 24 November 2019 в 00:56
поделиться

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

function build_address_list_for_zip($zip) {

    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

намного более хороший:

function fetch_addresses_for_zip($zip) {
    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }
    return $addresses;
}

function build_address_list_for_zip($zip) {

    $addresses = fetch_addresses_for_zip($zip);

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

Этот подход имеет два преимущества:

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

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

[С другой стороны (я отклоню, я сказал Вам это, даже под пыткой): Если Вы читаете много об оптимизации PHP, Вы могли бы получить идею сохранить количество функций как маленькое возможное, потому что вызов функции очень, очень дорог в PHP. Я не знаю об этом, так как я никогда не делал сравнительных тестов. Если бы это - случай, Вы, вероятно, были бы лучше из не следования любому из ответов на Ваш вопрос, если Вы приложение являетесь очень "производительностью, чувствительной" ;-)]

5
ответ дан 24 November 2019 в 00:56
поделиться

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

27
ответ дан 24 November 2019 в 00:56
поделиться

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

  1. Глубоко вложенные управляющие структуры : например, для циклов 3 уровня глубоко или даже всего 2 уровня глубоко с вложенными операторами "if", которые имеют сложные условия.

  2. Слишком многие определение состояния параметры : определяющий состояние параметр , я имею в виду параметр функции, который гарантирует конкретный путь выполнения через функцию. Получите слишком многие из подобных параметров, и у Вас есть комбинаторный взрыв путей выполнения (это обычно происходит в тандеме с № 1).

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

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

  5. Ненужный служебный : Комментарии, которые указывают на очевидные, глубоко вложенные классы, лишние методы считывания и методы set для частных вложенных переменных класса и необычно долгую функцию/имена переменной, могут все создать синтаксический шум в связанных функциях, которые в конечном счете увеличат их длину.

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

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

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

201
ответ дан 24 November 2019 в 00:56
поделиться

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

, Что Вы действительно не делаете , хотят сделать, скопировать и вставить каждые 10 строк Вашей долгой функции в короткие функции (как Ваш пример предполагает).

18
ответ дан 24 November 2019 в 00:56
поделиться

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

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

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

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

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

я полагаю, что ключевой пункт должен искать reuseability в той долгой функции и вытащить те части. То, с чем Вас оставляют, является функцией, является ли это 10, 20, или 60 строк долго.

16
ответ дан 24 November 2019 в 00:56
поделиться

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

, Если у Вас есть блок кода с комментарием наверху, рассмотрите вытаскивание его в функцию с функцией и именами аргумента, иллюстрирующими ее цель и резервирующими комментарий для объяснения кода.

Вы уверенный, что нет никаких частей там, которые были бы полезны в другом месте? Какая функция - это?

2
ответ дан 24 November 2019 в 00:56
поделиться

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

0
ответ дан 24 November 2019 в 00:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: