โ Back to Design Patterns
โ๏ธ
Behavioral
Strategy
Defines a family of interchangeable algorithms and lets you swap them at runtime.
The Problem
A class has multiple variants of an algorithm, selected with a big if/else or switch. Adding a new variant requires modifying the class itself.
How It Works
- โบEncapsulates each algorithm behind a common interface
- โบAlgorithms can be swapped at runtime without changing the context class
- โบEliminates large conditional blocks for algorithm selection
- โบContext delegates work to the strategy โ it does not perform the algorithm itself
- โบClosely related to dependency injection โ inject the strategy from outside
When to Use
โMultiple related algorithms that differ only in their behavior
โSwappable behaviors: sorting, compression, payment, validation
โReplacing large if/else chains that select an algorithm
โWhen you want to let users configure or extend behavior
Real-World Examples
๐
iOS
JSONEncoder.dateEncodingStrategy, URLSessionConfiguration, UICollectionViewLayout
๐ค
Android
RecyclerView.LayoutManager (Linear/Grid/Staggered), Room TypeConverter
๐
Web
Passport.js strategies (local, OAuth), webpack's loader config, sorting comparators
Code Examples
Swift
protocol ValidationStrategy {
func validate(_ input: String) -> Bool
}
struct EmailValidator: ValidationStrategy {
func validate(_ input: String) -> Bool {
input.contains("@") && input.contains(".")
}
}
struct PhoneValidator: ValidationStrategy {
func validate(_ input: String) -> Bool {
input.allSatisfy { $0.isNumber } && input.count >= 10
}
}
struct MinLengthValidator: ValidationStrategy {
let minLength: Int
func validate(_ input: String) -> Bool { input.count >= minLength }
}
class InputField {
var strategy: ValidationStrategy
init(strategy: ValidationStrategy) { self.strategy = strategy }
func isValid(_ input: String) -> Bool { strategy.validate(input) }
}
let emailField = InputField(strategy: EmailValidator())
print(emailField.isValid("agus@example.com")) // true
print(emailField.isValid("not-an-email")) // false
emailField.strategy = MinLengthValidator(minLength: 6)
print(emailField.isValid("hello")) // false