Статьи

Используйте заявления и читаемость кода

У меня была дискуссия на IRC об операторах использования и о том, улучшают ли они читаемость кода или нет.

Выбор

Рассмотрим этот гипотетический код:

$cache = new \User\Service\Cache();
$mapper = new \User\Mapper\User($cache)
$form = new \User\Form\Registration($mapper);
$form->process($request->getPost());

против

use User\Service\Cache;
use User\Mapper\User;
use User\Form\Registration;

// other code

$cache = new Cache();
$db = new User($cache)
$form = new Registration($mapper);
$form->process($request->getPost());

Первый фрагмент совершенно недвусмыслен за счет многословия. Эти длинные имена классов затрудняют быстрый анализ того, что происходит. Второе явно менее загромождено, но за счет двусмысленности. Какой именно класс является пользователем? Я должен был бы пойти в вершину файла, чтобы узнать. Должен ли я использовать псевдонимы? Если так, как я должен назвать их?

Это еще более интересно в контексте запросов на извлечение, когда в файле уже есть оператор использования. В результате рассматриваемый вами разностный файл не содержит оператора use, поэтому вам нужно перейти к другому представлению, чтобы убедиться, что используемый класс на самом деле правильный. Если используются полностью квалифицированные имена классов, тогда разница в PR является независимой и ее легче просматривать.

Получение совета

Как и во многих вещах в программировании, есть плюсы и минусы, поэтому я обратился к людям, которые следуют за мной в Twitter, и спросил их:

Людям нравятся операторы «use» или разделение сотен строк кода между реальным именем класса и его фактическим использованием раздражает?

15 марта 2014 г.

Было много интересных ответов , в том числе:

@akrabat Я думаю, что использование утверждений просто абстрактно, откуда приходит класс. Некоторые люди находят это полезным. Помогает держать линии под 80 символов

— Герман Радтке (@hermanradtke) 15 марта 2014 г.

@akrabat Я думаю, полезно видеть все пакеты, используемые классом, без необходимости просматривать весь код.

— Бен Джонсон (@ben_johnson) 15 марта 2014 г.

@akrabat Одна из причин, по которой они мне нравятся, заключается в том, что я могу просмотреть файл и сразу узнать зависимости.

— weierophinney (@mwop) 16 марта 2014 г.

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

Некоторые люди также отметили, что вы можете внести ясность при импорте:

@akrabat Я ценю то, что вы говорите о введении операторов косвенного использования. Псевдоним нечетких имен классов может помочь.

— Ричард Миллер (@mr_r_miller) 15 марта 2014 г.

@akrabat Неоднозначность может быть решена с использованием псевдонимов. Например: используйте My \ Mapper \ User; использовать My \ Mapper \ User как UserMapper;

— Никола Поша (@nikolaposa) 16 марта 2014 г.

@akrabat Я всегда импортирую пространство имен ниже класса. Так что мои намеки — это некое пространство \ пользователь

— Брэндон Сэвидж (@brandonsavage) 15 марта 2014 г.

Если вы постоянно называете свои псевдонимы, то код будет короче и понятнее. Если мы примем подход Брэндона, то приведенный выше пример станет:

use User\Service;
use User\Mapper;
use User\Form;

// other code

$cache = new Service\Cache();
$db = new Mapper\User($cache)
$form = new Form\Registration($mapper);
$form->process($request->getPost());

Теперь «псевдонимы» кодифицированы по имени пространства имен PHP, поэтому вы не зависите от разработчика, который называет псевдоним. Однако список операторов использования больше не является списком зависимых классов, это список зависимых пространств имен.

Мои мысли

Подумав обо всех ответах, которые я получил, и проспав о них, я думаю, что желательно иметь возможность организовать ваш код и назвать ваши классы так, чтобы при импорте мы минимизировали неоднозначность. Если бы мы реорганизовались, мы могли бы придумать что-то вроде этого:

use User\UserCache;
use User\UserMapper;
use User\RegistrationForm;

// other code

$cache = new UserCache();
$db = new UserMapper($cache)
$form = new RegistrationForm($mapper);
$form->process($request->getPost());

Теперь мы упростили нашу иерархию классов, что привело к более ясным именам классов. Конечно, это не всегда возможно, и в этих случаях я думаю, что последовательное именование псевдонимов — это путь.

Я что-то упустил очевидное? Как вы импортируете классы?