In this article we can explore the Bridge pattern which is commonly used in applications.
You are working on an abstract business class. The class needs to log information to by writing to a file, email to user etc. We need to avoid tightly coupling of the business class and logger as in future newer versions of logger might appear.
How to achieve a decoupled solution?
Decouple an abstraction from its implementation so that the two can vary independently
We can create an abstract class for representing the Logger. Let the abstract business class hold reference to the new abstract Logger. In the runtime we can specify the actual implementation instance of Logger class. (File writer or Emailer)
Following is the snapshot of the class diagram after using the Bridge Pattern:
Here the concrete Logger implementations derive from AbstractLogger class.
The concreate TransactionBL derives from AbstractBL class. The AbstractBL class is holding reference to Logger (abstract Logger).
Using the Bridge Pattern as shown above, there is decoupling of the implementation from its abstraction. It allows future extensibility to the Logger classes without modifying the BL class.
Following is the code that invokes above Transaction and Logger classes.
AbstractBL bl = new TransactionBL();
bl.Logger = new TextFileLogger();
bl.Logger = new EmailLogger();
On running the application we can see the following output.
Following is the coupling snapshot after using the Bridge Pattern.
We can see that this pattern is a simple implementation using an abstract class and interface. The Bridge Pattern is having some similarity with Strategy Pattern as both involve changing the implementation in the runtime. Here the class is abstract when compared with Strategy pattern.
In this article we have explored the Bridge design pattern. It provides convenient way for separating the abstraction from implementation through a bridge of abstract class or interface. The attached source code contains the example we discussed.