Mô hình cây cầu là gì?
Mẫu cầu là một mẫu thiết kế cấu trúc. Nói cách khác, công việc chính của nó là tạo ra một cấu trúc chính thức từ các lớp và đối tượng. Cầu nối thực hiện điều này bằng cách chia một hoặc nhiều lớp thành các phân cấp riêng biệt: trừu tượng hóa và triển khai . Một thay đổi về chức năng trong một hệ thống phân cấp không kéo theo sự thay đổi trong hệ thống phân cấp khác. Đó là tất cả tốt và tốt, nhưng định nghĩa này rất rộng và không trả lời câu hỏi quan trọng nhất: "mẫu cầu là gì?" Tôi nghĩ bạn sẽ dễ hiểu ứng dụng thực tế của nó hơn. Vì vậy, ngay bây giờ, hãy tạo một kịch bản cổ điển cho mô hình cây cầu. Chúng tôi có mộtShape
lớp trừu tượng, đại diện cho một hình hình học chung:
-
Hình dạng.java
public abstract class Shape { public abstract void draw(); }
Khi chúng tôi quyết định thêm các hình dạng như hình tam giác và hình chữ nhật, chúng tôi sẽ làm cho chúng kế thừa
Shape
lớp: -
Hình chữ nhật.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
Tam giác.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
phương thức sẽ phụ thuộc vào màu này. Để có các triển khai khác nhau của draw()
phương thức, thì chúng ta cần tạo một lớp cho từng kết hợp màu sắc hình dạng. Nếu chúng ta có ba màu, thì chúng ta cần sáu lớp: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
và RectangleRed
. Sáu lớp không phải là một vấn đề lớn. Nhưng! Nếu chúng ta cần thêm một hình dạng hoặc màu sắc mới, thì số lượng các lớp sẽ tăng theo cấp số nhân. Làm thế nào để thoát khỏi tình trạng này? Lưu trữ màu trong một trường và liệt kê tất cả các tùy chọn bằng câu lệnh điều kiện không phải là giải pháp tốt nhất. Một giải pháp tốt là chuyển màu sang một giao diện riêng. Nói sớm hơn làm: hãy tạo một giao diện Color
với ba triển khai: BlackColor
và : GreenColor
RedColor
-
Màu.java:
public interface Color { void fillColor(); }
-
Màu đen.java:
public class BlackColor implements Color { @Override public void fillColor() { System.out.println("Filling in black color"); } }
-
GreenColor.java
public class GreenColor implements Color { @Override public void fillColor() { System.out.println("Filling in green color"); } }
-
RedColor.java
public class RedColor implements Color { @Override public void fillColor() { System.out.println("Filling in red color"); } }
Bây giờ chúng ta thêm một
Color
trường vàoShape
lớp. Chúng ta sẽ lấy giá trị của nó trong hàm tạo. -
Hình dạng.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
Chúng tôi sẽ sử dụng
color
biến trongShape
triển khai. Điều này có nghĩa là các hình có thể sử dụng chức năng củaColor
giao diện. -
Hình chữ nhật.java
public class Rectangle extends Shape { public Rectangle(Color color) { super(color); } @Override public void draw() { System.out.println("Drawing rectangle"); color.fillColor(); } }
Color color
là cầu nối kết nối hai hệ thống phân cấp lớp riêng biệt.
Cách xây dựng một cây cầu: trừu tượng hóa và triển khai
Hãy xem một sơ đồ lớp mô tả mẫu cầu nối:
- Trừu tượng là
Shape
lớp - RefinedAbstraction là
Triangle
vàRectangle
các lớp - Người thực hiện là
Color
giao diện - ConcreteImplementor là
BlackColor
vàGreenColor
cácRedColor
lớp.
Shape
là một sự trừu tượng - một cơ chế để quản lý việc lấp đầy các hình dạng với nhiều màu sắc khác nhau, ủy quyền cho giao Color
diện (Người triển khai). Các lớp Triangle
và Rectangle
là các lớp cụ thể sử dụng cơ chế do lớp cung cấp Shape
. BlackColor
và GreenColor
là RedColor
các triển khai cụ thể trong hệ thống phân cấp Triển khai.
Trường hợp sử dụng mẫu cầu
Một lợi ích to lớn của việc sử dụng mẫu này là bạn có thể thực hiện các thay đổi đối với các lớp chức năng trong một hệ thống phân cấp mà không vi phạm logic của hệ thống kia. Ngoài ra, cách tiếp cận này giúp giảm sự ghép nối giữa các lớp. Yêu cầu chính khi sử dụng mẫu này là "làm theo hướng dẫn" — đừng bỏ qua bất kỳ hướng dẫn nào! Để làm được điều đó, hãy tìm hiểu các tình huống khi bạn chắc chắn nên sử dụng mẫu cầu nối:-
Nếu bạn cần mở rộng số lượng thực thể dựa trên sự kết hợp của hai khái niệm (ví dụ: hình dạng và màu sắc).
-
Nếu bạn muốn chia một lớp lớn không đáp ứng nguyên tắc một trách nhiệm thành các lớp nhỏ hơn có chức năng hẹp.
-
Nếu cần thay đổi logic của các thực thể nhất định trong khi chương trình đang chạy.
-
Nếu cần ẩn một triển khai khỏi các máy khách của lớp hoặc thư viện.
Ưu và nhược điểm của mẫu
Giống như các mô hình khác, một cây cầu có cả ưu điểm và nhược điểm. Ưu điểm của mô hình cây cầu:- Nó cải thiện khả năng mở rộng của mã — bạn có thể thêm chức năng mà không sợ làm hỏng thứ gì đó trong phần khác của chương trình.
- Nó làm giảm số lượng các lớp con khi số lượng thực thể dựa trên sự kết hợp của hai khái niệm (ví dụ: hình dạng và màu sắc).
- Nó cho phép làm việc riêng biệt trên hai hệ thống phân cấp riêng biệt - Trừu tượng hóa và Thực hiện. Hai nhà phát triển khác nhau có thể thực hiện các thay đổi mà không cần đi sâu vào chi tiết mã của nhau.
- Nó làm giảm sự ghép nối giữa các lớp — nơi duy nhất mà hai lớp được ghép nối là cầu nối (tức là trường
Color color
).
- Tùy thuộc vào tình huống cụ thể và cấu trúc tổng thể của dự án, nó có thể tác động tiêu cực đến hiệu suất của chương trình (ví dụ: nếu bạn cần khởi tạo nhiều đối tượng hơn).
- Nó làm cho mã khó đọc hơn do phải chuyển đổi giữa hai lớp.
GO TO FULL VERSION