Bridge Design Pattern in Kotlin

1. Definition

The Bridge Design Pattern decouples an abstraction from its implementation so that both can evolve independently. It promotes composition over inheritance.

2. Problem Statement

Imagine you have a series of shapes (circle, square) and they can be drawn in different colors (red, blue). Creating classes for every combination like RedCircle, BlueSquare, etc., can be cumbersome and doesn't scale well as new shapes or colors are added.

3. Solution

Separate the shape and color into two different hierarchies and use composition to combine them. This way, adding a new color or shape won't require changing the existing code.

4. Real-World Use Cases

1. Remote and devices: A universal remote (abstraction) can control TVs, audio systems, and DVD players (implementations).

2. Different UI themes or styles for a set of widgets in a software application.

5. Implementation Steps

1. Define the abstraction (Shape) and its operations.

2. Define the implementor (Color) that provides concrete functionality for the abstraction.

3. Combine them through composition.

6. Implementation in Kotlin Programming

// Implementor
interface Color {
    fun applyColor(): String
}
class RedColor : Color {
    override fun applyColor() = "Red"
}
class BlueColor : Color {
    override fun applyColor() = "Blue"
}
// Abstraction
abstract class Shape(protected val color: Color) {
    abstract fun draw(): String
}
class Circle(color: Color) : Shape(color) {
    override fun draw() = "Circle drawn in ${color.applyColor()} color"
}
class Square(color: Color) : Shape(color) {
    override fun draw() = "Square drawn in ${color.applyColor()} color"
}
fun main() {
    val redCircle = Circle(RedColor())
    val blueSquare = Square(BlueColor())
    println(redCircle.draw())
    println(blueSquare.draw())
}

Output:

Circle drawn in Red color
Square drawn in Blue color

Explanation:

1. Color is the implementor interface with different concrete classes like RedColor and BlueColor.

2. Shape is the abstraction that takes a Color as a parameter, which provides the concrete implementation of the color.

3. Concrete classes like Circle and Square extend Shape and use the provided color to draw themselves.

4. In the main function, we demonstrate the decoupled nature by drawing a red circle and a blue square without having specific classes for each combination.

7. When to use?

The Bridge pattern is beneficial when:

1. You want to avoid permanently binding an abstraction to its implementation.

2. Both the abstractions and their implementations should be extendable independently.

3. Changes in the implementation of an abstraction shouldn't impact client code.

Comments