Я услышал, что люди говорят, что копия желания и вставка однажды (ограничение дублирования кода к самое большее двум экземплярам), поскольку абстракции не окупаются, если Вы не используете код в трех местах или больше. () Самостоятельно, я пытаюсь сделать это хорошей привычкой к рефакторингу, как только я вижу потребность.
Задайте этот вопрос о своих функциях
, "если это небольшое требование изменяется, я должен буду изменить обе функции для удовлетворения его?"
Конечно, это иногда приемлемо. Вот почему люди сохраняют файлы отрывка. Но если Вы вырезаете и вставляете код очень часто, или с больше, чем несколькими строками, необходимо думать о создании его подпрограмма. Почему? потому что разногласия относительно необходимо будет изменить что-то и этот путь, только необходимо изменить его однажды.
средний случай должен использовать макрос, если у Вас есть такое доступное.
Да. Когда сегмент немного отличается, и Вы делаете доступные системы (системы, которые являются там в течение очень короткого срока и не будут нуждаться в обслуживании). Иначе, его обычно лучше для извлечения общностей.
, Если различие находится в данных, осуществите рефакторинг путем извлечения функции и использования различия в данных как параметры (Если существуют слишком многие к данным для передачи в качестве параметра, рассмотрите группировку их в объект или структуру). Если различие находится в некотором процессе в функции, осуществите рефакторинг при помощи шаблона "команда" или абстрактного шаблона. Если все еще трудно осуществить рефакторинг даже с этими шаблонами разработки, то Ваша функция могла бы пытаться обработать ко многим обязанностям самостоятельно.
, Например, если у Вас есть сегмент кода, который отличается по двум сегментам - diff#1, и diff#2. И в diff#1, у Вас может быть diff1A или diff1B, и для diff#2 у Вас могут быть diff2A и diff2B.
, Если diff1A & diff2A всегда вместе, и diff1B & diff2B всегда вместе, затем diff1A & diff2A может содержаться в одном классе команды или одной абстрактной шаблонной реализации и diff1B & diff2B в другом.
Однако, если существует несколько комбинаций (т.е. diff1A & diff2A, diff1A & diff2B, diff1B & diff2A, diff1B & diff2B), затем можно хотеть заново продумать функцию, потому что это может пытаться обработать слишком много обязанностей самостоятельно.
Используя логики (если еще, циклы) для создания SQL динамично жертвует удобочитаемостью. Но создание всех изменений SQL было бы трудно поддержать. Поэтому встретьтесь на полпути и используйте Сегменты SQL. Общности извлечения как сегменты SQL и создают все изменения SQL с теми сегментами SQL как константы.
, Например:
private static final String EMPLOYEE_COLUMNS = " id, fName, lName, status";
private static final String EMPLOYEE_TABLE = " employee";
private static final String EMPLOYEE_HAS_ACTIVE_STATUS = " employee";
private static final String GET_EMPLOYEE_BY_STATUS =
" select" + EMPLOYEE_COLUMNS + " from" + EMPLOYEE_TABLE + " where" + EMPLOYEE_HAS_ACTIVE_STATUS;
private static final String GET_EMPLOYEE_BY_SOMETHING_ELSE =
" select" + EMPLOYEE_COLUMNS + " from" + EMPLOYEE_TABLE + " where" + SOMETHING_ELSE;
Да, и это точно, как Вы говорите; незначительные но трудные к фактору изменения. Не клеймите себя, если это действительно, к чему призывает ситуация.
Как Martin Fowler предполагает,
делают это однажды, прекрасный.
делают это дважды, начинает пахнуть.
делают это трижды, время к осуществляют рефакторинг .
<час>РЕДАКТИРОВАНИЕ: в ответе на комментарий источником совета является Don Roberts:
Три забастовки и Вы осуществляете рефакторинг .
Martin Fowler описывает это в Рефакторинг глава 2, раздел The Rule of Three (страница 58).
В кодовой базе моей компании у нас есть серия приблизительно приблизительно 10 больших волосатых SQL-операторов, которые имеют высокую степень общности. Все операторы имеют общее ядро или по крайней мере ядро, которое только отличается словом или два. Затем Вы могли сгруппировать эти 10 операторов в 3 или 4 группировки, которые добавляют общие придатки к ядру, снова с, возможно, одним или двумя словами, отличающимися в каждом придатке. Во всяком случае думайте об этих 10 SQL-операторах как о наборах в схеме Венна со значительным перекрытием.
Мы приняли решение кодировать эти операторы в таком как путь для предотвращения любого дублирования. Так, существует функция (технически, метод Java) для создания оператора. Требуются некоторые параметры, которые составляют слово или два из различия в общем ядре. Затем это берет функтор для того, чтобы пристроить придатки, который, конечно, также параметризован с большим количеством параметров для незначительных различий и большим количеством функторов для большего количества придатков и так далее.
код умен в этом, ни один из SQL никогда не повторяется. Если когда-нибудь необходимо изменять пункт в SQL, Вы изменяете его во всего одном месте, и все 10 SQL-операторов изменяются соответственно.
, Но человек код трудно для чтения. О единственном способе выяснить то, что SQL будет выполняемым для данного случая, должно ступить через с отладчиком и распечатать SQL после того, как он был полностью собран. И выяснение, как конкретная функция, которая генерирует пункт, вписывается в большее изображение, противно.
Начиная с записи этого, я часто задавался вопросом, были ли мы более обеспечены просто вырезание и вставление SQL-запроса 10 раз. Конечно, если мы сделали это, любому изменению в SQL, возможно, придется произойти в 10 местах, но комментарии могли помочь указать на нас на 10 мест для обновления.
преимущество наличия понятного SQL и все в одном месте, вероятно, перевесили бы недостатки вырезания и вставления SQL.
Если это - единственный способ сделать это, то пойдите для него. Часто времена (в зависимости от языка), можно удовлетворить незначительные изменения к той же функции с дополнительным аргументом.
Недавно, у меня было добавление () функция и редактирование () функция в Сценарии PHP. Они оба сделали фактически то же самое, но редактирование () функция выполнило Запрос на обновление вместо Запроса на вставку. Я просто сделал что-то как
function add($title, $content, $edit = false)
{
# ...
$sql = edit ? "UPDATE ..." : "INSERT ...";
mysql_unbuffered_query($sql);
}
, Работал отлично - но существуют другие времена, когда скопировать/вставить необходимо. Не используйте некоторый странный, сложный путь для предотвращения его.
:)
Вы могли отправить рассматриваемый код и видеть, что легче, чем, на что это похоже
необходимо ли скопировать и вставить ли?Какая разница! То, что важно, , почему Вы - копия и вставка. Я не пытаюсь стать философским на любом здесь, но давайте думать об этом практически:
это из лени? "И тому подобное я сделал это прежде... Я только меняю несколько имен переменной.. сделанный".
Не проблема, если это уже был хороший код, прежде чем Вы скопировали и вставили его. Иначе Вы увековечиваете дрянной код из лени, которая укусит Вашу задницу в будущем.
это, потому что Вы не понимаете? "Чертовски.. Я не понимаю, как та функция работает, но интересно, будет ли она работать в моем коде.." Это могло бы! Это может сэкономить Вам время в непосредственный момент, когда Вы напряжены, что у Вас есть крайний срок в 9:00, и Вы смотрите красные следивший на часы около 4:00
, Вы поймете этот код, когда Вы возвратитесь к нему? Даже если Вы комментируете это? Нет действительно - после тысяч строк кода, если Вы не понимаете то, что делает код, поскольку Вы пишете это, как Вы поймете возвращение к нему недели, несколько месяцев спустя? Попытка изучить это, несмотря на все искушение иначе. Выведите его, это поможет выучить его. Каждая строка, которую Вы вводите, спрашиваете себя, что делает та строка и как она способствует полной цели той функции. Даже если Вы не изучаете это наизнанку, у Вас мог бы быть шанс при распознавании его по крайней мере, когда Вы возвращаетесь к нему позже.
Так - копирование и вставка кода? Прекрасный, если Вы ощущаете последствия того, что Вы делаете. Иначе? Не делайте этого. Кроме того, удостоверьтесь, что у Вас есть копия лицензии любого стороннего кода, который Вы копируете и вставляете. Кажется здравым смыслом, но Вы были бы удивлены, сколько не делают люди.
Я избегаю вырезанный и вставленный как эпидемия. Это еще хуже, чем его кузен клонирует и изменяет. Если сталкивающийся с ситуацией как Ваша я всегда готов использовать макропроцессор или другой сценарий для генерации различных изменений. По моему опыту, единственный момент истины чрезвычайно важен.
, К сожалению, макропроцессор C не очень хорош с этой целью из-за раздражающих требований заключения в кавычки для новых строк, выражений, операторов и аргументов. Я очень не хочу писать
#define RETPOS(E) do { if ((E) > 0) then return; } while(0)
, но что заключение в кавычки является необходимостью. Я буду часто использовать препроцессор C несмотря на его дефициты, потому что он не добавляет другой объект к набору инструментальных средств и так не требует изменения процесса сборки или Make-файлов.
Я рад, что этот отмечен как субъективный, потому что это, конечно! Это - чрезмерно неопределенный пример, но я предположил бы что, если у Вас есть достаточно кода, который дублирован, что Вы могли абстрагировать те разделы и сохранить различные части отличающимися. Точка не вставка копии так, Вы не заканчиваете тем, что имели код, который трудно поддержать и хрупкий.
Лучший способ (помимо преобразования в общие функции или макросы использования) состоит в том, чтобы вставить комментарии. Если Вы прокомментируете, где код копируется от и до, и что общность, и различия и причина того, чтобы сделать его... затем Вы будете в порядке.
Если Вы находите, что у Вас есть функции, которые являются главным образом тем же, но в различных сценариях требуют небольших тонких настроек, именно Ваш дизайн является проблемой. Используйте полиморфизм и состав вместо флагов или вставки копии.