Design Pattern | Proxy Pattern
Có những lúc trong cuộc sống, việc sử dụng một trình giữ chỗ (placeholder) để đại diện cho một cái gì đó hoặc người khác dễ dàng hơn, an toàn hơn và thuận tiện hơn. Đại diện cá nhân có thể được gửi để thay mặt công ty tại một hội nghị. Người giả thử nghiệm va chạm được thử nghiệm để ngay người thật thử nghiệm va chạm xe, và thẻ tín dụng là một hình thức thanh toán thay cho tiền mặt.
Trong mỗi tình huống, mỗi đối tượng được đại diện bởi một proxy object. Proxy hoạt động như một phiên bản đơn giản hoặc nhe hơn của đối tượng ban đầu, mỗi đối tưọng proxy vẫn có thể hoàn thành các nhiệm vụ tương tự, nhưng có thể ủy thác yêu cầu cho đối tượng ban đầu để đạt được chúng.
Chúng ta gặp phải các vấn đề tương tự trong hệ thống phần mềm, nơi tốt hơn là xử dụng một đối tượng proxy thay cho bản gốc. Đây là mục tiêu của Proxy Pattern, cho phép một lớp proxy đại diện cho một lớp chủ đề thực sự, trong mẫu thiết kế này, lớp proxy bao bọc lớp chủ đề thực, nghĩa là ẩn một tham chiếu đến một thể hiện của lớp chủ đề thực. Lớp chủ đề thực là một phần trong hệ thống của bạn, ví dụ, có thể chứa thông tin nhạy cảm hoặc sẽ tốn nhiều tài nguyên để khởi tạo, vì lớp proxy hoạt động như một lớp bao bọc, các lớp máy khách sẽ tương tác với nó thay vì lớp chủ đề thực sự.
Tại sao chúng ta muốn sử dụng một lớp proxy ? Ba kịch bản phổ biến nhất của chúng là:
Đầu tiên, để hoạt động một proxy ảo (virual proxy) trong đó một lớp proxy được sử dụng thay cho một lớp chủ đề thực, đó là tài nguyên cần nhiều khởi tạo, điều này thường được sử dụng trên hình ảnh, các trang web hoặc trình chỉnh sửa đồ họa, bởi vì một hình ảnh độ nét cao nguyên bản có thể có dung lượng cực kỳ lớn, nếu bạn tải tất cả hình này cùng một lúc, nó có thể gây căng thẳng cho tài nguyên hệ thống của bạn.
Hai, hoạt động như một proxy bảo vệ (protection proxy) để kiểm soát quyền truy cập vào một chủ đề thực, một proxy bảo vệ có thể được sử dụng trong hệ thống quản lý học tập kiểm tra thông tin đăng nhập của người dùng, vì vậy, những người dùng khác nhau, như sinh viên và người hướng dẫn, chỉ có thể truy cập các chức năng phù hợp được cho phép với vai trò của họ.
Và ba là, để hoạt động như một proxy từ xa (remote proxy), trong đó lớp proxy là cục bộ và lớp chủ đề thực sự tồn tại ở xa, hãy nghĩ về điều này giống như làm việc trên một tài liệu của Google Document nơi trình duyệt web của bạn có tất cả các đối tượng cần thiết cục bộ, cũng tồn tại trên máy chủ của Google ở một nơi khác.
Chúng ta hãy xem các lớp và cấu trúc trung của Proxy Pattern trên đây. Lớp proxy bao phủ và có thể được ủy nhiệm(delegate) hoặc chuyển hướng các cuộc gọi theo nó đến các đối tượng thực. Tuy nhiên, không phải tất cả các cuộc gọi (call lệnh) đều được ủy quyền vì lớp proxy được cho là hoạt động như một phiên bản nhẹ hơn của lớp chủ đề thực sự và có thể thực hiện một số trách nhiệm sau này. Lớp proxy sẽ chỉ chuyển hướng các yêu cầu thực chất hơn đến lớp chủ đề thực. Nhưng, những yêu cầu nào (cuộc gọi) cần được hỗ trợ trong lớp proxy ? Vì lớp proxy đại diện cho lớp chủ đề thực, nên nó phải cung cấp các phương thức tương tự.
Bạn có thể đảm bảo rằng bằng cách cả hai lớp này thực hiện một giao diện chủ đề chung, cũng cho phép đa hình. Vì lớp proxy và lớp chủ đề thực đều là loại con của chủ đề, nên lớp khách có thể tương tác với proxy, lớp này có giao diện dự kiến giống chủ đề thực.
Chúng ta hãy xem một ứng dụng thực tế của proxy qua ví dụ trên. Giả sử bạn điều hành một cửa hàng bán lẻ trực tuyến với phân phối và có kho lưu trữ toàn cầu, làm thế nào bạn biết kho hàng nào để định tuyến các đơn đặt hàng để thực hiện đơn đặt hàng của khách hàng ?
Bạn có thể gặp vấn đề trong đó bạn định tuyến các đơn đặt hàng đến một kho không có kho cho một mặt hàng trong đơn đặt hàng của khách hàng, bạn cần một số cách để xác định kho nào sẽ gửi đơn đặt hàng đến. Một hệ thống định tuyến thực hiện đầy đủ đơn hàng đến một kho thích hợp sẽ ngăn kho của bạn nhận đơn đặt hàng mà chúng không thể fill .. Vì vậy, thực hiện hệ thống này như thế nào ?
Bạn có thể sử dụng Proxy Pattern để có proxy bảo vệ chủ thể thực của bạn, warehouses, khỏi nhận đơn đặt hàng nếu kho không có đủ hàng để thực hiện đơn hàng. Giao diện IOrder xác định cách bạn sẽ thực hiện các đơn đặt hàng, lớp proxy và lớp chủ đề thực sẽ triển khai giao diện khác nhau.
Interface khai báo với hệ thống cách thực hiện đơn hàng của bạn, lớp OrderFulllfillment đóng vai trò là ủy quyền cho tất cả các kho của bạn, nó có một danh sách các kho mà nó có thể ủy thác các bộ phận đơn đặt hàng của khách hàng tùy thuộc vào việc một kho có khả năng đáp ứng một phần của đơn đặt hàng hay không. Lớp warehouse là lớp chủ đề thực sự của bạn và sẽ chịu trách nhiệm xử lý và thực hiện các phần đơn đặt hàng của khách hàng. Lớp kho sẽ báo cáo hàng tổn kho của nó với proxy yêu cầu của nó. Như thể hiện trong tổng quan của Proxy Pattern, máy khách sẽ tương tác với hệ thống của bạn bằng cách sử dụng giao diện IOrder. Bây giờ, ta sẽ triển khai nó trên JAVA:
Bước 1, thiết kế giao diện chủ đề. Tạo giao diện mà phần mềm máy khách sẽ sử dụng để tương tác với hệ thống của bạn. Giao diện này sẽ được implement bởi các lớp fullfillment và warehouse class.
Bước 2, thực hiện lớp chủ đề thực sự. Lớp warehouse biết cách xử lý một đơn đặt hàng (order) để thực hiện và nó biết cách báo cáo kho hàng hiện tại. Lưu ý rằng không cần kiểm tra xem nó có đủ hàng (stock to fullfill) để thực hiện không, bởi vì đơn hàng chỉ được gửi đến warehouse nếu nó có thể thực hiện.
Bước 3, thực hiện lớp proxy. Lớp order fulfillment thực hiện tất cả các công việc kiểm tra kho hàng và đảm bảo rằng một đơn hàng có thể được hoàn thành trước khi gửi yêu cầu đến kho. Nó sẽ hỏi mỗi kho về việc nó có đủ cho một mặt hàng cụ thể không, nếu kho đủ hàng tồn kho (stock item), item được thêm vào new order object để sẽ được gửi đến warehouse.
Lớp proxy đảm bảo rằng một order có thể được fullfill trước khi gửi yêu cầu đến kho của bạn. Điều này bảo vệ hệ thống kho của bạn khỏi việc nhận đơn đặt hàng mà nó không thể thực hiện. Lớp fulfillment cũng cho phép bạn tách xác thực đơn hàng bằng cách chia thành 2 phần. Điều này sẽ cải thiện tỷ lệ xử lý đơn hàng chung vì kho không phải lo lắng về quy trình xác nhận. Mỗi kho riêng lẻ (order fulfillment class) cũng không cần phải lo lắng về cách định tuyến lại đơn hàng nếu kho không thể thực hiện được đơn hàng. Lớp order fulfillment có thể được cải thiện với các chức năng khác, chẳng hạn như: ưu tiên gửi đơn đặt hàng đến kho dựa trên sự gần gũi với khách hàng để đảm bảo đơn hàng đến nhanh nhất có thể.
Proxy Pattern rất hữu ích khi bạn cần trì hoãn việc tạo các đối tượng cần nhiều tài nguyên cho đến khi cần, kiểm soát quyền truy cập vào các đối tượng cụ thể hoặc khi bạn cần một cái gì đó để hoạt động như một đại diện cục bộ của một hệ thống từ xa, tóm lại, các tính năng chính của Proxy Pattern là: sử dụng lớp proxy để bọc một lớp chủ đề thực, có thiết kế đa hình để lớp khách có thể mong đợi cùng một giao diện cho lớp chủ đề proxy và lớp thực, sử dụng một proxy nhẹ thay cho một đối tượng sử dụng nhiều tài nguyên cho đến khi thực sự cần thiết, để thực hiện một số hình thức xác minh thông minh các yêu cầu từ code client để xác định xem cách thức và yêu cầu nên được chuyển đến ai và để trình bày đại diện cục bộ của một hệ thống không nằm trong cùng một không gian vật lý hoặc ảo.
Proxy Pattern cung cấp cho hệ thống của bạn một phương tiện gián tiếp mạnh mẽ, và có thể cho phép xây dựng các hệ thống an toàn hơn và ít tốn tài nguyên hơn.
Cảm ơn.
Trong mỗi tình huống, mỗi đối tượng được đại diện bởi một proxy object. Proxy hoạt động như một phiên bản đơn giản hoặc nhe hơn của đối tượng ban đầu, mỗi đối tưọng proxy vẫn có thể hoàn thành các nhiệm vụ tương tự, nhưng có thể ủy thác yêu cầu cho đối tượng ban đầu để đạt được chúng.
Chúng ta gặp phải các vấn đề tương tự trong hệ thống phần mềm, nơi tốt hơn là xử dụng một đối tượng proxy thay cho bản gốc. Đây là mục tiêu của Proxy Pattern, cho phép một lớp proxy đại diện cho một lớp chủ đề thực sự, trong mẫu thiết kế này, lớp proxy bao bọc lớp chủ đề thực, nghĩa là ẩn một tham chiếu đến một thể hiện của lớp chủ đề thực. Lớp chủ đề thực là một phần trong hệ thống của bạn, ví dụ, có thể chứa thông tin nhạy cảm hoặc sẽ tốn nhiều tài nguyên để khởi tạo, vì lớp proxy hoạt động như một lớp bao bọc, các lớp máy khách sẽ tương tác với nó thay vì lớp chủ đề thực sự.
Tại sao chúng ta muốn sử dụng một lớp proxy ? Ba kịch bản phổ biến nhất của chúng là:
Đầu tiên, để hoạt động một proxy ảo (virual proxy) trong đó một lớp proxy được sử dụng thay cho một lớp chủ đề thực, đó là tài nguyên cần nhiều khởi tạo, điều này thường được sử dụng trên hình ảnh, các trang web hoặc trình chỉnh sửa đồ họa, bởi vì một hình ảnh độ nét cao nguyên bản có thể có dung lượng cực kỳ lớn, nếu bạn tải tất cả hình này cùng một lúc, nó có thể gây căng thẳng cho tài nguyên hệ thống của bạn.
Hai, hoạt động như một proxy bảo vệ (protection proxy) để kiểm soát quyền truy cập vào một chủ đề thực, một proxy bảo vệ có thể được sử dụng trong hệ thống quản lý học tập kiểm tra thông tin đăng nhập của người dùng, vì vậy, những người dùng khác nhau, như sinh viên và người hướng dẫn, chỉ có thể truy cập các chức năng phù hợp được cho phép với vai trò của họ.
Và ba là, để hoạt động như một proxy từ xa (remote proxy), trong đó lớp proxy là cục bộ và lớp chủ đề thực sự tồn tại ở xa, hãy nghĩ về điều này giống như làm việc trên một tài liệu của Google Document nơi trình duyệt web của bạn có tất cả các đối tượng cần thiết cục bộ, cũng tồn tại trên máy chủ của Google ở một nơi khác.
Chúng ta hãy xem các lớp và cấu trúc trung của Proxy Pattern trên đây. Lớp proxy bao phủ và có thể được ủy nhiệm(delegate) hoặc chuyển hướng các cuộc gọi theo nó đến các đối tượng thực. Tuy nhiên, không phải tất cả các cuộc gọi (call lệnh) đều được ủy quyền vì lớp proxy được cho là hoạt động như một phiên bản nhẹ hơn của lớp chủ đề thực sự và có thể thực hiện một số trách nhiệm sau này. Lớp proxy sẽ chỉ chuyển hướng các yêu cầu thực chất hơn đến lớp chủ đề thực. Nhưng, những yêu cầu nào (cuộc gọi) cần được hỗ trợ trong lớp proxy ? Vì lớp proxy đại diện cho lớp chủ đề thực, nên nó phải cung cấp các phương thức tương tự.
Bạn có thể đảm bảo rằng bằng cách cả hai lớp này thực hiện một giao diện chủ đề chung, cũng cho phép đa hình. Vì lớp proxy và lớp chủ đề thực đều là loại con của chủ đề, nên lớp khách có thể tương tác với proxy, lớp này có giao diện dự kiến giống chủ đề thực.
Chúng ta hãy xem một ứng dụng thực tế của proxy qua ví dụ trên. Giả sử bạn điều hành một cửa hàng bán lẻ trực tuyến với phân phối và có kho lưu trữ toàn cầu, làm thế nào bạn biết kho hàng nào để định tuyến các đơn đặt hàng để thực hiện đơn đặt hàng của khách hàng ?
Bạn có thể gặp vấn đề trong đó bạn định tuyến các đơn đặt hàng đến một kho không có kho cho một mặt hàng trong đơn đặt hàng của khách hàng, bạn cần một số cách để xác định kho nào sẽ gửi đơn đặt hàng đến. Một hệ thống định tuyến thực hiện đầy đủ đơn hàng đến một kho thích hợp sẽ ngăn kho của bạn nhận đơn đặt hàng mà chúng không thể fill .. Vì vậy, thực hiện hệ thống này như thế nào ?
Bạn có thể sử dụng Proxy Pattern để có proxy bảo vệ chủ thể thực của bạn, warehouses, khỏi nhận đơn đặt hàng nếu kho không có đủ hàng để thực hiện đơn hàng. Giao diện IOrder xác định cách bạn sẽ thực hiện các đơn đặt hàng, lớp proxy và lớp chủ đề thực sẽ triển khai giao diện khác nhau.
Interface khai báo với hệ thống cách thực hiện đơn hàng của bạn, lớp OrderFulllfillment đóng vai trò là ủy quyền cho tất cả các kho của bạn, nó có một danh sách các kho mà nó có thể ủy thác các bộ phận đơn đặt hàng của khách hàng tùy thuộc vào việc một kho có khả năng đáp ứng một phần của đơn đặt hàng hay không. Lớp warehouse là lớp chủ đề thực sự của bạn và sẽ chịu trách nhiệm xử lý và thực hiện các phần đơn đặt hàng của khách hàng. Lớp kho sẽ báo cáo hàng tổn kho của nó với proxy yêu cầu của nó. Như thể hiện trong tổng quan của Proxy Pattern, máy khách sẽ tương tác với hệ thống của bạn bằng cách sử dụng giao diện IOrder. Bây giờ, ta sẽ triển khai nó trên JAVA:
Bước 1, thiết kế giao diện chủ đề. Tạo giao diện mà phần mềm máy khách sẽ sử dụng để tương tác với hệ thống của bạn. Giao diện này sẽ được implement bởi các lớp fullfillment và warehouse class.
Bước 2, thực hiện lớp chủ đề thực sự. Lớp warehouse biết cách xử lý một đơn đặt hàng (order) để thực hiện và nó biết cách báo cáo kho hàng hiện tại. Lưu ý rằng không cần kiểm tra xem nó có đủ hàng (stock to fullfill) để thực hiện không, bởi vì đơn hàng chỉ được gửi đến warehouse nếu nó có thể thực hiện.
Bước 3, thực hiện lớp proxy. Lớp order fulfillment thực hiện tất cả các công việc kiểm tra kho hàng và đảm bảo rằng một đơn hàng có thể được hoàn thành trước khi gửi yêu cầu đến kho. Nó sẽ hỏi mỗi kho về việc nó có đủ cho một mặt hàng cụ thể không, nếu kho đủ hàng tồn kho (stock item), item được thêm vào new order object để sẽ được gửi đến warehouse.
Lớp proxy đảm bảo rằng một order có thể được fullfill trước khi gửi yêu cầu đến kho của bạn. Điều này bảo vệ hệ thống kho của bạn khỏi việc nhận đơn đặt hàng mà nó không thể thực hiện. Lớp fulfillment cũng cho phép bạn tách xác thực đơn hàng bằng cách chia thành 2 phần. Điều này sẽ cải thiện tỷ lệ xử lý đơn hàng chung vì kho không phải lo lắng về quy trình xác nhận. Mỗi kho riêng lẻ (order fulfillment class) cũng không cần phải lo lắng về cách định tuyến lại đơn hàng nếu kho không thể thực hiện được đơn hàng. Lớp order fulfillment có thể được cải thiện với các chức năng khác, chẳng hạn như: ưu tiên gửi đơn đặt hàng đến kho dựa trên sự gần gũi với khách hàng để đảm bảo đơn hàng đến nhanh nhất có thể.
Proxy Pattern rất hữu ích khi bạn cần trì hoãn việc tạo các đối tượng cần nhiều tài nguyên cho đến khi cần, kiểm soát quyền truy cập vào các đối tượng cụ thể hoặc khi bạn cần một cái gì đó để hoạt động như một đại diện cục bộ của một hệ thống từ xa, tóm lại, các tính năng chính của Proxy Pattern là: sử dụng lớp proxy để bọc một lớp chủ đề thực, có thiết kế đa hình để lớp khách có thể mong đợi cùng một giao diện cho lớp chủ đề proxy và lớp thực, sử dụng một proxy nhẹ thay cho một đối tượng sử dụng nhiều tài nguyên cho đến khi thực sự cần thiết, để thực hiện một số hình thức xác minh thông minh các yêu cầu từ code client để xác định xem cách thức và yêu cầu nên được chuyển đến ai và để trình bày đại diện cục bộ của một hệ thống không nằm trong cùng một không gian vật lý hoặc ảo.
Proxy Pattern cung cấp cho hệ thống của bạn một phương tiện gián tiếp mạnh mẽ, và có thể cho phép xây dựng các hệ thống an toàn hơn và ít tốn tài nguyên hơn.
Cảm ơn.
Nhận xét
Đăng nhận xét