Master Software Architecture & Clean Code!
Subscribe to Ram N Java for clean code, design pattern implementations, and practical Java tutorials!
SUBSCRIBE NOWDecoupling Abstraction and Implementation
The Bridge Design Pattern decouples an abstraction from its implementation so that both can vary independently. In graphics and GUI libraries, combining shapes and rendering colors using standard inheritance leads to a combinatorial explosion of subclasses (e.g., RedCircle, BlueCircle, RedSquare, BlueSquare).
By extracting color/rendering functionality into its own separate hierarchy and bridging it with the shape hierarchy via composition, both hierarchies can evolve freely without duplicating code.
Complete Java Code Implementation
Here is an end-to-end, object-oriented example demonstrating the classic Shape and Color Bridge implementation in Java:
// 1. Implementor Interface
interface Color {
void applyColor();
}
// 2. Concrete Implementors
class RedColor implements Color {
@Override
public void applyColor() {
System.out.println("Applying Red Color.");
}
}
class BlueColor implements Color {
@Override
public void applyColor() {
System.out.println("Applying Blue Color.");
}
}
// 3. Abstraction (Bridge holding the Implementor reference)
abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
// 4. Refined Abstractions
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void draw() {
System.out.print("Drawing Circle: ");
color.applyColor();
}
}
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public void draw() {
System.out.print("Drawing Square: ");
color.applyColor();
}
}
// 5. Client Application
public class ShapeBridgeDemo {
public static void main(String[] args) {
// Draw a Red Circle
Shape redCircle = new Circle(new RedColor());
redCircle.draw();
// Draw a Blue Circle
Shape blueCircle = new Circle(new BlueColor());
blueCircle.draw();
// Draw a Red Square
Shape redSquare = new Square(new RedColor());
redSquare.draw();
}
}
Key Architectural Advantages
- Eliminates Subclass Proliferation: Avoids creating
N × Mclasses; adding new shapes or colors requires onlyN + Mclasses. - Composition Over Inheritance: Binds abstractions and implementors at runtime rather than compile-time.
- Adheres to Open/Closed Principle: Adding a new color (e.g.,
GreenColor) or new shape (e.g.,Triangle) requires no changes to existing classes.
Watch More Related Design Pattern Tutorials
Click here to watch in Youtube : https://www.youtube.com/watch?v=ztdhlaWL5S0
Click the below Image to Enlarge
| Bridge Design pattern - Implementation [Shape] |
| Bridge Design pattern - Implementation [Shape] - Class Diagram |
Shape.java
abstract class Shape
{
protected ColorImplementor color;
protected ColorImplementor getColor()
{
return color;
}
protected void setColor( ColorImplementor color )
{
this.color = color;
}
abstract public void colorIt();
abstract public void draw();
}
Circle.java
{
public void colorIt()
{
System.out.print("Circle filled with ");
color.fillColor();
}
@Override
public void draw()
{
System.out.println("Circle has been drawn with out any color");
}
}
Rectangle.java
public class Rectangle extends Shape
{
public void colorIt()
{
System.out.print("Rectangle filled with ");
color.fillColor();
}
@Override
public void draw()
{
System.out.println("Rectangale has been drawn with out any color");
}
}
ColorImplementor.java
public interface ColorImplementor
{
public void fillColor();
}
BlueColorImplementor.java
public class BlueColorImplementor implements ColorImplementor
{
public void fillColor()
{
System.out.println("blue color using BlueColorImplementor");
}
}
GreenColorImplementor .java
public class GreenColorImplementor implements ColorImplementor
{
public void fillColor()
{
System.out.println("green color using GreenColorImplementor");
}
}
BridgeDesignPatternClient.java
import java.util.Scanner;
public class BridgeDesignPatternClient
{
public static void main( String[] args )
{
System.out.println("Please enter the color you want to fill : 'Green' or 'Blue'");
Scanner scanner = new Scanner(System.in);
String color = scanner.next();
System.out.println("color : " + color);
Shape rectangleShape = new Rectangle();
rectangleShape.draw();
Shape circleShape = new Circle();
circleShape.draw();
System.out.println();
if( "blue".equalsIgnoreCase(color) )
{
rectangleShape.setColor(new BlueColorImplementor());
rectangleShape.colorIt();
circleShape.setColor(new BlueColorImplementor());
circleShape.colorIt();
}
else if( "green".equalsIgnoreCase(color) )
{
rectangleShape.setColor(new GreenColorImplementor());
rectangleShape.colorIt();
circleShape.setColor(new GreenColorImplementor());
circleShape.colorIt();
}
}
}
Output
Please enter the color you want to fill : 'Green' or 'Blue'
Green
color : Green
Rectangale has been drawn with out any color
Circle has been drawn with out any color
Rectangle filled with green color using GreenColorImplementor
Circle filled with green color using GreenColorImplementor
Please enter the color you want to fill : 'Green' or 'Blue'
Blue
color : Blue
Rectangale has been drawn with out any color
Circle has been drawn with out any color
Rectangle filled with blue color using BlueColorImplementor
Circle filled with blue color using BlueColorImplementor
No comments:
Post a Comment