跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
代理模式
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
== 代理模式 == '''代理模式'''(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来间接访问目标对象,从而实现对目标对象的保护、延迟加载、访问控制等功能。 === 模式结构 === 代理模式包含以下主要角色: * '''Subject(抽象主题)''':声明真实主题和代理主题的共同接口,客户端通过该接口访问真实主题。 * '''RealSubject(真实主题)''':定义代理所代表的真实对象,是客户端最终要访问的对象。 * '''Proxy(代理)''':持有对真实主题的引用,控制对真实主题的访问,并可能负责创建和删除它。 <mermaid> classDiagram class Subject { +request() } class RealSubject { +request() } class Proxy { -realSubject: RealSubject +request() } Subject <|-- RealSubject Subject <|-- Proxy Proxy --> RealSubject </mermaid> === 代码示例 === 以下是一个简单的代理模式示例,展示如何通过代理控制对真实对象的访问: <syntaxhighlight lang="java"> // 抽象主题 interface Image { void display(); } // 真实主题 class RealImage implements Image { private String filename; public RealImage(String filename) { this.filename = filename; loadFromDisk(); } private void loadFromDisk() { System.out.println("Loading image: " + filename); } @Override public void display() { System.out.println("Displaying image: " + filename); } } // 代理 class ProxyImage implements Image { private RealImage realImage; private String filename; public ProxyImage(String filename) { this.filename = filename; } @Override public void display() { if (realImage == null) { realImage = new RealImage(filename); // 延迟加载 } realImage.display(); } } // 客户端代码 public class ProxyPatternDemo { public static void main(String[] args) { Image image = new ProxyImage("test.jpg"); // 图像将从磁盘加载 image.display(); System.out.println("---"); // 图像不需要再次加载 image.display(); } } </syntaxhighlight> '''输出结果:''' <pre> Loading image: test.jpg Displaying image: test.jpg --- Displaying image: test.jpg </pre> === 代理模式类型 === 代理模式有多种变体,常见的包括: 1. '''虚拟代理''':延迟创建开销大的对象(如上述图像加载示例)。 2. '''保护代理''':控制对原始对象的访问权限。 3. '''远程代理''':为位于不同地址空间的对象提供本地代表(如RPC调用)。 4. '''智能引用代理''':在访问对象时执行附加操作(如引用计数、线程安全检查等)。 === 实际应用案例 === ==== 1. Spring AOP ==== Spring框架使用代理模式实现面向切面编程(AOP)。当使用@Transactional注解时,Spring会创建目标对象的代理,在方法调用前后添加事务管理逻辑。 ==== 2. 缓存代理 ==== 代理可以用于实现缓存机制,当客户端请求数据时,代理首先检查缓存,如果存在则直接返回,否则访问真实对象并将结果缓存。 <syntaxhighlight lang="python"> class DataFetcher: def fetch_data(self, key): # 模拟耗时操作 print(f"Fetching data for key: {key}") return f"Data for {key}" class CachingProxy: def __init__(self, real_fetcher): self.real_fetcher = real_fetcher self.cache = {} def fetch_data(self, key): if key not in self.cache: self.cache[key] = self.real_fetcher.fetch_data(key) return self.cache[key] # 使用示例 fetcher = CachingProxy(DataFetcher()) print(fetcher.fetch_data("user1")) # 从真实对象获取 print(fetcher.fetch_data("user1")) # 从缓存获取 </syntaxhighlight> === 优缺点 === '''优点:''' * 可以在不修改目标对象的情况下扩展其功能 * 将客户端与目标对象分离,降低系统耦合度 * 可以实现精细化的访问控制 * 支持延迟加载和按需创建对象 '''缺点:''' * 可能增加系统复杂度 * 代理调用可能引入轻微的性能开销 * 某些代理模式实现需要生成额外类(如动态代理) === 数学表示 === 代理模式可以形式化表示为: <math> \begin{cases} Client \rightarrow Proxy & \text{客户端访问代理} \\ Proxy \rightarrow RealSubject & \text{代理在必要时访问真实对象} \\ Proxy \cong RealSubject & \text{代理与真实对象接口相同} \end{cases} </math> === 总结 === 代理模式是一种强大的设计模式,它通过引入间接层提供了对目标对象的灵活控制。理解代理模式有助于开发者设计更灵活、可维护的系统架构,特别是在需要控制对象访问或添加横切关注点时。 [[Category:计算机科学]] [[Category:面试技巧]] [[Category:设计模式]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)