PHP_CodeSniffer Много классов на файл

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

Например, у нас есть:

<?php
class FOO_EXCEPTION extends Exception   {   }
class FOO_EXCEPTION_BAR extends FOO_EXCEPTION   {   }
class FOO_EXCEPTION_POLE extends FOO_EXCEPTION  {   }

class FOO
{
    public function MethodDoingSomething()
    {
        if('some condition happens')    {
            throw new FOO_EXCEPTION_BAR();
        }

        if('some other condition')  {
            throw new FOO_EXCEPTION_POLE();
        }
        ...
    }
}
?>

Это позволяет нашему коду возвращать различные исключения, чтобы указать, что произошло с вызывающей стороной, но если выделенная функция try/catch недоступна, базовое исключение все равно может быть перехвачено.

Это удобно при работе с базами данных или другими внешними объектами, поскольку природа ошибки может быть возвращена компоненту, расположенному выше в стеке вызовов, для обработки ошибки.

Например, если вы удаляете файл, а этот файл не существует, код может сгенерировать исключение, но у вызывающей стороны есть возможность проигнорировать это, если он не обеспокоен тем, что файл не существует, поскольку он пытался все равно удаляй. Однако другой вызывающий объект может ошибиться из-за отсутствия файла, который должен был существовать на момент его удаления.


person Steven Scott    schedule 05.12.2012    source источник
comment
Если вы используете автозагрузчик, вам не нужно, чтобы классы Exception находились в одном файле; каждый может находиться в своем собственном файле, и его не нужно загружать (используя память PHP) до тех пор, пока он не будет фактически указан   -  person Mark Baker    schedule 06.12.2012
comment
Верно, но мы храним их вместе по логическим причинам, поскольку они определены в файле и ясно видны каждому разработчику для использования и для того, чтобы знать, что доступно для выбрасывания. Другая проблема заключается в том, как показано выше, что обычно исключение представляет собой не что иное, как определение, которое нужно перехватить, поэтому создание его во внешнем файле, который может быть загружен с помощью автозагрузки, также кажется немного излишним.   -  person Steven Scott    schedule 06.12.2012
comment
Вот где хорошая простая структура папок помогает: у вас есть файл класса Foo в вашей папке классов; затем папку Foo под той, где у вас есть файл класса Foo_Exception; и подпапка Exception под той, где у вас есть файлы классов Foo_Exception_Bar и Foo_Exception_Pole.... одинаково логично, и это легко читается   -  person Mark Baker    schedule 06.12.2012
comment
Я понимаю, куда вы идете. Это было бы довольно просто, хотя и много каталогов и очень коротких файлов. Больше всего я беспокоюсь о том, чтобы все наши разработчики следовали этому правилу и понимали, какие исключения создаются. Я предполагаю, что этот формат также хорошо работает для структур Namespace для PHP 5.3.   -  person Steven Scott    schedule 06.12.2012
comment
Много каталогов и коротких файлов; но если вы используете автозагрузчик и APC, это не оказывает отрицательного влияния на производительность (наоборот, обычно это намного лучше, потому что в память помещается только то, что действительно необходимо, и нет никаких накладных расходов на загрузку файла). дополнительные включения, которые не нужны). Самая большая проблема с переходом на подобную структуру — понимание структуры разработчиком; но он должен быть достаточно интуитивным   -  person Mark Baker    schedule 06.12.2012
comment
Возможно, это может быть что-то столь же простое, как использование вами CONSTANT_CASE вместо ClassCase для имени класса?   -  person meagar    schedule 07.01.2013


Ответы (1)


На мой взгляд, стандарт кодирования, который вы описываете в своем вопросе, вполне разумен. И я думаю, что для целей вашего проекта было бы лучше настроить снифф "стандартный несколько классов на файл", чтобы он работал с вашим кодом в этом конкретном (специальном) случае, а не тратить ваше время. настройка вашей кодовой базы, чтобы она соответствовала «букве закона» для этого конкретного сниффа.

Я согласен с утверждением, что лучше в целом не размещать несколько определений классов в одном файле. Но каждый аргумент, который я прочитал (до сих пор) в пользу перемещения каждого класса, производного от Exception, в отдельный файл, кажется мне призывом «улучшить» код, сделав его менее читаемым. Как человек, я не получаю никакой выгоды от сопровождения, загромождая свой код файлами, содержащими по одной строке каждый.

Это правда, что проще написать автозагрузчик, например, если каждый класс живет в своем файле. И если вы генерируете/компилируете свой PHP-код из какого-то метаязыка, вам ничего не стоит добавить дополнительные уровни в вашу структуру каталогов. Но я отвергаю вывод о том, что такой способ организации кода на самом деле делает его полезным для человека.

EDIT: Для записи я могу видеть, что было бы неплохо переместить определение класса, производного от Exception, в отдельный файл if strong> на самом деле он содержит некоторую «проверяемую» логику. В таких случаях вам может понадобиться имитировать/заглушить класс при написании автоматических тестов для логики, которая использует класс, что потребует от вас возможности загружать определение класса отдельно от логики, которая его использует. . Но это не ситуация, описанная в исходном вопросе, когда все классы, производные от Exception, "пусты".

person Peter    schedule 07.01.2013
comment
Спасибо. Мы используем исключения в верхней части ни по какой другой причине, кроме как просто для того, чтобы они выбрасывались, поскольку это кажется более ясным, чем все эти маленькие файлы, которые в основном ничего не делают. Основной класс должен быть включен, чтобы получить функциональность, поэтому он также автоматически добавляет исключения, без необходимости определять автозагрузчики и т. д. Мы согласны с тем, что это не делает код более удобным для сопровождения, и внутренне, это делает его менее таким. О внешнем файле можно забыть, не обновлять/не ссылаться на него и т. д. С почти 1 миллионом строк кода никто не может запомнить его целиком. - person Steven Scott; 07.01.2013
comment
Мы находимся в аналогичной ситуации, когда я работаю (несколько миллионов LOC с десятками тысяч файлов), и в настоящее время используем стандарт кодирования PHP для исключений, который очень похож на тот, который вы описываете в своем вопросе. - person Peter; 07.01.2013
comment
У вас есть нюх на это в настоящее время? Я хочу написать тот, в котором он будет следить за тем, чтобы у множественного класса было Exception в имени, а не защита от дурака, а то, что я пытаюсь. В настоящее время я написал обнюхивание (необходимо изменить для исключений) на основе имени файла, соответствующего имени класса. - person Steven Scott; 08.01.2013
comment
@StevenScott - в настоящее время я не использую какие-либо анализы для проверки нескольких классов в одном файле, поскольку мы (пока) не решили добавить какие-либо связанные правила в наш стандарт кодирования. Но было бы нетрудно написать его, реализовав интерфейс PHP_CodeSniffer_Sniff — вы можете использовать токены backet_opener и bracket_closer для T_OPEN_CURLY_BRACKET, чтобы проверить наличие пустого тела класса. Одна проблема: распознавание классов, которые расширяют производный от Exception класс, определенный в другом файле. Либо запретите это, либо потребуйте, чтобы классы, производные от Exception, имели имена, заканчивающиеся на «Exception». - person Peter; 10.01.2013
comment
Наши классы для Exception уже заканчиваются на Exception (стандарт кодирования, но для него нужно написать обнюхивание), а затем я собираюсь добавить обнюхивание в класс, поэтому пустой класс, который является исключением, должен быть расширен и заканчивается в виде исключения. Спасибо за помощь. - person Steven Scott; 15.01.2013