Nội dung
Mục tiêu
Proxy là một mẫu thiết kế cấu trúc cho phép bạn cung cấp vật thay thế hoặc trình giữ chỗ cho một đối tượng khác. Một proxy kiểm soát quyền truy cập vào đối tượng ban đầu, cho phép bạn thực hiện điều gì đó trước hoặc sau khi yêu cầu được chuyển đến đối tượng ban đầu.
Vấn đề
Tại sao bạn muốn kiểm soát quyền truy cập vào một đối tượng? Đây là một ví dụ: bạn có một đối tượng lớn tiêu thụ một lượng lớn tài nguyên hệ thống. Bạn cần nó theo thời gian, nhưng không phải lúc nào cũng vậy.
Bạn có thể triển khai khởi tạo lười biến (lazy initialization): chỉ tạo đối tượng này khi nó thực sự cần thiết. Tất cả các client của đối tượng sẽ cần thực thi một số mã khởi tạo trì hoãn. Thật không may, điều này có thể sẽ gây ra nhiều mã trùng lặp. Trong một thế giới lý tưởng, chúng ta muốn đặt mã này trực tiếp vào lớp đối tượng của chúng ta, nhưng điều đó không phải lúc nào cũng có thể. Ví dụ: lớp có thể là một phần của thư viện đóng bên thứ ba.
Giải pháp
Mẫu Proxy gợi ý rằng bạn nên tạo một lớp proxy mới với giao diện giống như một đối tượng dịch vụ gốc. Sau đó, bạn cập nhật ứng dụng của mình để ứng dụng chuyển đối tượng proxy đến tất cả các client của đối tượng ban đầu. Khi nhận được yêu cầu từ khách hàng, proxy sẽ tạo một đối tượng dịch vụ thực và ủy quyền tất cả công việc cho nó.
Nhưng lợi ích là gì? Nếu bạn cần thực thi điều gì đó trước hoặc sau logic chính của lớp, proxy cho phép bạn thực hiện điều này mà không cần thay đổi lớp đó. Vì proxy triển khai giao diện giống như lớp gốc, nó có thể được chuyển cho bất kỳ client nào mong đợi một đối tượng dịch vụ thực.
Cấu trúc
- ServiceInterface khai báo giao diện của Service. Proxy phải tuân theo giao diện này để có thể tự ngụy trang thành một đối tượng service.
- Service là một lớp cung cấp một số logic nghiệp vụ.
- Lớp Proxy có một trường tham chiếu trỏ đến một đối tượng Service. Sau khi proxy kết thúc quá trình xử lý (ví dụ: khởi tạo lười biếng, ghi nhật ký, kiểm soát truy cập, bộ nhớ đệm, v.v.), nó sẽ chuyển yêu cầu đến đối tượng Service.
Thông thường, proxy quản lý toàn bộ vòng đời của các đối tượng service của chúng. - Client phải làm việc với cả service và proxy thông qua cùng một giao diện. Bằng cách này, bạn có thể chuyển proxy vào bất kỳ mã nào yêu cầu đối tượng service.
Khả năng áp dụng
Khởi tạo lười biếng (proxy ảo). Đây là khi bạn có một đối tượng service nặng gây lãng phí tài nguyên hệ thống do luôn hoạt động, mặc dù thỉnh thoảng bạn chỉ cần nó.
Kiểm soát truy cập (proxy bảo vệ). Đây là khi bạn muốn chỉ những client cụ thể mới có thể sử dụng đối tượng service; ví dụ: khi các đối tượng của bạn là các phần quan trọng của hệ điều hành và các ứng dụng client là các ứng dụng được khởi chạy khác nhau (bao gồm cả những ứng dụng độc hại).
Thực thi cục bộ một dịch vụ từ xa (proxy từ xa). Đây là khi đối tượng service được đặt trên một máy chủ từ xa.
Yêu cầu ghi nhật ký (proxy đăng nhập). Đây là khi bạn muốn giữ lịch sử của các yêu cầu đối với đối tượng service.
Kết quả yêu cầu bộ nhớ đệm (proxy bộ nhớ đệm). Đây là lúc bạn cần lưu trữ kết quả của các yêu cầu client và quản lý vòng đời của bộ nhớ cache này, đặc biệt nếu kết quả khá lớn.
Tham chiếu thông minh. Đây là lúc bạn cần loại bỏ một đối tượng nặng khi không có ứng dụng client nào sử dụng nó.
Ưu và nhược điểm
😄😄😄
Bạn có thể kiểm soát đối tượng service mà client không biết về nó.
Bạn có thể quản lý vòng đời của đối tượng service khi client không quan tâm đến nó.
Proxy hoạt động ngay cả khi đối tượng service chưa sẵn sàng hoặc không có sẵn.
Nguyên tắc Mở / Đóng. Bạn có thể giới thiệu proxy mới mà không cần thay đổi service hoặc client.
🙁🙁🙁
Mã có thể trở nên phức tạp hơn vì bạn cần phải giới thiệu nhiều lớp mới.
Phản hồi từ service có thể bị trì hoãn.
Mối quan hệ với các mẫu khác
Adapter cung cấp một giao diện khác cho đối tượng được bao bọc, Proxy cung cấp cho nó cùng một giao diện và Decorator cung cấp cho nó một giao diện nâng cao.
Facade tương tự như Proxy ở chỗ, cả hai đều đệm một thực thể phức tạp và tự khởi tạo nó. Không giống như Facade, Proxy có giao diện giống với đối tượng service của nó, điều này làm cho chúng có thể hoán đổi cho nhau.
Decorator và Proxy có cấu trúc tương tự, nhưng nội dung rất khác nhau. Cả hai mẫu đều được xây dựng trên nguyên tắc kết hợp (composition), trong đó một đối tượng được cho là ủy quyền một số tác vụ cho đối tượng khác. Sự khác biệt là Proxy thường tự quản lý vòng đời của đối tượng service của nó, trong khi thành phần của Decorator luôn được kiểm soát bởi client.
Để lại một bình luận