Что это такое
Паттерн Strategy делает алгоритм заменяемым: окружающий код остаётся прежним, а взаимозаменяемая часть — как считать цену, как сортировать, как сжимать — подставляется как значение.
Именно этот паттерн Go упрощает сильнее всего: поскольку функции здесь являются значениями, стратегия часто оказывается просто типом-функцией. Ни интерфейса, ни структуры — присваиваете другую функцию, и поведение меняется.
Пример: заменяемый расчёт цены
Checkout не меняется никогда; правило расчёта цены — это значение-функция в поле структуры. Обычная цена, Black Friday, скидка участника клуба — три функции, один магазин.
Стратегия — это значение-функция
Три оформления заказа с одной и той же суммой 50 дают три разных итога — различается только присвоенная функция. Точно так же сортирует стандартная библиотека: вы передаёте ей стратегию сравнения.
Вывод: программа на Go и захваченный вывод
package main
import "fmt"
// В Go стратегия — это просто значение-функция.
type Pricing func(price float64) float64
func Regular(p float64) float64 { return p }
func BlackFriday(p float64) float64 { return p * 0.7 }
func Member(p float64) float64 { return p - 5 }
type Shop struct {
pricing Pricing
}
func (s Shop) Checkout(price float64) {
fmt.Printf("итого: %.2f\n", s.pricing(price))
}
func main() {
shop := Shop{pricing: Regular}
shop.Checkout(50)
shop.pricing = BlackFriday
shop.Checkout(50)
shop.pricing = Member
shop.Checkout(50)
}
Когда его использовать
Используйте его всякий раз, когда алгоритм меняется, а его окружение — нет: правила расчёта цены, политики повторных попыток, порядки сортировки, режимы проверки данных.
Не используйте его, когда алгоритм один и второй реально не предвидится. Вариант с интерфейсом вместо функции применяйте только тогда, когда стратегии нужно собственное состояние или несколько методов.
Плюсы и минусы
Плюсы: поведение подменяется во время выполнения; каждая стратегия мала и тестируется отдельно; в Go это стоит почти ничего — тип-функция и присваивание.
Минусы: выбранная стратегия не видна в месте вызова — отладка превращается в поиск того, что было присвоено; слишком большое число микростратегий дробит простую логику.