This question has come up umpteen times and has mystified many of us. Why? Because to a developer looking at the code, the implementations look the same. So where is the difference?
The simple answer is “They are similar but different”. The implementations are similar but the intentions are different. To give an analogy, a city bus and school bus are both similar vehicles, but they are used for different purposes. One is used to transport people between various parts of the city as a commuter service. The other is used for transporting kids to schools.
Let’s start with the definitions of each of these patterns and then look at some practical applications.
Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from the clients that use it.
Capture the abstraction in an interface, bury implementation details in derived classes
A bind once behavioral pattern.
Decouple an abstraction from its implementation so that the two can vary independently.
Publish interface in an inheritance hierarchy, and bury implementation in its own inheritance hierarchy.
A structural pattern.
Enough of theory. Let’s get to some scenarios and learn when to use each of these patterns.
As part of my daily exercise routine, I want to choose an appropriate workout strategy for the day before starting my workout.
var routine = new ExcerciseRoutine(new AerobicsStrategy);
The algorithm for the specific type of workout is encapsulated from the client who interacts only with the interface of the strategy.
Let’s see if we can apply the same concept of an exercise routine for the Bridge pattern.
As part of my exercise routine, I want to have a weekday exercise routine and a weekend routine. The routine involves running either on a treadmill, park or sidewalk.
The client sets the Runner type and invokes the workout as below
var weekdayRoutine = new WeekdayRoutine();
weekdayRoutine.Runner = new Treadmill();
//Change the Runner and perform the workout again
weekdayRoutine.Runner = new Sidewalk();
An exercise routine can vary independently of the implementation of the run. For example, I may decide to add a new runner SchoolPlayground without having to change the client. On the other hand, I can add a new routine MondayRoutine without impacting the implementation of the Runner.
Hope this helps understand the difference between a Strategy and a Bridge pattern.