Embora o Golang não implemente orientação a objetos, de forma superficial, sua estratégia de embedding – que inclusive é muito utilizada nos packages nativos da linguagem – é muito parecida com a famosa herança.
Nesse post, vou mostrar como utilizar essa estratégia para que possamos ter interfaces mais granulares.
Antes de começar, como o objetivo desse post é exemplificar como utilizar embedding em interfaces, não vamos implementar os métodos. Também não vamos mostrar como utilizá-las em assinaturas de funções/métodos. Caso você queria saber mais sobre como utilizar interfaces, recomendo a leitura do post “Trabalhando com Interfaces”.
Sem mais delongas, vamos criar 3 interfaces. Writer, Reader e Closer.
type Writer interface { Write(p []byte) (n int, err error) } type Reader interface { Read(p []byte) (n int, err error) } type Closer interface { Close() error }
Com essas 3 interfaces criadas, já podemos criar funções e métodos que esperem structs que implementem uma dessas interfaces.
Agora, e se em determinado método eu precisar de uma struct que implemente o método Write
e o método Read
? Como não podemos definir 2 tipos – afinal nem faria sentido fazer isso – para um mesmo parâmetro da função, só nos resta utilizar a estratégia de embedding.
Embedding
Para resolver o problema citado acima, e reaproveitar as interfaces que já foram declaradas, vamos criar uma nova interface que faça o embedding das interfaces Writer e Reader.
type ReadWriter interface { Reader Writer }
Dessa forma, podemos criar funções que esperem structs que implementem, obrigatoriamente, os métodos Write
e Read
.
Para ter o máximo de possibilidades, embora não seja um regra, podemos criar as interfaces ReadWriteCloser, ReadCloser e WriteCloser.
type ReadWriteCloser interface { Reader Writer Closer } type ReadCloser interface { Reader Closer } type WriteCloser interface { Writer Closer }
É claro que não faz muito sentido criar interfaces que nunca serão utilizadas. Por isso, sempre que você for criar interfaces, recomendo que avalie o software como um todo. Dessa forma você evitará ter interfaces completamente ou parcialmente duplicadas.
Os exemplos foram simples e baseados no package io, que é um package nativo ****da linguagem Go.
Espero que esse post possa te ajudar a pensar em como organizar as interfaces do seu software.
Dúvidas, é só deixar um comentário.
Até a próxima!