Именование интерфейсов/абстрактных классов в PHP 5.3 (с использованием пространств имен)
До PHP 5.3 я называл интерфейсы/абстрактные классы следующим образом:
abstract class Framework_Package_Subpackage_Abstract {}
Framework/Package/Subpackage/Abstract.php
interface Framework_Package_Subpackage_Interface {}
Framework/Package/Subpackage/Interface.php
Теперь с PHP 5.3 и с использованием пространств имен я больше не могу использовать свое соглашение, потому что interface
и abstract
являются зарезервированными ключевыми словами.
namespace Framework\Package\Subpackage;
abstract class Abstract {}
Framework/Package/Subpackage/Abstract.php
namespace Framework\Package\Subpackage;
interface Interface {}
Framework/Package/Subpackage/Interface.php
Итак, что я должен назвать моими классами/интерфейсами, например?
Ответы
Ответ 1
В текущем руководстве по кодированию "PSR-2" в основном предлагается отказаться от интерфейса по одному каталогу и объединить имя.
например:
File \Vendor\Foo\Interface.php ===> \Vendor\FooInterface.php.
и использование элемента, например:
use \Vendor\Foo\Interface; ===> use\Vendor\FooInterface;
см. ниже: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
Ответ 2
Об этом вопросе (Аннотация и интерфейс) вы можете взглянуть на сообщение " Миграция библиотек и фреймворков OOP в PHP 5.3" on Блог Мэтью Вейера O'Phinney - о Zend Framework и о том, как они могут решить эту проблему в версии 2.0.
Одна из замечаний:
На других языках ООП, таких как Интерфейсы Python, С#, обозначаются префикс интерфейса с капиталом 'Я'; в приведенном выше примере мы затем Zend:: View:: IView.
Итак, в вашем примере у вас будет что-то вроде этого, я думаю:
namespace Framework\Package\Subpackage;
abstract class ASubpackage {}
Framework/Package/Subpackage/ASubpackage.php
namespace Framework\Package\Subpackage;
interface ISubpackage {}
Framework/Package/Subpackage/ISubpackage.php
Что вы думаете об этом?
(Я не тестировал этот путь, но это не похоже на плохую идею?)
Ответ 3
SubpackageAbstract,
SubpackageInterface
Ответ 4
Я лично рекомендовал бы избежать использования венгерской нотации и рассмотреть следующий стандарт Java для имен интерфейсов; то есть они называются дескриптивно так же, как и любой другой класс. См. этот вопрос SO для обсуждения входов и выходов венгерской нотации.
Хороший пример использования общих описательных имен, указывающих на функциональность или поведение, можно найти в собственном SPL PHP, например: "Countable", "Iterator", "ArrayObject".
Ответ 5
Вы также можете сделать что-то вроде этого:
ЦСИ/Шахматы/Piece.php
<?php
namespace \Chess;
abstract class Piece implements \Chess\PieceInterface {}
ЦСИ/Шахматы/PieceInterface.php:
<?php
namespace \Chess;
interface PieceInterface {}
ЦСИ/Шахматы/шт/Pawn.php:
<?php
namespace \Chess\Piece;
class Pawn extends \Chess\Piece {}
Здесь, как бы настроить автозагрузку в composer.json
{
"autoload": {
"psr-0": {
"": "src/"
}
}
}
Ответ 6
Честно говоря, я считаю, что венгерская нотация была введена с С#, потому что ключевое слово "расширяет" и "реализует", как на Java, отсутствует. Таким образом, чтобы разграничить конвенцию, стало называть ее IView. В Java интерфейс будет называться View alone, а реализации будут называться DefaultViewImpl, SmartyViewImpl или что-то в этом роде. Поскольку PHP имеет расширения и реализует ключевые слова, имеет смысл использовать соглашение Java.
Я слышал аргумент о том, что венгерская нотация делает это сам, чтобы идентифицировать элементы API, просто взглянув на имена классов. В этом случае я бы назвал это либо IView, либо AbstractView.
Ответ 7
На мой взгляд, лучший способ решить это - просто добавить класс к вашим именам классов.
namespace Framework\Package\Subpackage;
abstract class AbstractClass {}
Framework/Package/Subpackage/AbstractClass.php
namespace Framework\Package\Subpackage;
interface InterfaceClass {}
Framework/Package/Subpackage/InterfaceClass.php
Обратите внимание, что это все еще не идеально (однако работает отлично), но я сохраняю код похожим на оригинальную идею;)