Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bridge Pattern #10

Open
tuananhhedspibk opened this issue Mar 12, 2022 · 0 comments
Open

Bridge Pattern #10

tuananhhedspibk opened this issue Mar 12, 2022 · 0 comments

Comments

@tuananhhedspibk
Copy link
Owner

tuananhhedspibk commented Mar 12, 2022

Là Pattern cho phép ta chia một class lớn hoặc tập các classes có mối liên hệ gần nhau thành 2 classes, tập riêng biệt, độc lập với nhau.

Vấn đề

Ta cùng nhau lấy một ví dụ với class tổng quát là Shape với 2 sub-classes là CircleSquare. Giả sử trong trường hợp ta muốn kết hợp với màu, ví dụ như: Red & Blue thì ta cần cả thảy 4 sub-classes: BlueCircle, BlueSquare, RedCircle, RedSquare.

Screen Shot 2022-03-12 at 21 14 05

Nếu sau này ta thêm một shape mới như Triangle thì ta cần thêm 2 sub-classes đó là BlueTriangle, RedTriangle. Sau đó nếu thêm màu mới thì ta lại phải thêm 3 sub-classes nữa.

Tổng quát lên, nếu số lượng shape và màu tăng thì số lượng sub-classes sẽ tăng với tốc độ của hàm mũ.

Giải pháp

Vấn đề này xảy ra là do ta đang cố gắng mở rộng class Shape thành 2 nhánh là colorform. Đây là vấn đề thường gặp với class inheritance.

Bridge pattern giải quyết vấn đề này bằng cách thay vì kế thừa sẽ chuyển qua object composition. Tách một nhánh cũ thành một tập class và sub-classes riêng biệt. Class gốc ban đầu sẽ tham chiếu đến class thuộc về nhánh mới này thay vì giữ toàn bộ thuộc tính và behavior của nó trong một class duy nhất.

Screen Shot 2022-03-12 at 21 14 10

Lúc này, việc thêm màu mới cho Shape không quá khó khăn khi chỉ cần thêm vào list các colors của Shape mà thôi. Reference tới Color thuộc Shape sẽ đóng vai trò như một chiếc cầu nối giữa 2 classes.

Abstraction & Implementation

Abstraction là tầng ở mức cao, nó không thực hiện một hành động thực tế nào cả, thay vào đó nó sẽ chuyển tiếp công việc này cho tầng implementation (còn gọi là tầng platform).

Khi nói về ứng dụng trong thực tế thì những gì được gọi là abstraction thường sẽ được cụ thể hoá thông qua UI. Và việc triển khai sẽ nằm ở API hoặc OS.

Nói một cách tổng quát, ta có thể chia một ứng dụng trong thực tế ra thành 2 nhánh độc lập:

  • Có một vài UIs (giao diện cho admin và user thông thường)
  • Hỗ trợ một vài APIs khác biệt (app có thể chạy ở Window, MacOS, Linux)

Tuy nhiên trong kịch bản tồi tệ nhất, app có thể trông như một bát mì Ý khổng lồ khi cả tá điều kiện kết nối giữa UI và API tồn tại trong code của bạn.

Việc sửa đổi một app với kiến trúc là monolithic sẽ rất khó vì bạn phải hiểu rõ toàn bộ hệ thống, còn với app được chia modules rõ ràng thì việc sửa đổi sẽ dễ hơn rất nhiều.

Screen Shot 2022-03-13 at 11 31 53

Bạn có thể đưa các đoạn code liên quan đến một interface-platform cụ thể vào các classes riêng biệt. Nhưng sẽ có rất nhiều classes mới sẽ được sinh ra. Việc kế thừa class cũng sẽ tăng nhanh chóng mặt vì việc thêm UI mới hoặc API mới sẽ đòi hỏi các classes mới.

Chúng ta có thể giải quyết vấn đề trên bằng Bridge pattern. Ta sẽ chia các classes thành 2 nhánh kế thừa:

  1. Abstraction: UI layer
  2. Implementation: OS's APIs

Screen Shot 2022-03-13 at 11 35 54

Abstraction object điểu khiển tầng UI, nó sẽ chuyển tiếp công việc xử lí cho các implementation objects. Các implementation objects khác nhau hoàn toàn có thể tráo đổi vai trò cho nhau nếu chúng cùng tuân theo interface chung cũng như cho phép UI hoạt động với Window, Linux.

Kết quả là ta có thể thay đổi UI classes mà không làm ảnh hưởng gì đến API-related classes.

Cấu trúc

Screen Shot 2022-03-13 at 11 52 12

  1. Abstraction: cung cấp high-level control. Nó sẽ chuyển tiếp việc xử lí cấp thấp (low-level) cho implementation object
  2. Implementation: định nghĩa interface cho các class triển khai. Abstraction object chỉ có thể giao tiếp với implementation object thông qua các methods được định nghĩa ở interface này.
  3. Concrete Implementations: platform-specific code.
  4. Client chỉ quan tâm tới việc tương tác với abstraction.

Tính ứng dụng

  1. Bridge Pattern giúp ta chia nhỏ Monolithic class thành các nhánh class kế thừa độc lập với nhau. Khi class càng lớn, càng dài thì sẽ càng khó để nắm bắt luồng làm việc, cũng như fix bug cho nó. Ngoài ra việc thêm tính năng mới cũng gặp nhiều khó khăn. Việc chia class thành các nhánh class kế thừa cho phép ta có thể thay đổi được class trong nhánh kế thừa này mà không làm ảnh hưởng đến các classes ở nhánh kế thừa khác.

  2. Sử dụng pattern khi bạn muốn mở rộng class theo các nhánh độc lập nhau. Từ đó original class có thể chuyển tiếp các công việc cho các class con trong cây kế thừa thay vì làm trực tiếp mọi việc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant