Рефакторинг: введение объясняющих переменных
Иногда в исходном коде выражения бывают настолько сложными, что если даже и мы их написали, то по прошествии какого-то времени не можем понять, что мы имели в виду в том или ином участке кода.
Например, рассмотрим следующее выражение (правда, оно не настолько сложное, но выражения посложнее я покажу далее):
if ((strpos(strtoupper($platform), "MAC") !== false) &&
(strpos(strtoupper($browser), "IE") !== false) &&
wasInitialized() && $resize > 0 ) {
// что-то делаем ...
}
Чтобы нам легче было понять логическое выражение в условии, попробуем упростить его с помощью нашего сегодняшнего приема:
$isMacOs = strpos(strtoupper($platform), "MAC") !== false;
$isIEBrowser = strpos(strtoupper($browser), "IE") !== false;
$wasResized = $resize > 0;
if ($isMacOs && $isIEBrowser && wasInitialized() && $wasResized) {
// что-то делаем ...
}
Выражение могут быть очень сложными для понимания и чтения. В таких случаях введение локальных переменных может существенно помочь разбить сложное и длинное выражение на ряд более простых. Только тут надо учитывать, что имена переменных должны быть понятны читателю кода, т.е. они должны отражать суть того, что делает выражение, результат которого сохраняется в переменной.
Иногда бывает трудно применить прием группировки кода в отдельную функцию, о котором мы говорили ранее. И наш сегодняшний прием немного может облегчить нам жизнь в этом случае.
Рассмотрим теперь пример посложнее:
function price() {
// цена = базовая_цена - скидка + стоимость_доставки
return $this->_quantity * $this->_itemPrice -
max(0, $this->_quantity - 500) * $this->_itemPrice * 0.05 +
min($this->_quantity * $this->_itemPrice * 0.1, 100.0);
}
Во-первых, в примере базовая цена вычисляется как цена одной единицы, умноженная на количество товара. Мы можем с легкостью выделить это в отдельную переменную:
function price() {
// цена = базовая_цена - скидка + стоимость_доставки
$basePrice = $this->_quantity * $this->_itemPrice;
return $basePrice -
max(0, $this->_quantity - 500) * $this->_itemPrice * 0.05 +
min($basePrice * 0.1, 100.0);
}
Во-вторых, мы можем выделить вычисление скидки в отдельную переменную:
function price() {
// цена = базовая_цена - скидка + стоимость_доставки
$basePrice = $this->_quantity * $this->_itemPrice;
$qtyDiscount = max(0, $this->_quantity - 500) * $this->_itemPrice * 0.05;
return $basePrice - $qtyDiscount + min($basePrice * 0.1, 100.0);
}
В конце концов, я могу вынести определение стоимости доставки в третью переменную. При этом я могу удалить комментарий, т.к. он для понимания кода уже не нужен:
function price() {
$basePrice = $this->_quantity * $this->_itemPrice;
$qtyDiscount = max(0, $this->_quantity - 500) * $this->_itemPrice * 0.05;
$shipping = min($basePrice * 0.1, 100.0);
return $basePrice - $qtyDiscount + $shipping;
}
Но здесь мы могли бы вполне использовать прием группировки кода в отдельную функцию:
function price() {
return basePrice() - qtyDiscount() + shipping();
}
function quantityDiscount() {
return max(0, $this->_quantity - 500) * $this->_itemPrice * 0.05;
}
function shipping() {
return min($this->basePrice() * 0.1, 100.0);
}
function basePrice() {
return $this->_quantity * $this->_itemPrice;
}
Я предпочел бы использовать именно группировку кода в отдельную функцию, т.к. в этом случае выделенные методы quantityDiscount, shipping и basePrice доступны любой части объекта, в котором мы их используем. Но если у нас есть довольно сложное выражение, которое не позволит нам просто так применить прием группировки, мы вынуждены будем применить наш сегодняшний прием введения объясняющих переменных.
Постовой:
- Недвижимость в Одессе, продажа квартир в одессе
- Рекомендую выдержанное вино и шампанское торговой марки Французский бульвар
- Вам нужна очистка воздуха? Тогда жмите на ссылку!
Популярность: 4%
- Рефакторинг: выделение временной переменной в метод
- Рефакторинг: избавляемся от очевидных функций
- Рефакторинг: параметризация метода


Ноябрь 3rd, 2008
Хороший прием для качественного кода, но делать руппировку кода в отдельную функцию надо только тогда когда код встречается более двух раз, а если нет то переменные самый раз.
Ноябрь 9th, 2008
Нашёл ошибку, по крайне мере у меня не воспринимает браузер пока не исправил: #
# function quantityDiscount() {
# return max(0, $this->_quantity - 500) * $this->_itemPrice * 0.06;
Кто нить уже пробовал код?
Ноябрь 9th, 2008
2 iwan: не воспринимает скорее всего не браузер, а php-интерпретатор ) Тут конечно будет ошибка, если держать этот код не в классе, в котором есть поля _quantity и _itemPrice. А вообще этот код просто для примера приведен, его даже пробовать не стоит
Достаточно понять смысл приема.