Предположим, у меня есть сегмент кода для подключения к Интернету и отображения результатов подключения, например:
HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
string responseString=response->getResponseDataString();
if(response->getErrorCode()!=200){
if(response->getErrorCode()==404){
Alert* alert=new Alert();
alert->setFontSize(30);
alert->setFontColor(255,255,255);
alert->setPosition(Screen.MIDDLE);
alert->show("Connection Error","Not Found");
}else if((some other different cases)){
(some other alert)
}else
Alert* alert=new Alert();
alert->setFontSize(30);
alert->setPosition(Screen.MIDDLE);
alert->setFontColor(255,255,255);
alert->show("Connection Error","unknown error");
}
}else{
(other handle methods depend on different URL)
}
}
код длинный и обычно используется, но приведенный выше код не требует каких-либо дополнительных вещей, таких как пользовательские функции и классы (HttpRequest и Alert оба по умолчанию предоставляются framework), и хотя сегмент кода длинный, он простой и не сложный (он длинный только потому, что есть набор настроек, таких как url, размер шрифта ...), и сегмент кода имеет небольшие различия между классами (например: url, данные запроса, случаи с дескриптором кода ошибки, нормальный дескриптор случаи ...)
У меня вопрос: допустимо ли копировать и вставлять длинный, но простой код вместо того, чтобы заключать их в функцию, чтобы уменьшить зависимость кода?
Alert
объекты?) Теперь представьте, что вам нужно найти каждый скопированный экземпляр этого кода, чтобы исправить ошибку. А теперь представьте, что это должен делать не вы, а сумасшедший убийца топоров, который знает, что именно вы создали все эти копии в первую очередь.Ответы:
Вам необходимо учитывать стоимость изменений. Что, если вы хотите изменить способ подключения? Насколько легко это будет? Если у вас много дублированного кода, то поиск всех мест, которые нужно изменить, может быть довольно трудоемким и подверженным ошибкам.
Вам также необходимо учитывать ясность. Скорее всего, необходимость взглянуть на 30 строк кода не будет так же легко понять, как один вызов функции connectToInternet. Сколько времени будет потеряно, пытаясь понять код, когда необходимо добавить новую функциональность?
Есть определенные редкие случаи, когда дублирование не является проблемой. Например, если вы проводите эксперимент, а код будет отброшен в конце дня. Но в целом стоимость дублирования перевешивает небольшую экономию времени, когда нет необходимости извлекать код в отдельную функцию .
См. Также /software//a/103235/63172.
источник
HttpRequest
одинакового », легко ошибочна.Нет.
На самом деле, даже ваш «простой» код должен быть разбит на более мелкие части. По меньшей мере, два.
Один, чтобы установить соединение и обработать нормальный ответ 200. Например, что если в некоторых случаях вы меняете POST на PUT? Что, если вы создаете миллионы таких соединений и нуждаетесь в многопоточности или пуле соединений? Наличие кода в одном месте с аргументом для метода сделает это намного проще
Точно так же, другой для обработки ошибок. Например, если вы измените цвет или размер шрифта оповещения. Или у вас проблемы с прерывистыми подключениями и вы хотите регистрировать ошибки.
источник
Нет.
Для меня решающим аргументом является следующий:
Если вы используете фрагмент кода в более чем одном месте, то, когда он меняется, вам нужно изменить его в более чем одном месте, или вы начинаете получать несоответствия - начинают происходить «странные вещи» (т.е. вы вводите ошибки).
И так должно быть проще сделать рефакторинг в функцию.
А что любят менять пользователи? Шрифты, размеры шрифтов, цвета и т. Д. И т. Д.
В настоящее время; во скольких местах вам придется изменить этот же кусок кода, чтобы они снова получили одинаковый цвет / шрифт / размер? (Рекомендуемый ответ: только один ).
Вариация => функциональные параметры.
источник
Это не имеет никакого отношения к копированию и вставке. Если вы берете код из другого места, во второй вы берете код, это ваш код и ваша ответственность, поэтому, независимо от того, копируется он или полностью написан вами, не имеет значения.
В ваших оповещениях вы принимаете некоторые дизайнерские решения. Скорее всего, аналогичные проектные решения должны быть приняты для всех предупреждений. Поэтому вполне вероятно, что у вас должен быть метод где-то "ShowAlertInAStyleSuitableForMyApplication" или, возможно, немного короче, и его следует вызывать.
У вас будет много http-запросов с похожей обработкой ошибок. Вы, вероятно, не должны дублировать обработку ошибок снова и снова и снова, а извлекать общую обработку ошибок. Особенно, если ваша обработка ошибок становится немного более сложной (как насчет ошибок тайм-аута, 401 и т. Д.).
источник
Дублирование в некоторых случаях нормально. Но не в этом. Этот метод слишком сложен. Существует нижний предел, когда дублирование проще, чем «вычленение» метода.
Например:
глупо, просто сделай a + b.
Но когда вы становитесь чуть-чуть сложнее, тогда вы обычно выходите за рамки.
должен стать
В твоем случае я вижу четыре «метода». Вероятно, в разных классах. Один для выполнения запроса, другой для получения ответа, другой для отображения ошибок и некоторый вид обратного вызова, который будет вызван после возврата ответа для обработки ответа. Лично я, скорее всего, добавил бы «обертку», чтобы облегчить вызовы.
В конце, чтобы сделать веб-запрос, я бы хотел, чтобы звонок выглядел примерно так:
Эта строка - то, что у меня было бы по всему моему коду. Затем, когда мне нужно было внести изменения в «как я получаю материал», я мог сделать это быстро, с гораздо меньшими усилиями.
Это также сохраняет код СУХОЙ и помогает с SRP .
источник
В проекте любого размера / сложности я хочу иметь возможность находить код, когда он мне нужен, для следующих целей:
Разве не было бы замечательно присоединиться к незавершенному проекту или продолжить работу над проектом в течение нескольких лет, и когда новый запрос «подключиться к Интернету и показать результаты подключения» был в некоторой степени легко найти из-за наличия хороший дизайн вместо того, чтобы полагаться на поиск по всему коду для httprequest? В любом случае, с Google, наверное, легче найти.
Не волнуйтесь, я новичок, и я проведу рефакторинг этого блока кода, потому что я очень расстроен из-за того, что присоединился к этой бестолковой команде с ужасной базой кода, или сейчас я нахожусь под большим давлением, как и остальные Вы и просто скопируете и вставите его. По крайней мере, это удержит босса от моей спины. Затем, когда проект действительно будет определен как катастрофа, я буду первым, кто порекомендует нам переписать его, скопировав и вставив версию в последнюю и лучшую среду, которую никто из нас не понимает.
источник
Класс и / или функция лучше, по крайней мере, на мой взгляд. На этот раз файл становится меньше, что очень выгодно, если вы работаете с веб-приложениями или приложениями для устройств с небольшим объемом памяти (IoT, старые телефоны и т. Д.).
И, очевидно, лучшим моментом является то, что если вам нужно что-то изменить из-за новых протоколов и т. Д., Вы просто меняете содержимое функции, и не бесчисленное количество раз вы помещаете эту функцию куда-то, что может даже находиться в разных файлах, делая их еще труднее найти и изменить.
Я написал целый интерпретатор SQL, чтобы лучше переключаться с MySQL на MySQLi в PHP, потому что мне просто нужно изменить мой интерпретатор, и все работает, хотя это немного экстремальный пример.
источник
Чтобы решить, должен ли код дублироваться или перемещаться в функцию, которая вызывается дважды, попробуйте определить, какая из них более вероятна:
Необходимо будет изменить оба использования кода одинаково.
Необходимо будет изменить хотя бы одно использование кода, чтобы они различались.
В первом случае, вероятно, будет лучше иметь одну функцию, обрабатывающую оба использования; в последнем случае, вероятно, будет лучше иметь отдельный код для двух использований.
Принимая решение о том, должен ли фрагмент кода, который будет использоваться один раз, записываться в строку или извлекаться в другую функцию, выясните, как можно полностью описать требуемое поведение функции. Если полное и точное описание требуемого поведения функции будет таким же длинным или длинным, как сам код, перемещение кода в отдельную функцию может усложнить понимание, а не упростить вещи. Возможно, все-таки стоит сделать, если существует высокая вероятность того, что второму вызывающему абоненту потребуется использовать ту же функцию, и любые будущие изменения в функции должны будут повлиять на обоих вызывающих абонентов, но в отсутствие такого рассмотрения удобочитаемость будет способствовать разделению до уровня, на котором код и описание его требуемого поведения будут примерно одинаково длинными.
источник