设计模式-代理模式(Proxy Pattern)
设计模式-代理模式(Proxy Pattern)
概要
记忆关键字:代理控制
定义:为其他对象提供一种代理以控制对这个对象的访问。
分析:
1)通过代理类,给对象的行为增加辅助功能的解决方案,就是代理模式
2)在程序运行时,动态地为被代理对象生成代理类,借助编程语言当中的"反射"特性。
3)动态代理可以更灵活地适应不同的接口,无需为每个被代理的类都创建一个代理类。代理对象的创建和管理由代理工具类完成,减少了手动编写代理类的工作。
类型:结构型
工厂方法模式结构图如下:
一、能解决什么问题
保护代理根据调用者的权限控制对对象的访问。例如,只有管理员才能访问某些方法。
二、涉及的角色
1. 抽象主题(Subject)
定义了真实主题和代理主题的共同接口,这样在任何使用真实主题的地方都可以使用代理主题。
代码示例如下:
1 public interface IStudentService { 3 void insertStudent(); 5 void deleteStudent(); 7 }
2. 真实主题(Real Subject)
实现了抽象主题接口,是代理对象所代表的真实对象。客户端直接访问真实主题,但在某些情况下,可以通过代理主题来间接访问。
代码示例如下:
1 public class StudentService implements IStudentService { 2 public void insertStudent(){ 3 //添加学生 4 System.out.println("添加学生"); 5 } 6 7 public void deleteStudent(){ 8 //删除学生 9 System.out.println("删除学生"); 10 } 11 }
3. 代理(Proxy)
实现了抽象主题接口,并持有对真实主题的引用。代理主题通常在真实主题的基础上提供一些额外的功能,例如延迟加载、权限控制、日志记录等。
代码示例:
1 public class StudentServiceProxy implements IStudentService { 2 3 IStudentService studentService; 4 5 public StudentServiceProxy(IStudentService studentService) { 6 this.studentService = studentService; 7 } 8 9 @Override 10 public void insertStudent() { 11 System.out.println("准备添加学生"); 12 studentService.insertStudent(); 13 System.out.println("添加学生成功"); 14 } 15 16 @Override 17 public void deleteStudent() { 18 System.out.println("准备删除学生"); 19 studentService.deleteStudent(); 20 System.out.println("删除学生成功"); 21 } 22 }
4. 客户端(Client)
1 public class Client { 2 public static void main(String[] args) { 3 IStudentService studentServiceProxy = new StudentServiceProxy(new StudentService()); 4 studentServiceProxy.insertStudent(); 5 studentServiceProxy.deleteStudent(); 6 } 7 } 8 9 //运行结果 10 准备添加学生 11 添加学生 12 添加学生成功 13 准备删除学生 14 删除学生 15 删除学生成功
使用抽象主题接口来操作真实主题或代理主题,不需要知道具体是哪一个实现类。
三、静态代理和动态代理
代理模式可以分为静态代理和动态代理两种类型,而动态代理中又分为JDK动态代理和CGLIB代理两种。下面先简单介绍下,详细介绍请参考文章《静态代理和动态代理》
1. 静态代理
在静态代理中,代理类和真实类的关系在编译阶段就已经确定。在编写代理类的时候,需要明确代理哪个具体类,代理类和被代理类之间的关系在编译时就已经确定,因此称为静态代理。
2. 动态代理
在动态代理中,代理类是在运行时动态生成的。所谓动态代理,就是在程序运行时,动态地为被代理对象生成代理类,这就需要借助编程语言当中的"反射"特性。
四、代理模式跟装饰模式的区别
1. 相同点
代理模式跟装饰模式都是把原有的类对象作为成员,放在代理类或装饰类当中去调用。
2. 区别
对于原有的类来说,装饰类是"自己人",增强的功能是对自身的增强,而代理类是"外人",增强的功能和自身并无直接关系。