The Bridge Pattern is a structural design pattern from the Gang of Four that might be little harder to understand at first due to its definition –
“decouple an abstraction from its implementation so that the two can vary independently.”
This definition sounds more complicated than it actually is.
Intent and Structure
As said in its definition, there are two parts to the bridge pattern:
- The abstraction – the class itself
- The implementation – what the class can do
Instead of the abstraction and the implementation being tied together, they are split apart. The abstraction class instead has a reference to the implementation. This allows you to vary each of these independently of each other.
Example Application – Car Inventory
This will become more clear in the following example. Let’s say we have an application which manages car inventory (such as a used car dealership). The dealership has several different makes.
In the class diagram below, we have a car class which has several subclasses tied to each of its own Automaker. Here, we’ve got properties for AutomakerId and AutomakerName, but maybe there’s additional details that would be included for different automakers that could be added.
What’s the problem with this?
Right now, the car dealership has 3 different makes. However, what if more are added? You would have to keep adding more subclasses – for example, ChevroletCar, GMCCar, HyndaiCar, etc. What if we also started selling trucks? Would we then need to also have classes “FordTruck”, “ToyotaTruck”, etc.?
Refactoring with The Bridge Pattern
The solution is fairly simple. We currently have 2 “aspects” tied together in the class. The implementation in this case is the “Automaker” and the abstraction is the “Car”.
Instead of trying them together in subclasses,
- we can create a separate class for Automaker
- we can create a “bridge” (or a reference) to the Automaker object.
Now, we don’t have to create a new subclass every time a new automaker is added to the dealership. If there is a change to the Automaker class, it doesn’t affect the Car class. Each class can vary independently of each other.
Code:
We switched to using a “has-a” relationship instead of using inheritance for the automaker. “Has-a” (aka composition) rather than using “is-a” (inheritance) is easier to understand, maintain, and is more flexible.
This was an obvious example to demonstrate the concept. If you are finding classes in your code which ties the implementation together with the abstraction, especially with the symptom of growing classes, consider splitting them using the bridge pattern.