Правило для имени интерфейса GoLang и его количества методов

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

Давайте посмотрим на пример. В стандартной библиотеке Go lang есть Pusher Интерфейс, который выполняет одно действие: "Push инициирует HTTP/2-серверный push". Вот его определение:

type Pusher interface {
  Push(target string, opts *PushOptions) error
}

https://golang.org/pkg/net/http/

Хороший пример. Тем не менее, некоторые коллеги защитили его реализацию, которая содержала более двух методов с er в постфиксе имени. Основным аргументом было то, что есть интерфейсы stdlib, которые нарушают такое правило. Он сослался на интерфейс ReadCloser,

Глядя на его определение:

type ReadCloser interface {
        Reader
        Closer
}

https://golang.org/pkg/io/

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

Как вы будете интерпретировать такой случай?

1 ответ

Решение

Этот вопрос, возможно, будет закрыт, потому что он считается основанным на мнении, или не связан с кодом, или как там...

Тем не менее, Голанг считается весьма самоуверенным, и, поскольку я считаю стандарты очень важными, я буду придерживаться своего взгляда на неписаное правило и на то, как я примирю, по сути, почему ReadCloser хорошо, но некоторые другие er интерфейсов может не быть.


Я бы истолковал ReadCloser не нарушать "правило" (я бы назвал это соглашением больше похожим). У меня есть ряд аргументов, почему я бы сказал, что это не нарушает соглашение:

1. Это не автономный интерфейс

ReadCloser Интерфейс не является автономным интерфейсом. Это сложный интерфейс. Это имя отражает это. Объединяет Read а также Close (2 функции в интерфейсе, который вы ищете), и добавляет er суффикс. То, как реализованы обе функции и откуда они берутся, не имеет отношения к интерфейсу. Если вы что-то прочитали, скорее всего, вам тоже придется закрыть ресурс. Имеет смысл только объединить два интерфейса, так что вы можете использовать тип, который гарантирует оба Reader а также Closer функциональность будет доступна.

2. Имена не должны заикаться

Как и в случае с заиканиями в названиях пакетов WRT, их следует избегать. Особенно, если это не добавляет никакой ценности. Технически можно утверждать, что интерфейс должен называться ReaderCloser, но означает ли это имя что-либо, что не передается именем ReadCloser? Конечно нет. Последний не повторяет суффикс и читается легче.

3. er интерфейсы и CamelCasing

Примеры однофункциональных er интерфейсы как Stringer, или же Publisher действительно порезанный и сухой. Stringer содержит String функция. Конец истории. Такой же как Publisher интерфейс.

Вы заметите, что ReadCloser интерфейс CamelCased, предполагая, что это композитный тип. Просто разделите имя на символы UpperCase и добавьте суффикс к каждой части. Если части добросовестны er интерфейсы, и составной интерфейс имеет смысл (см. пункт 1: если вы читаете, скорее всего, вам придется закрыть), то это допустимый составной интерфейс.

Примеры недействительных er Интерфейс будет:

type FileReader interface {
    ReadCloserer
    ScanDir(string) ([]string, error)
    IsFile(string) bool
    Open(string, string) error
    // and so on
}

Этот интерфейс содержит слишком много функций BS для упаковки в FileReader интерфейс.

Другие вопросы по тегам