Я посетил GopherCon UK 2019 в Лондоне. Одной из вещей, которые привлекли мое внимание, были функциональные параметры.

Обычно, когда вы разрабатываете приложение или службу, существует множество параметров конфигурации, которые вам нужно передать вашему приложению при его вызове. Традиционно у вас будет конфигурация struct, которую вы передаете. Функциональные опции — это альтернативный и более элегантный способ настройки вашего приложения.

Сначала я продемонстрирую традиционный подход:

Скажем, у меня есть сервер, как показано ниже:

type Server struct {
 Addr     string
 Port     int
 Name     string
 Setting1 string
 Setting2 bool
}

Чтобы настроить этот Server, нам нужна структура Config, например:

type Config struct {
 Addr     string
 Port     int
 Name     string
 Setting1 string
 Setting2 bool
}

Типичный вызов Server выглядит следующим образом:

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

Это переносит на вызывающую сторону ответственность за правильное использование Server. Однако это приводит к неустойчивому использованию, особенно если количество настраиваемых параметров велико и когда вызывающий абонент не знает, что они все означают.

Теперь позвольте мне продемонстрировать настройку сервера с использованием функциональных опций. Сначала я покажу вам реализацию:

Вы можете видеть, что вызов Server стал намного понятнее. Все, что не передается явно, использует значение по умолчанию.

Ключом к этой работе является функция NewServerBetter — это функция с переменным числом. Он получает переменное количество функций, каждая из которых возвращает замыкание. NewServerBetter просматривает вариативный список и выполняет каждую функцию по очереди. Каждая из этих функций берет один и тот же экземпляр Сервера и изменяет его конфигурацию. Элегантный.

Функциональные опции приводят к лучшему дизайну пакетов/приложений. Я буду включать функциональные опции в свои проекты Go.

Если вы хотите узнать больше о функциональных опциях, ознакомьтесь с этими основополагающими статьями Дэйва Чейни и Роба Пайка.