Understand Strategy Pattern in Swift in easy way
First of all, it is necessary to understand what Design Patterns are. Here is my medium article link for the same.
It covers the intro to Design Patterns in very concise way. Please do check it in case you are completely beginner to design patterns.
In computer programming, the strategy pattern (also known as the policy pattern) is a behavioural software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.
-Wikipedia
The strategy pattern defines the family of interchangeable objects that can be fed or switched at runtime.
Here, there are three components:
1. Object using a Strategy: Any kind of object that needs interchangeable behaviour
2. Protocol Strategy: Method that every strategy must implement
3. Strategies: Objects that conform to the strategy protocol
Let us understand this with help of code example
Suppose that we are creating a functionality where the user wants to play some sports (say football, basketball, cricket, etc.). We are not sure what different kind of sports user will play. There could be more sports added on, or sports could be deleted at any point of time (i.e. the list of sports that user plays can be modified at any point of time)
So, how are we going to implement this using code? Remember the challenge is the list of sports that the user play is dynamic.
The answer is Strategy pattern. We first define a base for all the sports. The base is protocol GameStrategy.
All the sports need to conform to this protocol.
protocol GameStrategy {
func playGame()
}
protocol GameStrategy
has blueprint of function playGame.
Now, let us define a class Player
that will use GameStrategy
protocol
class Player {
let gameStrategy: GameStrategy
init(gameStrategy: GameStrategy) {
self.gameStrategy = gameStrategy
}
func playGame() {
gameStrategy.playGame()
}
}
The class Player
has a gameStrategy
variable and a playGame
function. The playGame
function further executes the playGame
function of gameStrategy
protocol.
Suppose the user wants to play football. We implement FootballStrategy
class that conforms to GameStrategy
protocol.
class FootballStrategy: GameStrategy {
func playGame() {
/// some football strategy
print("play football")
}
}
playGame
function for FootballStrategy
class has some strategy to play football. At the end of function we have added a print statement to signal the user to play football .
Now the user also wants to play cricket. So we now implement CricketStrategy
class that conforms to GameStrategy
protocol.
class CricketStrategy: GameStrategy {
func playGame() {
/// some cricket strategy
print("play cricket")
}
}
Similarly, playGame
function for CricketStrategy
class has some strategy to play cricket. At the end of function we have added a print statement to signal the user to play cricket.
We then create an instance of Player
class by passing CricketStrategy
as initializer. We then execute playGame
function. The output is play cricket.
var cricketPlayer = Player(gameStrategy: CricketStrategy())
cricketPlayer.playGame()
We now create an instance of Player
class by passing FootballStrategy
as initializer. The output is play football.
var footballPlayer = Player(gameStrategy: FootballStrategy())
footballPlayer.playGame()
If in future, the user want to create another sport, they can do so by first creating a class and conforming it to GameStrategy
protocol and then creating an instance of Player
class by passing that sport class as initializer.
So we can conclude that:
1. Player
class is the object using a strategy
2. GameStrategy
is the protocol strategy
3. CricketStrategy
and FootballStrategy
are different kind of strategies that conform to GameStrategy
Advantages of Strategy Pattern
- Strategy Pattern helps to write clean code because we avoid conditional nested code and we create separate class for different strategies
- The algorithms are loosely coupled with the context entity. They can be changed/replaced without changing the context entity.
- The strategy pattern allows you to modify the algorithm’s implementation without completely disrupting your code.
If you found this article helpful, kindly share this story, follow me on medium and give applaud 👏. Thank You!