Proxy Pattern là một mẫu thiết kế thuộc nhóm Structural Patterns (mẫu cấu trúc), được sử dụng để cung cấp một đại diện hoặc thay thế cho một đối tượng khác nhằm kiểm soát truy cập đến đối tượng đó. Proxy giúp quản lý quyền truy cập, thêm chức năng bổ sung hoặc thực hiện các hành động trước và sau khi tương tác với đối tượng thật.
Trong Proxy Pattern, có hai đối tượng chính:
Proxy có thể thực hiện các nhiệm vụ như:
Bạn nên sử dụng Proxy Pattern trong các trường hợp sau:
// Interface Subject public interface Image { void display(); } // Real Subject: Đối tượng thực sự public class RealImage implements Image { private String fileName; public RealImage(String fileName) { this.fileName = fileName; loadFromDisk(); } private void loadFromDisk() { System.out.println("Loading image from disk: " + fileName); } @Override public void display() { System.out.println("Displaying image: " + fileName); } } // Proxy: Đối tượng đại diện public class ProxyImage implements Image { private RealImage realImage; private String fileName; public ProxyImage(String fileName) { this.fileName = fileName; } @Override public void display() { // Chỉ khởi tạo đối tượng thật khi cần thiết (lazy initialization) if (realImage == null) { realImage = new RealImage(fileName); } realImage.display(); } } // Sử dụng Proxy Pattern public class Main { public static void main(String[] args) { Image image = new ProxyImage("test_image.jpg"); // Tải ảnh từ đĩa chỉ khi cần hiển thị System.out.println("Image will be displayed now."); image.display(); // Lần đầu tiên, ảnh được tải từ đĩa System.out.println("Image will be displayed again."); image.display(); // Lần sau, ảnh không cần phải tải lại } }
display
được gọi. Điều này giúp tối ưu hóa hiệu suất khi đối tượng thật chỉ được khởi tạo khi cần thiết.main
, đối tượng ProxyImage sẽ kiểm soát việc khởi tạo và hiển thị hình ảnh. Khi ảnh được hiển thị lần đầu tiên, nó sẽ được tải từ đĩa. Tuy nhiên, khi hiển thị lại, đối tượng thật không cần phải tải lại ảnh, giúp tối ưu hóa tài nguyên.Giả sử bạn có một hệ thống bảo mật và chỉ cho phép một số người dùng truy cập vào một tài nguyên cụ thể. Bạn có thể sử dụng Proxy Pattern để kiểm soát quyền truy cập này.
// Interface Subject public interface Database { void access(String userRole); } // Real Subject: Đối tượng thực sự public class RealDatabase implements Database { @Override public void access(String userRole) { System.out.println("Accessing database..."); } } // Proxy: Đối tượng đại diện public class DatabaseProxy implements Database { private RealDatabase realDatabase = new RealDatabase(); @Override public void access(String userRole) { if (userRole.equals("ADMIN")) { realDatabase.access(userRole); } else { System.out.println("Access denied: You do not have the required permissions."); } } } // Sử dụng Proxy Pattern public class Main { public static void main(String[] args) { Database database = new DatabaseProxy(); System.out.println("User with role USER:"); database.access("USER"); // Quyền truy cập bị từ chối System.out.println("User with role ADMIN:"); database.access("ADMIN"); // Truy cập thành công } }
main
, proxy sẽ kiểm tra vai trò của người dùng trước khi cho phép họ truy cập vào cơ sở dữ liệu.Proxy Pattern là một mẫu thiết kế mạnh mẽ giúp bạn kiểm soát truy cập và tối ưu hóa tài nguyên khi làm việc với các đối tượng phức tạp. Nó giúp tách biệt logic quản lý truy cập ra khỏi đối tượng thật và dễ dàng bổ sung các chức năng bổ sung mà không làm thay đổi cấu trúc hiện tại của đối tượng.