Если тип существует только для реализации интерфейса и никогда не будет экспортировать методы за пределами этого интерфейса, нет необходимости экспортировать сам тип. Экспорт только интерфейса дает понять, что значение не имеет какого-либо поведения сверх того, что описано в интерфейсе. Это также избавляет от необходимости повторять документацию на каждый случай общего метода.
В таких случаях конструктор должен возвращать значение интерфейса, а не тип реализации. Как пример, в хеш-библиотеках crc32.NewIEEE
и adler32.New
возвращают тип интерфейса hash.Hash32
. Подстановка алгоритма CRC-32 для Adler-32 в Go программе требует только изменения вызова конструктора; остальная часть кода не зависит от изменения алгоритма.
Подобный подход позволяет алгоритмам потокового шифра в различных пакетах crypto
быть отдельным от блочных шифров, которые они соединяют вместе. Интерфейс Block
в пакете crypto/cipher
указывает поведение блочного шифра, который обеспечивает шифрование одного блока данных. Затем по аналогии с пакетом bufio
, пакеты шифров, которые реализуют этот интерфейс, могут быть использованы для построения потоковых шифров, представленных через интерфейс Stream
, без знания деталей блока шифрования.
Интерфейсы crypto/cipher
выглядят так:
type Block interface {
BlockSize() int
Encrypt(src, dst []byte)
Decrypt(src, dst []byte)
}
type Stream interface {
XORKeyStream(dst, src []byte)
}
Вот определение потока в режиме счетчика (CTR), который превращает блочный шифр в потоковый шифр; отметьте что детали блочного шифра абстрагированы:
// NewCTR возвращает поток, который шифрует/дешифрует,
// используя данный блок в режиме счетчика.
// Длина iv должна соответствовать размеру блока.
func NewCTR(block Block, iv []byte) Stream
NewCTR
применяется не только для одного конкретного алгоритма шифрования и источника данных, но для любой реализация интерфейса Block
и любого Stream
. Потому что они возвращают значения интерфейса, замена CTR шифрование другими режимами шифрования является локализованным изменением. Вызовы конструктора должны быть отредактированы, но поскольку окружающий код должен обрабатывать результат только как Stream
, он не заметит разницы.
Читайте также:
Комментариев нет:
Отправить комментарий