代理模式 是一种结构型设计模式,它为其他对象提供一个代理或占位符,以控制对这个对象的访问。代理模式的核心思想是通过一个代理对象间接访问目标对象,从而在不改变目标对象的情况下增强其功能。
代理模式的核心角色包括:
-
抽象主题(Subject):定义目标对象和代理对象的共同接口,客户端通过该接口与目标对象交互。
-
真实主题(Real Subject):实际的目标对象,代理对象最终会调用它的方法。
-
代理(Proxy):实现与目标对象相同的接口,并持有对目标对象的引用。 以下是我写的一个简单的代理模式例子,用于控制对论坛用户(
ForumUser
)的访问。通过ForumProxy
类,游客(Guest)和已注册用户(RegisteredUser)可以以不同的方式访问论坛功能。public class ForumDemo { public static void main(String[] args) { // 游客只能通过代理访问 ForumUser guestUser = new ForumProxy("Guest"); guestUser.postMessage("This should not work for a guest"); // 已注册用户可以直接访问 RegisteredUser registeredUser = new RegisteredUser("Alice"); registeredUser.postMessage("Hello, everyone!"); } } class ForumProxy implements ForumUser { private String username; private RegisteredUser user; public ForumProxy(String username) { this.username = username; } @Override public void postMessage(String message) { if (user == null) { user = new RegisteredUser(username); } user.postMessage(message); } @Override public void editProfile(String profile) { if (user == null) { user = new RegisteredUser(username); } user.editProfile(profile); } @Override public void editPost(String postId, String newContent) { if (user == null) { user = new RegisteredUser(username); } user.editPost(postId, newContent); } } interface ForumUser { void postMessage(String message); void editProfile(String profile); void editPost(String postId, String newContent); } class RegisteredUser implements ForumUser { private String username; public RegisteredUser(String username) { this.username = username; } @Override public void postMessage(String message) { System.out.println(username + " posted a message: " + message); } @Override public void editProfile(String profile) { System.out.println(username + " updated profile: " + profile); } @Override public void editPost(String postId, String newContent) { System.out.println(username + " edited post " + postId + ": " + newContent); } }
这个例子有个不合理的地方,当游客(Guest)通过代理访问时,会自动创建一个
RegisteredUser
对象,让游客也可以发帖。应该限制游客的权限,禁止其发帖或编辑内容。还可以对代码进行优化,再加入一些新的功能比如删帖和查看帖子。 优化后的代码如下:public class ForumDemo { public static void main(String[] args) { // 游客只能通过代理访问 ForumUser guestUser = new ForumProxy("Guest"); guestUser.postMessage("This should not work for a guest"); guestUser.editProfile("New profile"); guestUser.editPost("123", "New content"); guestUser.deletePost("123"); guestUser.viewPost("123"); System.out.println("-----------------------------"); // 已注册用户可以直接访问 ForumUser registeredUser = new ForumProxy("Alice"); registeredUser.postMessage("Hello, everyone!"); registeredUser.editProfile("Updated profile"); registeredUser.editPost("456", "Updated content"); registeredUser.deletePost("456"); registeredUser.viewPost("456"); } } public class ForumProxy implements ForumUser { private String username; private RegisteredUser user; public ForumProxy(String username) { this.username = username; if (!username.equals("Guest")) { user = new RegisteredUser(username); } } @Override public void postMessage(String message) { System.out.println("Log: Attempt to post message by " + username); if (username.equals("Guest")) { System.out.println("Guests are not allowed to post messages."); } else { user.postMessage(message); } } @Override public void editProfile(String profile) { System.out.println("Log: Attempt to edit profile by " + username); if (username.equals("Guest")) { System.out.println("Guests are not allowed to edit profiles."); } else { user.editProfile(profile); } } @Override public void editPost(String postId, String newContent) { System.out.println("Log: Attempt to edit post by " + username); if (username.equals("Guest")) { System.out.println("Guests are not allowed to edit posts."); } else { user.editPost(postId, newContent); } } @Override public void deletePost(String postId) { System.out.println("Log: Attempt to delete post by " + username); if (username.equals("Guest")) { System.out.println("Guests are not allowed to delete posts."); } else { user.deletePost(postId); } } @Override public void viewPost(String postId) { System.out.println("Log: Attempt to view post by " + username); if (username.equals("Guest")) { System.out.println("Guest is viewing post " + postId); } else { user.viewPost(postId); } } } public interface ForumUser { void postMessage(String message); // 发帖 void editProfile(String profile); // 编辑个人资料 void editPost(String postId, String newContent); // 编辑帖子 void deletePost(String postId); // 删除帖子 void viewPost(String postId); // 查看帖子 } public class RegisteredUser implements ForumUser { private String username; public RegisteredUser(String username) { this.username = username; } @Override public void postMessage(String message) { System.out.println(username + " posted a message: " + message); } @Override public void editProfile(String profile) { System.out.println(username + " updated profile: " + profile); } @Override public void editPost(String postId, String newContent) { System.out.println(username + " edited post " + postId + ": " + newContent); } @Override public void deletePost(String postId) { System.out.println(username + " deleted post " + postId); } @Override public void viewPost(String postId) { System.out.println(username + " is viewing post " + postId); } }
运行结果:
新增方法
deletePost(String postId)
:删除指定帖子和viewPost(String postId)
:查看指定帖子。游客(Guest)只能查看帖子,不能发帖、编辑帖子、删除帖子或编辑个人资料;已注册用户可以执行所有操作。每次操作都会记录日志,便于跟踪用户行为。