Лично я бы посоветовал вам размещать интерфейсы и исключения там, где они семантически приемлемы.Нет смысла складывать их все в одну папку от занятий.Но в то же время не ставьте их рядом с конкретными реализациями только ради этого.Я приведу пример.
Допустим, мы имеем дело со слоем абстракции базы данных.У вас будет интерфейс iDatabase
и интерфейс iDatabaseDriver
.Скажем, структура вашей папки (и класса) выглядит следующим образом:
/classes/database/idatabase.php
/classes/database/database.php
/classes/database/drivers/mysql/databasedrivermysql.php
/classes/database/drivers/postgres/databasedriverpostgres.php
Теперь есть 2 логических места для размещения iDatabaseDriver
.Вы можете поместить его в базу данных или под драйверы.Лично я бы поместил его в базу данных, поскольку он держится рядом с тем местом, где он необходим (поскольку более вероятно, что Database
требует iDatabaseDriver
, поэтому зависимость есть).
Итак, с этим,вы можете видеть, что иногда семантически целесообразно помещать интерфейс рядом с конкретной реализацией.Но в других случаях более целесообразно размещать интерфейс рядом с зависимостью, чем конкретные реализации.
Теперь этот пример является чрезмерным упрощением, но я думаю, что он должен понять суть.
Есть правила для именования и хранения интерфейсов
Придумайте систему организации кода.Таким образом, это более предсказуемо и проще для автозагрузки.Кроме того, становится намного легче поддерживать, когда вы можете сказать, где что-то должно быть по правилам
Соблюдать эти правила!
Это важнее, чем наличие правил.Если вы не следуете правилам, это хуже, чем вообще их не иметь, поскольку вы ожидаете чего-то, что не произойдет.
Любите семантические отношения по отношению к уровням кода
Семантические отношения между интерфейсом и его конкретными реализациями важнее, чем отношения, которые интерфейс представляет собой интерфейс.Поэтому поместите семантически связанный код в те же (или похожие) места.
Редактировать: Относительно именования и вашего редактирования:
Лично я ненавижутакие вещи, как Database_Database
.Хотя это может иметь смысл с учетом структуры приложения, оно не имеет никакого смыслового смысла.Вместо этого мне нравится проверять наличие файла в автозагрузчике, и, если он не существует, но каталог существует, проверять наличие того же файла внутри этого каталога.Таким образом, Database
приведет к проверке /database.php
, а в случае неудачи /database/database.php
.Это устраняет необходимость двойного именования.Database_DatabaseAbstract
станет Database_Abstract
.Таким образом, ваш Database_Mysql_Database
может стать Database_Mysql
сохраненным в /database/mysql/mysql.php
(что мне кажется более чистым).
Насколько ваше соглашение об именах абстрактных классов и тому подобное, я личнопредпочитаю идентифицировать интерфейсы по имени.Это облегчает понимание с первого взгляда (Вы знаете, что public function foo(iDatabase $database)
ищет экземпляр интерфейса вместо абстрактного класса или конкретного класса).Теперь есть два реальных способа сделать это.
Добавьте Interface
к имени, поэтому Database_Database
станет Database_Interface
.Лично я считаю, что это слишком многословно для моих нужд, однако выгода в том, что все ваши специальные типы классов (исключения, интерфейсы, итераторы и т. Д.) Могут просто отображаться следующим образом.Имя класса говорит вам точно, что у вас есть, без какой-либо двусмысленности.
Добавьте всю последовательность с помощью i
.Таким образом, Database_Database
станет iDatabase
, который затем будет переведен в автозагрузчик в /database/interface.php
.Тогда, если бы у вас были более глубокие интерфейсы, iDatabase_Mysql_Query
также мог бы работать (что соответствовало бы /database/mysql/query/interface.php
.
Что касается абстрактного класса, я бы этого не сделал.Тот факт, что класс является абстрактным, на самом деле не должен иметь ничего общего с его семантическим значением.Абстрактная природа является конструкцией кодирования, а не семантической (абстрактный класс используется только для наследования, поскольку вы используете интерфейс для проверки типов)Поэтому я бы не рекомендовал включать Abstract
в название класса.Просто назовите это Database
и все будет готово.Он лучше читается семантически (ИМХО) и передает то же значение.
Я надеюсь, что это помогает и имеет смысл ...