Суффикс для интерфейсов

Обсуждаем разработку фреймворка: дизайн компонентов, API, пакеты

Какое именование интерфейсов вам нравится больше?

NameInterface. С суффиксом
27
90%
Без суффикса
3
10%
 
Всего голосов: 30

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Суффикс для интерфейсов

Сообщение samdark » 2019.07.04, 19:52

В Yii 1.1 интерфейсы именовались как `IName`. В Yii 2 используется `NameInterface`. В Yii 3 я попробовал убрать суффикс. Получились имена вроде ErrorRenderer.

Что вы думаете на эту тему?

Аватара пользователя
chungachguk
Сообщения: 426
Зарегистрирован: 2012.07.17, 11:52

Re: Суффикс для интерфейсов

Сообщение chungachguk » 2019.07.04, 20:05

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

Loveorigami
Сообщения: 974
Зарегистрирован: 2014.08.27, 21:54

Re: Суффикс для интерфейсов

Сообщение Loveorigami » 2019.07.04, 21:19

Дело привычки, но я за суффикс.

Иначе:
ErrorRenderer implements ErrorRenderer
ErrorException implements ErrorException
и тд...
Где интерфейс, а где класс?

-----------

1. ErrorRenderer implements ErrorRendererInterface
в шторме легче найти или класс, или интерфейс.

2. psr именует как LoggerInterface

https://github.com/php-fig/log/tree/master/Psr/Log
Последний раз редактировалось Loveorigami 2019.07.09, 22:49, всего редактировалось 1 раз.

Аватара пользователя
chungachguk
Сообщения: 426
Зарегистрирован: 2012.07.17, 11:52

Re: Суффикс для интерфейсов

Сообщение chungachguk » 2019.07.05, 06:34

Loveorigami писал(а):
2019.07.04, 21:19
Дело привычки, но я за префикс.

Иначе:

ErrorRenderer implements ErrorRenderer

Где интерфейс, а где класс?
К примеру здесь интерфейс можно было назвать Renderable и сделать класс его реализующий ErrorRenderer. По-большому счёту, интерфейс это просто маркер, указывающий, что в данном классе есть какая-то функциональность. К тому же один класс необязательно должен реализовывать только один интерфейс, может и десяток реализаций в себе иметь, и в своём именовании не должен быть зависим от названия интерфейса.

dimsog
Сообщения: 7
Зарегистрирован: 2019.07.02, 12:29

Re: Суффикс для интерфейсов

Сообщение dimsog » 2019.07.05, 09:22

Понятное дело, что во всех книгах говорят используйте *able, Runnable, Throwable и так далее. Но RequestInterface, DataObjectInterface и так далее. Я за Interface на конце.

Аватара пользователя
NeverDie
Сообщения: 69
Зарегистрирован: 2012.05.13, 04:05
Откуда: Минск
Контактная информация:

Re: Суффикс для интерфейсов

Сообщение NeverDie » 2019.07.05, 12:56

Я тоже за суффикс. А если без, то как же psr?
https://www.php-fig.org/bylaws/psr-naming-conventions/

Аватара пользователя
BrusSENS
Сообщения: 565
Зарегистрирован: 2012.07.26, 06:51
Откуда: Новороссийск
Контактная информация:

Re: Суффикс для интерфейсов

Сообщение BrusSENS » 2019.07.05, 13:25

Я тоже не понимаю, как может быть без суффикса, если 3 мажор следует PSR
Native Web - небольшой блог о веб разработке (временно на ремонте)
Режим обслуживания сайта для Yii 2.x.x

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Суффикс для интерфейсов

Сообщение samdark » 2019.07.05, 14:39

Ссылка выше не на стиль кода для внешних проектов, а на внутренний документ PHP-FIG, стандартизирующий именование в рамках самих PSR-документов.

Loveorigami
Сообщения: 974
Зарегистрирован: 2014.08.27, 21:54

Re: Суффикс для интерфейсов

Сообщение Loveorigami » 2019.07.05, 15:20

samdark писал(а):
2019.07.05, 14:39
Ссылка выше не на стиль кода для внешних проектов, а на внутренний документ PHP-FIG, стандартизирующий именование в рамках самих PSR-документов.
... коими потом будут пользоваться во всех PSR совместимых пакетах

https://github.com/php-fig/log/blob/mas ... erface.php

Вы же Yii3 для чего на пакеты разнесли? Чтоб никто не мог понять, что там внутри? ;)

Через пол-года эдак напишите (не заходя внутрь), что из этого интерфейс https://github.com/yiisoft/yii-web/tree ... rorHandler
Не говоря уже о тех, кто видит это впервые.

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Суффикс для интерфейсов

Сообщение samdark » 2019.07.05, 17:32

Итого пока будем с суффиксом: https://github.com/yiisoft/docs/blob/ma ... erfaces.md

Решение до релиза можно поменять.

skynin
Сообщения: 193
Зарегистрирован: 2017.12.12, 10:09

Re: Суффикс для интерфейсов

Сообщение skynin » 2019.07.07, 14:41

часто
В мире Java
интерфейс
SomeEntity
реализация
SomeEntityImpl // метят суффиксом реализацию

В C#
интерфейс
ISomeEntity // метят префиксом интерфейс
реализация
SomeEntity

-- интерфейс это просто маркер, указывающий
так то оно так...

но, приходится читать в коде
instanceof SomeEntity

и гадать, если одинаковые названия
так что проверяем то - класс или интерфейс?

тот же вопрос с указанием типа в параметрах метода
скролить вверх, смотреть какой use?

Итого:
1. названия интерфейса и класса реализации должны отличаться
2. для автокомлита в IDE удобней префикс, а не суффикс
3. Но раз написано Interfaces MUST be suffixed by Interface: e.g. Psr\Foo\BarInterface то и ладно, пункт 1 соблюден
Неврубающийся не может опознать врубающегося.

Nex-Otaku
Сообщения: 825
Зарегистрирован: 2016.07.09, 21:07

Re: Суффикс для интерфейсов

Сообщение Nex-Otaku » 2019.07.08, 12:26

1. Предлагаю убрать требование суффикса "Interface" для интерфейсов из соглашения.

2. Считаю, что этот суффикс только уродует и захламляет код. Повторение бесполезной информации в коде, затрудняет его чтение.

3. С суффиксом "Interface" усложняется рефакторинг.

Например, у нас есть компонент Cache, который используется в 500 классов системы через внедрение зависимостей. Подключается конкретный класс Cache.

Допустим, нам понадобилось реализовать новый вид кеширования. Был файловый кеш, а мы решили сделать ещё кеш в памяти, для быстрого запуска тестов.

Без суффикса, нам пришлось бы изменить только один файл - Cache. Заменив в нём ключевое слово "class" на "interface", и написав две реализации этого интерфейса, мы успешно решаем задачу.

С суффиксами, к этим действиям прибавляется переименование класса и соответственно изменение 500 связанных с ним классов.

4. Откуда взялось требование суффикса интерфейса в соглашении?

Я уверен, что такое требование перешло в соглашение из невнимательного прочтения соглашения PSR: https://www.php-fig.org/bylaws/psr-naming-conventions/

Если приглядеться внимательнее, станет ясно, что этот стандарт описывает не стандарт для кодирования, а стандарт написания самих текстов PSR. То есть это стиль документации, а не стандарт кода.

Видимо, разработчика соглашения ввёл в заблуждение заголовок "PSR Naming Conventions", и стиль не глядя был скопирован в соглашения кода.

5. В списке актуальных стандартов, разумеется, этого нет. Ни один из действующих и ни один из устаревших стандартов PSR не предлагает использовать суффиксы для интерфейсов.
См. https://www.php-fig.org/psr/

Nex-Otaku
Сообщения: 825
Зарегистрирован: 2016.07.09, 21:07

Re: Суффикс для интерфейсов

Сообщение Nex-Otaku » 2019.07.08, 12:34

skynin писал(а):
2019.07.07, 14:41
но, приходится читать в коде
instanceof SomeEntity

и гадать, если одинаковые названия
так что проверяем то - класс или интерфейс?
Зачем гадать? Какая разница, что там? Какое это может иметь значение? Можешь описать ситуацию, в которой твои дальнейшие после "гаданий" действия различаются, в зависимости от того, класс это или интерфейс?
skynin писал(а):
2019.07.07, 14:41
тот же вопрос с указанием типа в параметрах метода
скролить вверх, смотреть какой use?
Тот же вопрос. Какое дело разработчику, класс обозначается или интерфейс? Ему важно лишь, что тип объекта соответствует ожидаемому. Есть такой-то тип, он даёт нам возможность пользоваться такими-то методами и ожидать такого-то поведения. Согласованная абстракция.
skynin писал(а):
2019.07.07, 14:41
3. Но раз написано Interfaces MUST be suffixed by Interface: e.g. Psr\Foo\BarInterface то и ладно, пункт 1 соблюден
Это написано в PSR для стиля ДОКУМЕНТАЦИИ, а не кода. К сожалению, немногие видят различие, как и показывают комментарии в этом топике.

Nex-Otaku
Сообщения: 825
Зарегистрирован: 2016.07.09, 21:07

Re: Суффикс для интерфейсов

Сообщение Nex-Otaku » 2019.07.08, 12:48

Loveorigami писал(а):
2019.07.04, 21:19
Дело привычки, но я за префикс.

Иначе:
ErrorRenderer implements ErrorRenderer
ErrorException implements ErrorException
и тд...
Где интерфейс, а где класс?
Если интерфейс описывает общую для нескольких классов абстракцию, то это будет выглядеть так:

Код: Выделить всё

interface Renderer { public function render():string; }

class ErrorRenderer implements Renderer {}

class HtmlRenderer implements Renderer {}


class AccessDenied implements AppException {}

class FileNotFound implements AppException {}
Если же для каждого интерфейса существует только один класс, то интерфейс в этом случае и не нужен. Достаточно указывать класс.

Loveorigami
Сообщения: 974
Зарегистрирован: 2014.08.27, 21:54

Re: Суффикс для интерфейсов

Сообщение Loveorigami » 2019.07.08, 19:39

Nex-Otaku писал(а):
2019.07.08, 12:26

3. С суффиксом "Interface" усложняется рефакторинг.

Например, у нас есть компонент Cache, который используется в 500 классов системы через внедрение зависимостей. Подключается конкретный класс Cache.
Думаю, не стоит приводить частные случаи и делать обобщающие выводы.

1. Что мешало изначально сделать через интерфейс?
2. Когда я открываю DI - с префиксом я вижу, где у меня класс, а где у меня интерфейс.

Код: Выделить всё

$container->set('app\cache\CacheInterface', 'app\cache\FileCache');
легко меняю

Код: Выделить всё

$container->set('app\cache\CacheInterface', 'app\cache\RedisCache');
В вашем DI будет список классов, непонятно как сконфигурированных (то ли класс, то ли интерфейс). Если я и запомню как-то это все, то каждому новому человеку в команде нужно будет дополнительно все это изучать...

Опять же повторюсь, откройте пакет https://github.com/php-fig/log/tree/master/Psr/Log, мысленно уберите там суффикс Interface. И попробуйте теперь написать свою реализацию логера. А если не известно, где лежит класс и нужно в шторме найти. Набрав LoggerI...я уже его найду. А если искать Logger (по вашему без суффикса) - мне в выдачу попадут все вперемешку - и интерфейсы, и классы...

Так что я за суффикс, однозначно. Я лучше переименую 500 классов за пару сек в шторме, зато это избавит меня от последующих трат времени при разработке.
Последний раз редактировалось Loveorigami 2019.07.09, 22:51, всего редактировалось 1 раз.

Nex-Otaku
Сообщения: 825
Зарегистрирован: 2016.07.09, 21:07

Re: Суффикс для интерфейсов

Сообщение Nex-Otaku » 2019.07.09, 16:37

Loveorigami писал(а):
2019.07.08, 19:39
1. Что мешало изначально сделать через интерфейс?
KISS - Keep It Simple, Stupid.

Пока реализация одна, интерфейс не нужен. Если вы конечно не Ванга, которая предвидит все будущие изменения кода на месяцы вперёд.

Как только понадобилась вторая реализация - впору и интерфейс создать, если это опять же уместно.

Ну а если вы на всё и вся заранее плодите интерфейсы, то вы замусориваете свой проект.
Loveorigami писал(а):
2019.07.08, 19:39
2. Когда я открываю DI - с префиксом я вижу, где у меня класс, а где у меня интерфейс.

Код: Выделить всё

$container->set('app\cache\CacheInterface', 'app\cache\FileCache');
легко меняю

Код: Выделить всё

$container->set('app\cache\CacheInterface', 'app\cache\RedisCache');
В настройках контейнера в такой строке может быть только интерфейс, иначе это весьма странное переопределение классов, попахивающее "костылями". Вы часто так делаете?
Loveorigami писал(а):
2019.07.08, 19:39
В вашем DI будет список классов, непонятно как сконфигурированных (то ли класс, то ли интерфейс). Если я и запомню как-то это все, то каждому новому человеку в команде нужно будет дополнительно все это изучать...
Если код Yii плохо читается, то это решается простой обёрткой. Сделайте свой метод, и используйте его.

Код: Выделить всё

$this->setImplementation('app\cache\Cache', 'app\cache\FileCache')
Loveorigami писал(а):
2019.07.08, 19:39
Опять же повторюсь, откройте пакет ...
Именование классов в фреймворке должно зависеть от произвольных сторонних пакетов? Или оно должно быть самостоятельным?
Вы код своего проекта тоже делаете максимально зависимым от используемых библиотек и фреймворков?

Nex-Otaku
Сообщения: 825
Зарегистрирован: 2016.07.09, 21:07

Re: Суффикс для интерфейсов

Сообщение Nex-Otaku » 2019.07.09, 16:43

Чтобы использование суффикса было осмысленным, этот суффикс должен давать дополнительную ПОЛЕЗНУЮ информацию разработчику, читающему код.

Информация полезна только тогда, когда она влияет на решения. Если читая "ага, это интерфейс", я принимаю другое решение, чем прочитав "ага, это класс", то это и есть польза. Вы можете такой пример привести, реалистичный? Попробуйте.

Если не можете - значит, эта информация только кажется вам полезной, а на самом деле такой не является.

Аватара пользователя
chungachguk
Сообщения: 426
Зарегистрирован: 2012.07.17, 11:52

Re: Суффикс для интерфейсов

Сообщение chungachguk » 2019.07.09, 18:35

skynin писал(а):
2019.07.07, 14:41
часто
В мире Java
интерфейс
SomeEntity
реализация
SomeEntityImpl // метят суффиксом реализацию

В C#
интерфейс
ISomeEntity // метят префиксом интерфейс
реализация
SomeEntity
Кстати говоря, а как с этим обстоит дело в PHP? Может стоит от этого и отталкиваться?

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Суффикс для интерфейсов

Сообщение samdark » 2019.07.09, 20:21

В PHP большинство суффиксит Interface.

Loveorigami
Сообщения: 974
Зарегистрирован: 2014.08.27, 21:54

Re: Суффикс для интерфейсов

Сообщение Loveorigami » 2019.07.09, 20:49

Речь шла про компонент кеша. Для которого уже есть PSR. Мы обсуждаем Yii3-пакет, а не Yii2-монолит.
Именование классов в фреймворке должно зависеть от произвольных сторонних пакетов?
1. Отвечать вопросом на вопрос - это не конструктивная дискуссия.

2. Не просто фреймворк, a PSR совместимый
https://github.com/yiisoft/docs/blob/ma ... roadmap.md

3. Эти же пакеты потом будут использовать в других проектах, и даже не Yii-разработчики. Симфони в пример.

4. Откройте любой компонент в Симфони. Первый попавшийся - https://packagist.org/packages/symfony/console (147 915 885 установок)
- открываем любой класс https://github.com/symfony/console/blob ... Logger.php
- что мы видим в use ?
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
5. Тоже для Slim - https://github.com/slimphp/Slim/tree/3. ... Interfaces

6. В laravel - там все структурировано монолитом. https://github.com/laravel/framework/tr ... /Contracts
Да, без префикса, но все интерфейсы в одном месте. Но это не путь для Yii3.

А то что вне - use Illuminate\Database\ConnectionResolverInterface - в общем, поизучайте https://github.com/laravel/framework/se ... =Interface

7. Навскидку, пару библиотек
- Doctrine https://github.com/doctrine/orm/tree/ma ... ctrine/ORM
- Guzzle https://github.com/guzzle/guzzle/tree/master/src
- Flysystem https://github.com/thephpleague/flysyst ... master/src

8. В самом PHP - https://www.php.net/manual/en/class.dat ... erface.php и др.

9. Любой принятый PSR - https://github.com/php-fig/fig-standard ... r/accepted

https://github.com/php-fig/fig-standard ... e-cache.md

Т.е. почему, если уже выработано некое негласное правило среди программистов по интерфейсам, мы должны стоять особняком только потому, что так "проще рефакторить" отдельно взятому программисту. Но рефакторить - не только поменять имя, но и переместить в другую папку. В таком случае Ваш выше упомянутый класс разве не потребует 500 изменений в других файлах? Так что Ваши аргументы меня не убедили.
Если код Yii плохо читается, то это решается простой обёрткой. Сделайте свой метод, и используйте его.
Для меня плохочитающимся кодом является такой (вопрос, на который Вы не ответили)

Код: Выделить всё

use Google\Auth\CacheTrait;
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\Subscriber;
use Psr\Cache\CacheItemPool;
и хорошо читающимся

Код: Выделить всё

use Google\Auth\CacheTrait;
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use Psr\Cache\CacheItemPoolInterface;
https://github.com/googleapis/google-au ... criber.php

И далее код я могу не смотреть уже...
Информация полезна только тогда, когда она влияет на решения. Если читая "ага, это интерфейс", я принимаю другое решение, чем прочитав "ага, это класс", то это и есть польза. Вы можете такой пример привести, реалистичный? Попробуйте.
пожалуйста

Не открывая каждый класс, я уже вижу, что последних два я могу в DI заменить на свои реализации.

Не просто кеш, а CacheItemPoolInterface - а дальше я уже смотрю в DI, а какой кеш у меня в системе. А если у данного пакета нет нужной мне реализации

https://github.com/PHPixie/Cache/tree/m ... ivers/Type

Идем на пакажист и выбираем, что нравится

https://packagist.org/packages/psr/cach ... nts?page=1

https://packagist.org/packages/zendframework/zend-cache

https://github.com/zendframework/zend-c ... ge/Adapter

Или настраиваем, или смотрим пример и пишем (копируем) к себе в проект нужный адаптер.

Ответить