Пример рефакторинга «извлечение метода» для кода поиска и группировки подходящих товаров


Исходный код

foreach ($_pp as $k => $v) {
    if ($v['qty'] == $_pp[$i*count($groups)]['qty']) {
        $qtys[$i][]=$v;
    }
}

Что не так в исходном коде

В цикле выполняется банальный поиск объектов по определённому признаку, но сам признак не до конца ясен. Понятно, что отбираются объекты, в которых количество совпадает с количеством в контрольном объекте того же массива, но нет указаний на то, чем является этот контрольный объект.

Несмотря на то, что кусок исходного кода совсем маленький, в нём смешаны три знания. Первое — как искать (через цикл и сравнение). Второе — что искать ($_pp[$i*count($groups)]). Третье — куда девать результат.

Сами обрабатываемые объекты являются массивами, а не экземплярами класса, что сомнительно по причине «[https://pro-code.su/knowledge-diffusion](размазывания знаний)».

Названия переменных отличаются лаконичностью, поэтому ничего не сообщают об их предназначении.

Как можно улучшить исходный код

Сначала надо расцепить знания.

$sample_product = $products[$segment_number * $group_size];

$product_segment = [];
foreach ($productsas$product) {
    if ($product['qty'] === $sample_product['qty']) {
        $product_segment[] = $product;
    }
}

$qtys[$segment_number] = $product_segment;

Теперь, когда ключевое знание исходного кода чётко очерчено, можно улучшать реализацию дальше, например, создав отдельный класс под коллекцию товаров, поместив поиск товаров в отдельный метод и применив функцию array_filter.

class ProductCollection {
    private $products;

    public function findMatching($sample_product) {
        return array_filter($this->products, function ($product) use ($sample_product) { 
            return $product['qty'] === $sample_product['qty'];
        });
    }
}

Обрати внимание на название метода. Оно должно соотноситься с целью метода, с его результатом (которые связаны с предметной областью), а не с реализацией.

Если смысл метода — в поиске похожих товаров, а сходство определяется путём сравнения количества, то и название должно говорить просто о сходстве. В данном конкретном случае, скорее всего, смысл завязан именно на количестве, так что пример не очень удачный.

Если бы было доступно больше исходного кода, можно было бы порассуждать об оптимальности алгоритма группировки в целом, а не только его отдельного фрагмента.

Теория