Bridge- vs Strategy-Pattern

Wikipedia UML Diagram for Bridge Pattern:

Wikipedia UML Diagram for BridgeHave a look at my answer in linked question for basic differences :

What is the difference between the bridge pattern and the strategy pattern?

Main difference: Abstraction and Implementation can change independently.

Regarding your other queries:

Is this probably the main-difference? Since the Implementor and the Abstraction are so loose coupled, I can change the Interface of the Implementor and the Abstraction doesn't have to care? That sounds reasonable, but wouldn't then have the Abstraction to change as well, since they are kindahow connected?

Have a look at below code example @

When do you use the Bridge Pattern? How is it different from Adapter pattern?

Even though the example is in java, it can be easily understood for c# developers.

In linked example:

Vehicle            : Abstraction
Car                : Re-defined Abstraction
Truck              : Re-defined Abstraction
Implementor        : GearShifter
ConcreteImplementor: ManualGearShifter  
ConcreteImplementor: AutoGearShifter 

Keynotes:

  1. Now Vehicle and GearShifter can change independently.

  2. If Vehicle changes, only Car and Truck have to be changed.

  3. If GearShifter changes, only ManualGearShifter and AutoGearShifter need to change.

  4. Since Vehicle(abstraction) contains GearShifter(implementation) through composition, changes in GearShifter does not affect Vehicle

  5. Since GearShifter ( implementor) does not contain or refer Vehicle ( abstraction), changes in abstraction does not effect implementation.

EDIT:

Bridge pattern presents two orthogonal class hierarchies - One is for Abstraction and one is for Implementor, which can be changed independently without dependency on other.


In the Strategy pattern, the activities of the "Parent" for a particular operation are constant whereas the activities of the "Child" can vary. However, in the Bridge Pattern, the activities of the Parent, as well as the Child, can vary.

So, for example,

public class Ticket {
    
    Date dateOfTravel;
    int distance;
    Vehicle vehicle;
    Seat  seat;
    
    public float getTotalFare(){
         //depends on 
               //Distance
               //Vehicle - whether Vehicle is AC or non-AC. 
               //Seat - based on the location of the Seat.
     
        //Fare = vehicleBaseFare*seatMultiplier*distance

    }
    
}

In the above, the variations depend on the Parent (distance) as well as the children (Vehicle and Seat). So, here Vehicle and Seat both acted like Bridge.

Now, here

public class Vehicle {

   TrackingDevice device;

   public Coordinates getCoordinates(){
       return device.getCoordinates();
   }
}

Here, the Parent's role was constant, i.e., nothing! So, this was a Strategy pattern.


I checked original design patterns book to see how the authors were defining Bridge pattern. Their real-life examle shows a case when both abstraction and imlementation hierarchies can change independently (i.e. new subclasses can be introduced for an abstraction; new subclasses can be introduced for implementations). Their example deals with window library that can work for different window systems. In the original example the authors used different window system from IBM, but I believe a good current analogy would be different Linux window managers (GNOME, KDE, etc.). So, imagine a Window abstraction, and two implementations for GNOME and KDE. And now imagine that you want to add new Window subclass, TransparentWindow. TransparentWindow extends Window, so as GNOMEWindow and KDEWindow. But you also have to provide imlementations for TransparentWindow: GNOMETransparentWindow and KDETransparentWindow. The hierarchy starts looking messy. Imagine new type of window, or new window manager - XFCE. To avoid complicated hierarchies, they introduce the Bridge pattern, and make two hierarchies separate (i.e. TransparentWindow extends Window; GNOMEWindow and KDEWindow extend WindowImpl). To me it seems that a tricky part is to define interface for implementation, since the hierarchies of abstractions will need to define their operations using only that interface. A learning example of Bridge pattern that I liked is here, and I liked it because it does not use artificial classes ConcreteImplementor1 and ConcreteImplementor2. When it comes to real-life examples, I believe I saw this pattern in Selenium WebDriver implementation, but I am not 100% sure now.