Ответ
Strategy (Стратегия) — это поведенческий паттерн, который определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Он позволяет изменять алгоритм независимо от клиента, который его использует.
Проблема: Класс содержит множество условных операторов (if/switch), которые выбирают один из многих вариантов поведения.
Решение: Вынести каждое поведение в отдельный класс и сделать их взаимозаменяемыми.
Пример на Swift (Сортировка):
// 1. Интерфейс Стратегии
protocol SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T]
}
// 2. Конкретные стратегии
class BubbleSortStrategy: SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T] {
var result = array
for i in 0..<result.count {
for j in 1..<result.count - i {
if result[j] < result[j-1] {
result.swapAt(j, j-1)
}
}
}
return result
}
}
class QuickSortStrategy: SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T] {
guard array.count > 1 else { return array }
let pivot = array[array.count/2]
let less = array.filter { $0 < pivot }
let equal = array.filter { $0 == pivot }
let greater = array.filter { $0 > pivot }
return sort(less) + equal + sort(greater)
}
}
// 3. Контекст, использующий стратегию
class Sorter {
private var strategy: SortStrategy
init(strategy: SortStrategy) {
self.strategy = strategy
}
func setStrategy(_ strategy: SortStrategy) {
self.strategy = strategy
}
func performSort<T: Comparable>(on array: [T]) -> [T] {
return strategy.sort(array)
}
}
// 4. Использование
let numbers = [64, 34, 25, 12, 22, 11, 90]
let sorter = Sorter(strategy: BubbleSortStrategy())
print(sorter.performSort(on: numbers)) // [11, 12, 22, 25, 34, 64, 90]
// Динамическая смена алгоритма
sorter.setStrategy(QuickSortStrategy())
print(sorter.performSort(on: numbers)) // [11, 12, 22, 25, 34, 64, 90]
Другие примеры использования:
- Расчёт стоимости доставки (Standard, Express, International).
- Способы оплаты (CreditCard, PayPal, ApplePay).
- Алгоритмы сжатия (ZIP, RAR, 7z).
Преимущества:
- Избегание условных операторов.
- Принцип открытости/закрытости: Легко добавлять новые стратегии.
- Выбор алгоритма во время выполнения.
- Изоляция кода и данных алгоритмов от контекста.
Ответ 18+ 🔞
А, паттерн «Стратегия»! Ну это ж классика, блядь, как «Муму» у Тургенева, только без утопления собак, а с утоплением в условных операторах!
Смотри, в чём суть трагедии. Есть у тебя класс, а в нём, сука, сидит такой здоровый Герасим-метод, который внутри себя делает выбор: «Если так — делай раз, если эдак — делай два». И этих «если» там, блядь, овердохуища! Получается пиздопроебибна из switch-case и if-else, которая раздувается, как жопа у ткачихи из сказки. Добавить новый алгоритм? Да это ж переписать полкласса, в рот меня чих-пых!
И тут приходит стратегия, как добрая фея, и говорит: «А давайте, блядь, вынесем каждый этот поганый алгоритм в отдельный домик-класс!». И делает их взаимозаменяемыми, как носки, ёпта.
Смотри, как это на Swift выглядит, не трогая священный код, блядь:
// 1. Интерфейс Стратегии. Это как общая команда всем: «Сортировать!»
protocol SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T]
}
// 2. Конкретные стратегии. Это уже исполнители.
// Вот пузырёк, старый добряк, медленный, как немой Герасим, но свой.
class BubbleSortStrategy: SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T] {
var result = array
for i in 0..<result.count {
for j in 1..<result.count - i {
if result[j] < result[j-1] {
result.swapAt(j, j-1)
}
}
}
return result
}
}
// А вот быстрая сортировка — шустрая, хитрая жопа.
class QuickSortStrategy: SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T] {
guard array.count > 1 else { return array }
let pivot = array[array.count/2]
let less = array.filter { $0 < pivot }
let equal = array.filter { $0 == pivot }
let greater = array.filter { $0 > pivot }
return sort(less) + equal + sort(greater)
}
}
// 3. Контекст. Это наш главный чувак, который будет пользоваться стратегиями.
// Он не парится, КАК сортировать, он просто говорит: «Сортируй!»
class Sorter {
private var strategy: SortStrategy // Держит стратегию, как тайное оружие.
init(strategy: SortStrategy) {
self.strategy = strategy
}
// А вот тут магия! Меняешь стратегию на лету, как перчатки.
func setStrategy(_ strategy: SortStrategy) {
self.strategy = strategy
}
func performSort<T: Comparable>(on array: [T]) -> [T] {
return strategy.sort(array) // Просто делегирует работу. Умно, блядь!
}
}
// 4. Использование. Смотри, как всё изящно.
let numbers = [64, 34, 25, 12, 22, 11, 90]
let sorter = Sorter(strategy: BubbleSortStrategy()) // Сначала пузырёк.
print(sorter.performSort(on: numbers)) // [11, 12, 22, 25, 34, 64, 90]
// А теперь, ёпта, БАЦ! И меняем алгоритм прямо в бою!
sorter.setStrategy(QuickSortStrategy())
print(sorter.performSort(on: numbers)) // Результат тот же, но внутри — другой мир!
Вот и вся философия, блядь. Вместо того чтобы пихать в один метод кучу if (type == "bubble"), ты просто подсовываешь контексту нужную стратегию. Хочешь посчитать доставку? StandardShipping, ExpressShipping, InternationalShipping — нате вам, хуй с горы, выбирайте. Способы оплаты? Да похуй! CreditCardStrategy, PayPalStrategy, CryptoStrategy — подставляй и не парься.
Преимущества? Да их, блядь, как собак нерезаных:
- Условных операторов — ноль ебать. Никаких монструозных switch-case.
- Принцип «открыт-закрыт» в действии. Новый алгоритм? Просто новый класс стратегии, и в пизду, ни одну строчку в старом коде не тронул.
- Меняй алгоритмы как перчатки, прямо во время выполнения. Гибкость — пиздец.
- Всё изолировано. Каждая стратегия живёт в своём домике и не срёт в общий коридор.
Короче, стратегия — это когда ты перестаёшь быть тем самым мудаком, который пихает всю логику в один метод, и начинаешь мыслить архитектурно. Почти как Тургенев, только про код.