Исходный код
function levelIncrease($lvl)
{
for($i = 2, $ng = 0; $i >= 0; $i--) {
$g = ord($lvl[$i]);
if($i == 2)
++$g;
$g += $ng;
$ng = 0;
if($g > 57 && $g < 97)
$g = 97;
elseif($g > 122) {
$diff = $g - 122;
$g = 48 + $diff - 1;
$ng = ceil($diff / 36);
}
$lvl[$i] = chr($g);
if($ng == 0)
break;
}
return $lvl;
}
echo levelIncrease('aaa'); // aab
Что не так в исходном коде
Если в названии функции присутствует глагол, то он должен стоять на первом месте: надо что-то типа increaseLevel
или incrementLevel
.
Однако с моей точки зрения эта функция не функция-команда, а функция-запрос, поэтому глагол здесь не особо нужен. Можно nextLevel
.
Алгоритм инкремента опирается не на фактическую длинну полученного кода, а на допущение, что она всегда будет равна трём. Не всегда такие допущения долго остаются в силе, поэтому есть смысл опираться не на них, а на факты.
В алгоритме смешаны три разных знания: как инкрементировать единичный разряд кода, как выполнить перенос разряда и как инкрементировать весь код в целом.
Непонятно, для чего сделано так, что перенос разряда может быть больше единицы.
Неговорящие названия переменных затрудняют чтение алгоритма.
Магические литералы тоже ясности не добавляют.
Вариант рефакторинга исходного кода
function nextLevel($level)
{
for ($i = length($level) - 1, $carry = 1; $i--) {
list ($level[$i], $carry) = nextDigit($level[$i], $carry);
if ($carry == 0) break;
}
return $level;
}
const CODE_0 = 48;
const CODE_9 = 57;
const CODE_A = 97;
const CODE_Z = 122;
function nextDigit($digit, $carry) {
// перенос может быть только 0 или 1
$digit_code = ord($digit);
$digit_code += $carry;
if ($digit_code > CODE_0 && $digit_code < CODE_A) {
return ['a', 0];
}
elseif ($digit_code > CODE_Z) {
return ['z', 1];
}
return [ord($digit_code), 0];
}
А если говорить об улучшении инкремента как такового, я бы сделал примерно вот так:
function nextLevel($level)
{
$level10 = base_convert($level, 36, 10);
$level10++;
return base_convert($level10, 10, 36);
}
Теория
- Принцип единственного знания
- Рефакторинг «извлечение функции»
- Название переменной
- Магические литералы