• Как организовать код в интерфейсы golang?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Интерфейс нужно будет указывать как параметр функций, которые будут уметь работать с вашим интрейфейсом.
    Например.
    func Process(device test123.Command) {
        device.Open()
        device.Close()
    }
    
    dev1 := a123.A123struct{параметры...}
    Process(dev1)
    
    dev2 := b123.B123struct{параметры...}
    Process(dev2)
    
    // или с перечислением
    devices := []test123.Command{dev1, dev2}
    for _, device := range devices {
        Process(device)
    }


    Приведу пример более похожий на реальный.
    Допустим нам нужно сделать логгер, который умеет писать в файл (если указан в настройках), а если не указан - тогда в консоль.
    Пример намеренно упрощён, чтобы было проще уловить суть.
    package main
    
    import (
        "fmt"
        "os"
    )
    
    // Logger интерфейс логгера.
    type Logger interface {
        Error(msg string)
    }
    
    // StdoutLogger реализация интерфейса Logger для вывода сообщений в консоль.
    type StdoutLogger struct{}
    
    // NewStdoutLogger конструктор (возвращаем структуру, не интерфейс)
    func NewStdoutLogger() *StdoutLogger {
        return &StdoutLogger{}
    }
    
    // Error добавляет в лог сообщение с уровнем error
    func (l *StdoutLogger) Error(msg string) {
        fmt.Printf("ERROR: %s\n", msg)
    }
    
    // FileLogger реализация интерфейса Logger для вывода сообщений в файл.
    type FileLogger struct {
        FileName string
        Fh       *os.File
    }
    
    // NewFileLogger конструктор.
    func NewFileLogger(fileName string) *FileLogger {
        logger := &FileLogger{
            FileName: fileName,
        }
        fh, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0664)
        if err != nil {
            panic(fmt.Sprintf("FileLogger: can't open log file: %s: %s\n", fileName, err))
        }
        logger.Fh = fh
    
        return logger
    }
    
    // Error добавляет в лог сообщение с уровнем error.
    func (l *FileLogger) Error(msg string) {
        l.Fh.WriteString(fmt.Sprintf("ERROR: %s\n", msg))
    }
    
    // ProcessData какая то функция, которая использует логгер и которую не должна беспокоить реализация логгера.
    // Тут тип параметра должен быть интерфейс.
    func ProcessData(logger Logger) {
        logger.Error("Data process some error happened")
    }
    
    func main() {
        var logger Logger
    
        // если лог файл не указан - используем StdoutLogger, если указан - используем FileLogger
        logFile := os.Getenv("LOG_FILE")
        if logFile != `` {
            logger = NewFileLogger(logFile)
        } else {
            logger = NewStdoutLogger()
        }
    
        ProcessData(logger)
    }

    После запуска go run main.go вы увидите сообщение в консоли:
    ERROR: Data process some error happened
    а если запустите вот так LOG_FILE=test.log go run main.go
    или
    export LOG_FILE=test.log
    go run main.go

    То будет создан файл test.log и туда будет добавлено тоже сообщение, что вы видели в консоли.

    Если понятнее не стало - пишите, будут рад помочь.
    Ответ написан