为真实对象提供一个替身(Proxy),以控制对它的访问。
理解代理模式:通过 Proxy 控制对真实对象的访问,实现延迟加载、访问控制等功能
掌握远程代理、虚代理(缓存)、保护代理、智能引用等多种代理变体
理解代理与装饰器模式的区别:代理控制访问,装饰器动态增加功能
了解代理在图片懒加载、视频缓存、权限控制、远程服务调用中的应用
代理与真实服务实现同一接口,可在转发请求前后增加缓存、鉴权等控制
import java.util.List;
/** 第三方视频库接口(模拟真实服务)*/
public interface ThirdPartyYouTubeLib {
List<Video> listVideos();
Video getVideoInfo(String id);
byte[] downloadVideo(String id);
}import java.util.HashMap;
import java.util.List;
/** 缓存代理:实现同一接口,在调用真实服务前检查缓存 */
public class YouTubeCacheProxy implements ThirdPartyYouTubeLib {
private ThirdPartyYouTubeLib youtubeService;
private List<Video> listCache;
private HashMap<String, Video> videoCache = new HashMap<>();
private long listCachedTime = 0;
public YouTubeCacheProxy() {
youtubeService = new ThirdPartyYouTubeClass();
}
public List<Video> listVideos() {
if (listCache == null || System.currentTimeMillis() - listCachedTime > 3600000) {
listCache = youtubeService.listVideos();
listCachedTime = System.currentTimeMillis();
}
return listCache;
}
public Video getVideoInfo(String id) {
if (!videoCache.containsKey(id)) {
videoCache.put(id, youtubeService.getVideoInfo(id));
}
return videoCache.get(id);
}
public byte[] downloadVideo(String id) {
return youtubeService.downloadVideo(id);
}
}/** 视频数据对象 */
public class Video {
public String id;
public String title;
public String data;
public Video(String id, String title) {
this.id = id; this.title = title;
}
}/** 视频下载器:客户端使用,不感知是否使用了代理 */
public class YouTubeDownloader {
private ThirdPartyYouTubeLib factory;
public YouTubeDownloader(ThirdPartyYouTubeLib factory) {
this.factory = factory;
}
public void renderListPage() {
System.out.println("Fetching video list...");
}
public void renderVideoPage(String videoId) {
System.out.println("Fetching info for " + videoId + "...");
}
}public class Demo {
public static void main(String[] args) {
ThirdPartyYouTubeLib youtubeService =
new YouTubeCacheProxy();
YouTubeDownloader downloader =
new YouTubeDownloader(youtubeService);
downloader.renderListPage();
downloader.renderVideoPage("vid1");
downloader.renderListPage(); // 第二次调用走缓存
}
}import java.util.List;
/** 模拟真实第三方服务 */
public class ThirdPartyYouTubeClass implements ThirdPartyYouTubeLib {
public List<Video> listVideos() {
return List.of(new Video("vid1", "Design Patterns"));
}
public Video getVideoInfo(String id) {
return new Video(id, "Design Patterns");
}
public byte[] downloadVideo(String id) {
return new byte[0];
}
}YouTubeCacheProxy 实现与 ThirdPartyYouTubeLib 相同接口,客户端以为在用真实服务,实际上代理在中间层做了缓存逻辑。
首次调用 listVideos() 真实请求,后续调用直接返回缓存,避免重复网络请求和带宽消耗。
代理:控制访问(替身);装饰器:动态增加功能;适配器:转换接口。三者都是包装已有对象,目的不同。
图片懒加载(先显示占位图)、视频缓存(减少带宽)、权限控制(保护代理)、远程服务调用(远程代理如 Java RMI)、日志记录(智能引用)。