Bridge Design Pattern là một trong những mẫu thiết kế cấu trúc (structural design pattern) trong lập trình phần mềm. Mục tiêu chính của nó là tách biệt một abstraction (abstraction) từ implementation (implementation), để hai có thể thay đổi độc lập với nhau. Điều này giúp giảm sự phụ thuộc giữa abstraction và implementation, cung cấp sự linh hoạt và dễ mở rộng.
Mô hình Bridge bao gồm hai thành phần chính:
Mô hình Bridge cho phép Abstraction và Implementor thay đổi mà không cần phải thay đổi nhau, bằng cách giữ chúng độc lập. Điều này làm cho mô hình này thích hợp cho các trường hợp khi có nhiều biến thể của một tính năng hoặc khi có nhiều cách triển khai cho một giao diện.
Trong ví dụ này, chúng ta sẽ xem xét một hệ thống vẽ hình ảnh với khả năng vẽ hình cơ bản (như hình vuông và hình tròn) trên nền tảng vẽ cụ thể (như vẽ trên màn hình hoặc in ra console).
Đầu tiên, chúng ta sẽ xác định hai phần chính của mô hình Bridge: Abstraction và Implementor.
Shape đại diện cho hình cơ bản như hình vuông và hình tròn.DrawingAPI đại diện cho nền tảng vẽ cụ thể (ví dụ: vẽ trên màn hình hoặc in ra console).// Implementor
interface DrawingAPI {
fun drawCircle(x: Double, y: Double, radius: Double)
fun drawSquare(x: Double, y: Double, side: Double)
}
// Concrete Implementor 1
class DrawingAPI1 : DrawingAPI {
override fun drawCircle(x: Double, y: Double, radius: Double) {
println("API1 - Drawing Circle at ($x, $y) with radius $radius")
}
override fun drawSquare(x: Double, y: Double, side: Double) {
println("API1 - Drawing Square at ($x, $y) with side $side")
}
}
// Concrete Implementor 2
class DrawingAPI2 : DrawingAPI {
override fun drawCircle(x: Double, y: Double, radius: Double) {
println("API2 - Drawing Circle at ($x, $y) with radius $radius")
}
override fun drawSquare(x: Double, y: Double, side: Double) {
println("API2 - Drawing Square at ($x, $y) with side $side")
}
}
// Abstraction
abstract class Shape(protected val drawingAPI: DrawingAPI) {
abstract fun draw()
}
// Refined Abstraction 1
class Circle(private val x: Double, private val y: Double, private val radius: Double, drawingAPI: DrawingAPI) :
Shape(drawingAPI) {
override fun draw() {
drawingAPI.drawCircle(x, y, radius)
}
}
// Refined Abstraction 2
class Square(private val x: Double, private val y: Double, private val side: Double, drawingAPI: DrawingAPI) :
Shape(drawingAPI) {
override fun draw() {
drawingAPI.drawSquare(x, y, side)
}
}
fun main() {
val api1: DrawingAPI = DrawingAPI1()
val api2: DrawingAPI = DrawingAPI2()
val circle1: Shape = Circle(1.0, 2.0, 3.0, api1)
val square1: Shape = Square(5.0, 7.0, 10.0, api1)
val circle2: Shape = Circle(2.0, 3.0, 4.0, api2)
val square2: Shape = Square(8.0, 10.0, 12.0, api2)
circle1.draw()
square1.draw()
circle2.draw()
square2.draw()
}
Trong ví dụ này, DrawingAPI là Implementor, trong khi các lớp Circle và Square là Abstraction. Bằng cách này, chúng ta có thể dễ dàng thêm nền tảng mới hoặc hình mới mà không làm thay đổi mã hiện tại. Các lớp Abstraction chỉ tương tác với DrawingAPI thông qua phương thức đã định nghĩa trong giao diện, điều này giữ cho Abstraction và Implementor độc lập và dễ mở rộng.