Giới Thiệu
Trong cuộc sống hàng ngày, chúng ta đôi khi phải đối mặt với những tình huống khó khăn khi không thể kết nối thiết bị cũ với thiết bị mới. Chẳng hạn như khi điện thoại Android cũ của bạn bị hỏng và bạn phải mượn iPhone 15 Promax 1TB của bạn bè. Khi bạn cố gắng cắm tai nghe cũ vào, bạn nhận ra rằng cổng kết nối không tương thích. Nhưng đừng lo, bạn có thể "mượn" một cổng chuyển đổi từ jack 3.5mm sang cổng lightning của iPhone và tiếp tục sử dụng tai nghe yêu thích của mình. Đây chính là ví dụ điển hình về vai trò của Adapter.
Adapter Là gì?
Mẫu thiết kế Adapter thuộc về nhóm mẫu structural, có nhiệm vụ kết nối các giao diện của các lớp không tương thích để chúng có thể làm việc cùng nhau. Nó cho phép các đối tượng tương tác mà không cần phải thay đổi cấu trúc của lớp. Ví dụ, trong trường hợp một chiếc xe ô tô muốn di chuyển trên đường ray, cần có một "Xe chuyên chở ô tô" để nó có thể hoạt động.
Mục Tiêu của Mẫu Thiết Kế Adapter
Mẫu thiết kế Adapter được phát triển với hai mục tiêu chính:
- Chuyển đổi giao diện của một lớp hiện có sang giao diện mà client yêu cầu.
- Kết nối các giao diện lại với nhau một cách hiệu quả mà không làm thay đổi cấu trúc của chúng.
Sơ Đồ Lớp của Adapter
Mô hình cơ bản của mẫu Adapter bao gồm hai loại: Object Adapter và Class Adapter.
- Object Adapter: Thực hiện phép chuyển đổi bằng cách tham chiếu đến đối tượng được chuyển đổi (Adaptee).
- Class Adapter: Thực hiện việc kế thừa từ cả hai lớp: Target và Adaptee.
So Sánh giữa Object Adapter và Class Adapter
Một trong những lợi thế của Class Adapter là có thể ghi đè (override) các phương thức của Adaptee, nhưng nó chỉ có thể kế thừa một lớp Adaptee. Ngược lại, Object Adapter linh hoạt hơn bởi vì nó cho phép sử dụng nhiều Adaptees khác nhau thông qua ghép nối (composition). Với ngôn ngữ Dart không hỗ trợ kế thừa nhiều (multiple inheritance), Object Adapter là lựa chọn thích hợp hơn.
Ứng Dụng của Adapter
Mẫu thiết kế Adapter có thể được ứng dụng trong nhiều tình huống:
- Nâng cấp hệ thống mà không làm thay đổi các lớp hiện tại.
- Tương tác với các thư viện bên thứ ba mà không cần phải viết lại chúng.
Ví Dụ Thực Hành
Chúng ta sẽ xây dựng một ứng dụng để hiển thị danh sách liên lạc từ hai nguồn dữ liệu: JSON và XML. Với thiết kế Adapter, chúng ta có thể sử dụng cùng một giao diện mà không cần quan tâm đến cách mà dữ liệu đó được lấy ra.
Cấu Trúc Dữ Liệu
- Contact: Lớp chứa thông tin liên lạc.
- JSONContactData và XMLContactData: Chứa dữ liệu liên lạc từ từng nguồn khác nhau.
- IContactAdapter: Giao diện trừu tượng với phương thức
getContacts()
. - JSONContactAdapter và XMLContactAdapter: Lớp thực thi để lấy dữ liệu từ hai nguồn dữ liệu khác nhau.
ContactSection
ContactSection
là widget hiển thị danh sách liên lạc. Nó nhận vào một đối tượng IContactAdapter
và có thể tải dữ liệu từ nhiều nguồn khác nhau mà không cần phụ thuộc vào cách thức lấy dữ liệu.
Kết Luận
Mẫu thiết kế Adapter cho phép chúng ta kết nối các thành phần không tương thích một cách dễ dàng và hiệu quả. Với khả năng mở rộng và tính linh hoạt cao, Adapter là một trong những mẫu thiết kế quan trọng trong lập trình ứng dụng. Hãy cùng chờ đón phần tiếp theo của chuỗi bài viết, nơi chúng ta sẽ khám phá mẫu thiết kế Template Method - "Quy trình tạo nên chìa khóa"!
source: viblo