设计模式之代理模式详解(定义、优缺点、应用场景、实例类图)
时间:2024-12-09 来源:互联网 标签: PHP教程
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能,这种类型的设计模式属于结构型模式。代理模式通过引入一个代理对象来控制对原对象的访问。代理对象在客户端和目标对象之间充当中介,负责将客户端的请求转发给目标对象,同时可以在转发请求前后进行额外的处理。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
一、代理模式的介绍
意图
为其他对象提供一种代理以控制对这个对象的访问。
主要解决的问题
代理模式解决的是在直接访问某些对象时可能遇到的问题,例如对象创建成本高、需要安全控制或远程访问等。
使用场景
当需要在访问一个对象时进行一些控制或额外处理时。
实现方式
增加中间层:创建一个代理类,作为真实对象的中间层。
代理与真实对象组合:代理类持有真实对象的引用,并在访问时进行控制。
关键代码
代理类:实现与真实对象相同的接口,并添加额外的控制逻辑。
真实对象:实际执行任务的对象。
结构
主要涉及到以下几个核心角色:
抽象主题(Subject):
定义了真实主题和代理主题的共同接口,这样在任何使用真实主题的地方都可以使用代理主题。
真实主题(Real Subject):
实现了抽象主题接口,是代理对象所代表的真实对象。客户端直接访问真实主题,但在某些情况下,可以通过代理主题来间接访问。
代理(Proxy):
实现了抽象主题接口,并持有对真实主题的引用。代理主题通常在真实主题的基础上提供一些额外的功能,例如延迟加载、权限控制、日志记录等。
客户端(Client):
使用抽象主题接口来操作真实主题或代理主题,不需要知道具体是哪一个实现类。
应用实例
快捷方式:Windows系统中的快捷方式作为文件或程序的代理。
角色扮演:孙悟空作为高翠兰的代理,猪八戒无法区分。
代售点:购买火车票时,代售点作为火车站的代理。
支票:作为银行账户资金的代理,控制资金的访问。
Spring AOP:使用代理模式来实现面向切面编程。
二、代理模式的优缺点
优点
职责分离:代理模式将访问控制与业务逻辑分离。
扩展性:可以灵活地添加额外的功能或控制。
智能化:可以智能地处理访问请求,如延迟加载、缓存等。
缺点
性能开销:增加了代理层可能会影响请求的处理速度。
实现复杂性:某些类型的代理模式实现起来可能较为复杂。
三、代理模式的使用建议
根据具体需求选择合适的代理类型,如远程代理、虚拟代理、保护代理等。
确保代理类与真实对象接口一致,以便客户端透明地使用代理。
与适配器模式的区别:适配器模式改变接口,而代理模式不改变接口。
与装饰器模式的区别:装饰器模式用于增强功能,代理模式用于控制访问。
四、代理模式的实现
我们将创建一个 Image 接口和实现了 Image 接口的实体类。ProxyImage 是一个代理类,减少 RealImage 对象加载的内存占用。
ProxyPatternDemo 类使用 ProxyImage 来获取要加载的 Image 对象,并按照需求进行显示。
步骤 1:创建一个接口。
Image.java
publicinterfaceImage{
voiddisplay();
}
步骤 2:创建实现接口的实体类。
RealImage.java
publicclassRealImageimplementsImage{
privateStringfileName;
publicRealImage(StringfileName){
this.fileName=fileName;
loadFromDisk(fileName);
}
@Override
publicvoiddisplay(){
System.out.println("Displaying"+fileName);
}
privatevoidloadFromDisk(StringfileName){
System.out.println("Loading"+fileName);
}
}
ProxyImage.java
publicclassProxyImageimplementsImage{
privateRealImagerealImage;
privateStringfileName;
publicProxyImage(StringfileName){
this.fileName=fileName;
}
@Override
publicvoiddisplay(){
if(realImage==null){
realImage=newRealImage(fileName);
}
realImage.display();
}
}
步骤 3:当被请求时,使用 ProxyImage 来获取 RealImage 类的对象。
ProxyPatternDemo.java
publicclassProxyPatternDemo{
publicstaticvoidmain(String[]args){
Imageimage=newProxyImage("test_10mb.jpg");
//图像将从磁盘加载
image.display();
System.out.println("");
//图像不需要从磁盘加载
image.display();
}
}
步骤 4:执行程序,输出结果:
Loadingtest_10mb.jpg
Displayingtest_10mb.jpg
Displayingtest_10mb.jpg
以上就是php小编整理的全部内容,希望对您有所帮助,更多相关资料请查看php教程栏目。
-
永劫无间多少钱一个红 2024-12-20
-
永劫无间多少钱开一个箱子 2024-12-20
-
阿瑞斯病毒2火铳弹药怎么获得?阿瑞斯病毒2火铳弹药获得方法 2024-12-19
-
阿瑞斯病毒2哈士奇在哪?阿瑞斯病毒2哈士奇获得方法 2024-12-19
-
寻道大千反击流阵容推荐 2024-12-19
-
和平精英性别怎么换?和平精英性别转换方法 2024-12-19