Я читаю Код Макконелла , и он обсуждает использование логических переменных для документирования вашего кода. Например, вместо:
if((elementIndex < 0) || (MAX_ELEMENTS < elementIndex) ||
(elementIndex == lastElementIndex)){
...
}
Он предлагает:
finished = ((elementIndex < 0) || (MAX_ELEMENTS < elementIndex));
repeatedEntry = (elementIndex == lastElementIndex);
if(finished || repeatedEntry){
...
}
Мне это кажется логичным, передовым и очень самодокументируемым. Однако я не решаюсь начать использовать эту технику регулярно, поскольку я почти никогда с ней не сталкивался; и, возможно, это сбивало бы с толку только потому, что было редкостью. Однако мой опыт еще не очень обширен, поэтому мне интересно услышать мнение программистов об этой технике, и мне было бы любопытно узнать, использует ли кто-нибудь эту технику регулярно или часто видел ее при чтении кода. Стоит ли принять это соглашение / стиль / метод? Другие программисты поймут и оценят это или сочтут это странным?
Ответы:
Разделение слишком вложенного и сложного выражения на более простые подвыражения, назначенные локальным переменным, а затем снова собранные вместе, является довольно распространенной и популярной техникой - совершенно независимо от того, являются ли подвыражения и / или общее выражение логическими или логическими. почти любой другой тип. При правильно подобранных именах подобная декомпозиция со вкусом может повысить удобочитаемость, и у хорошего компилятора не должно возникнуть проблем с генерацией кода, эквивалентного исходному сложному выражению.
Некоторые языки, в которых отсутствует концепция «присваивания» как таковая, например, Haskell, даже вводят специализированные конструкции, позволяющие использовать технику «дать имя части выражения» (
where
предложение в Haskell) - кажется, некоторые популярность рассматриваемой техники! -)источник
Я использовал его, хотя обычно булеву логику оборачивали в метод многократного использования (если вызывается из нескольких мест).
Это способствует удобочитаемости, и когда логика меняется, ее нужно изменить только в одном месте.
Другие поймут это и не сочтут это странным (то есть, за исключением тех, кто когда-либо писал только тысячи строчных функций).
источник
Я стараюсь делать это везде, где возможно. Конечно, вы используете «лишнюю строку» кода, но в то же время вы описываете, почему вы сравниваете два значения.
В вашем примере я смотрю на код и спрашиваю себя: «Хорошо, почему человек, который видит, что значение меньше 0?» Во втором вы ясно говорите мне, что некоторые процессы завершаются, когда это происходит. Во втором не догадываешься, каковы были твои намерения.
Самым большим для меня является то, что я вижу такой метод, как:
DoSomeMethod(true);
Почему он автоматически устанавливается на true? Это намного читаемее, напримеристочник
[Object createOrderWithSource:YES backOrder:NO custom:YES type:kCreditCard];
Предоставленный образец:
Также можно переписать для использования методов, которые улучшают читаемость и сохраняют логическую логику (как указал Конрад):
Конечно, за это приходится платить, так как это два дополнительных метода. Если вы будете делать это часто, это может сделать ваш код более читабельным, но ваши классы будут менее прозрачными. Но опять же, вы также можете переместить дополнительные методы во вспомогательные классы.
источник
Единственный способ увидеть, что это идет не так, - это если у логического фрагмента нет имени, которое имеет смысл, и имя все равно выбрано.
Я указываю на это, потому что правила типа «комментируйте весь свой код», «используйте именованные логические значения для всех if-критериев с более чем 3 частями» - обычное дело »только для получения комментариев, которые семантически пусты следующего вида
источник
Делая это
вы удаляете логику из своего мозга и вставляете ее в код. Теперь программа знает, что вы имели в виду.
Когда вы что-то называете, вы даете этому физическое представление. Это существует.
Вы можете манипулировать им и использовать его повторно.
Вы даже можете определить весь блок как предикат:
и сделайте больше (позже) в этой функции.
источник
Если выражение сложное, то я либо перемещаю его в другую функцию, которая возвращает,
bool
напримерisAnEveningInThePubAGoodIdea(dayOfWeek, sizeOfWorkLoad, amountOfSpareCash)
,, либо пересматриваю код, чтобы такое сложное выражение не требовалось.источник
Помните, что таким образом вы вычисляете больше, чем необходимо. Из-за извлечения условий из кода вы всегда вычисляете их оба (без короткого замыкания).
Так что:
После преобразования становится:
В большинстве случаев это не проблема, но все же в некоторых это может означать снижение производительности или другие проблемы, например, когда во втором выражении вы предполагаете, что первое не удалось.
источник
Думаю, лучше вместо временных переменных создавать функции / методы. Таким образом повышается удобочитаемость еще и потому, что методы становятся короче. В книге Мартина Фаулера «Рефакторинг» есть хорошие советы по повышению качества кода. Рефакторинг, связанный с вашим конкретным примером, называется «Заменить временный запрос на запрос» и «Метод извлечения».
источник
Лично я считаю, что это отличная практика. Это влияние на выполнение кода минимально, но ясность, которую он может обеспечить при правильном использовании, неоценима, когда дело доходит до поддержки кода в дальнейшем.
источник
если для метода требуется уведомление об успехе: (примеры в C #) Мне нравится использовать
чтобы начать. код неверен, пока я не изменю его на:
затем в конце:
источник
Думаю, это зависит от того, какой стиль предпочитаете вы / ваша команда. Рефакторинг "ввести переменную" может быть полезен, но иногда нет :)
И я не согласен с Кевином в его предыдущем посте. Его пример, я полагаю, можно использовать в случае, если введенная переменная может быть изменена, но вводить ее только для одного статического логического значения бесполезно, потому что у нас есть имя параметра в объявлении метода, так зачем дублировать его в коде?
например:
источник
По моему опыту, я часто возвращался к некоторым старым сценариям и задавался вопросом: «Что, черт возьми, я тогда думал?». Например:
что не так интуитивно понятно, как:
источник
Я редко создаю отдельные переменные. Когда тесты усложняются, я вкладываю IF и добавляю комментарии. подобно
Признанный недостаток этой техники состоит в том, что следующий приходящий программист может изменить логику, но не утруждает себя обновлением комментариев. Я предполагаю, что это общая проблема, но я много раз видел комментарий, в котором говорится: «Подтвердите идентификатор клиента», а в следующей строке проверяется номер детали или что-то подобное, и мне остается задаться вопросом, где покупатель входит id.
источник