Реклама на сайте (разместить):


Реклама и пожертвования позволяют нам быть независимыми!

Введение поясняющей переменной

Материал из Вавилон.wiki
Перейти к: навигация, поиск

Введение поясняющей переменной (Introduce Explaining Variable)

Имеется сложное выражение.

Поместите результат выражения или его части во временную пере¬менную, имя которой поясняет его назначение.

if ( (platform.toUpperCase().indexQf('MAC") > -1) && (browser.toUpperCase().index0f("IE') > -1) && waslnitialized() && resize > 0 ) { // do something > 4 4/ final boolean- IsMacOs = platform. toUpperCaseO. indexOf("MAC') > -1; final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1; final boolean wasResized = resize > 0; if (isMacOs && isIEBrowser && waslnitialized() && wasResized) ! // do something >

Мотивировка

Выражения могут становиться очень сложными и трудными для чте¬ния. В таких ситуациях полезно с помощью временных переменных превратить выражение в нечто, лучше поддающееся управлению. Особую ценность «Введение поясняющей переменной» (Introduce Ex¬plaining Variable, 137) имеет в условной логике, когда удобно для каждого пункта условия объяснить, что он означает, с помощью времен¬ной переменной с хорошо подобранным именем. Другим примером слу¬жит длинный алгоритм, в котором каждый шаг можно раскрыть с по¬мощью временной переменной.

«Введение поясняющей переменной» (Introduce Explaining Variable, 137) - очень распространенный вид рефакторинга, но должен при¬знаться, что сам я применяю его не очень часто. Почти всегда я пред¬почитаю «Выделение метода» (Extract Method, 124), если это возмож¬но. Временная переменная полезна только в контексте одного метода Метод же можно использовать всюду в объекте и в других объектах. Однако бывают ситуации, когда локальные переменные затрудняют применение «Выделения метода» (Extract Method, 124). В таких слу¬чаях обращаюсь к «Введению поясняющей переменной» (IntroduceЕх plainingVanable, 137).

Техника

Объявите локальную переменную с ключевым словом final и уста¬новите ее значением результат части сложного выражения. Замените часть выражения значением временной переменной.

Если эта часть повторяется, каждое повторение можно заменять поочередно

Выполните компиляцию и тестирование.

Повторите эти действия для других частей выражения.

Пример

Начну с простого вычисления:

  • •»

double priceO { // price есть базисная цена - скидка по количеству + поставка return _quantity * _itemPnce - Math max(0 _quantity - 500) * _itemPrice * 0 05 + Math min(_quantity * _itemPrice * 0 1 100 0) } Простой код, но можно сделать его еще понятнее. Для начала я обо значу количество, умноженное на цену предмета, как базисную цену Эту часть расчета можно превратить во временную переменную:

double price() { // price есть базисная цена - скидка по количеству + поставка final double basePrice = .quantity * _itemPrice return basePrice - Math max(0 _quantity - 500) * _itemPnce * 0 05 + Math min(_quantity * _itemPnce * 0 1 100 0)

Количество, умноженное на цену одного предмета, используется так¬же далее, поэтому и там можно подставить временную переменную:

double priceO { // price есть базисная цена - скидка по количеству + поставка final double basePrice = _quantity * _itemPrice, return basePrice - Math max(0 .quantity - 500) * _itemPnce * 0 05 + Math min(basePnce * 0 1, 100 0), } Теперь возьмем скидку в зависимости от количества:

double рпсеО { // price есть базисная цена - скидка по количеству + поставка final double basePrice = .quantity * _itemPnce, final double quantityDiscount = Math.max(0, .quantity - 500) * .itemPrice * 0.05; return basePrice - quantityDiscount + Math min(basePrice * 0 1, 100 0), }

Наконец, разберемся с поставкой. После этого можно убрать коммен¬тарий, потому что теперь в нем нет ничего, о чем бы не говорил код:

double рпсеО { final double basePrice = .quantity * .itemPrice, final double quantityDiscount = Math max(0 .quantity - 500) .itemPrice * 0 05, final double shipping = Math.min(basePrice * 0.1, 100.0); return basePrice - quantityDiscount + shipping, )

Пример с «Выделением метода»

Для подобного случая я не стал бы создавать поясняющие перемен¬ные, а предпочел бы «Выделение метода» (Extract Method, 124). Снова начинаю с double priceO { // price есть базисная цена - скидка по количеству + поставка return .quantity * .itemPrice - Math max(0, .quantity - 500) * .itemPrice * 0 05 + Math min(_quantity * .itemPrice * 0 1, 100 0), }

На этот раз я выделяю метод для базисной цены:

double рпсе() { // price есть базисная цена - скидка по количеству + поставка return basePriceO - Math max(0, .quantity - 500) * .itemPrice * 0 05 + Math min(basePrice() * 0 1 100 0), > private double basePriceO { return _quantity * _itemPnce, }

Продолжаю по шагам. В итоге получается:

double priceO { return basePriceO - quantityDiscountO + shippingO, > private double quantityDiscountO { return Math max(0 ^quantity - 500) * _itemPnce * 0 05 } private double shippingO { return Math min(basePnceO * 0 1, 100 0) } private double basePriceO { return _quantity * _itemPrice, }

Я предпочитаю «Выделение метода» (Extract Method, 124), поскольку в результате методы становятся доступными в любом другом месте объекта, где они могут понадобиться. Первоначально я делаю их зак¬рытыми, но всегда могу ослабить ограничения, если методы понадо¬бятся другому объекту. По моему, опыту обычно для «Выделения ме¬тода» (Extract Method, 124) требуется не больше усилий, чем для «Введения поясняющей переменной» (Introduce Explaining Variable, 137).

Когда же я применяю «Введение поясняющей переменной» (Introduce Explaining Variable, 137)1 Тогда, когда «Выделение метода» (Extract Method, 124) действительно требует больше труда. Если идет работа с алгоритмом, использующим множество локальных переменных, «Вы¬деление метода» (Extract Method, 124) может оказаться делом непрос¬тым. В такой ситуации я выбираю «Введение поясняющей перемен¬ной» (Introduce Explaining Variable, 137), что позволяет мне лучше по¬нять действие алгоритма. Когда логика станет более доступной для по¬нимания, я смогу применить «Замену временной переменной вызовом метода» (Replace Temp with Query, 133). Временная переменная ока¬жется также полезной, если в итоге мне придется прибегнуть к «Заме¬не метода объектом методов» (Replace Method with Method Object, 148).

глава 6

Статью можно улучшить?
✍ Редактировать 💸 Спонсировать 🔔 Подписаться 📩 Переслать 💬 Обсудить
Позвать друзей