简单代理模式:
图片来源
image.png
image.png


首先看看什么是代理模式。

一 代理模式

  1. 使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

介绍

意图:为其他对象提供一种代理以控制对这个对象的访问。 主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。 何时使用:想在访问一个类时做一些控制。 如何解决:增加中间层。 关键代码:实现与被代理类组合。 应用实例: 1、Windows 里面的快捷方式。 2、猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。 3、买火车票不一定在火车站买,也可以去代售点。 4、一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。 5、spring aop。 优点: 1、职责清晰。 2、高扩展性。 3、智能化。 缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。 使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。 注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

二 静态模式

  1. 要求被代理类和代理类同时实现相应的一套接口,通过代理类调用重写接口的方法,实际上调用的是原始对象的同样的方法。如下图:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2755207/1642834835020-f93621f1-78e0-4153-bb0d-cdf3596bed9a.png#clientId=u9608c84f-5a72-4&from=paste&height=224&id=u0bc48149&margin=%5Bobject%20Object%5D&name=image.png&originHeight=224&originWidth=480&originalType=binary&ratio=1&size=49300&status=done&style=none&taskId=u79517b08-d3d5-494e-a8a6-99c4647ad6b&width=480)

Cilent调用Source的method()方法,实际上是Proxy来调用method()方法,静态代理中Source跟Proxy都要实现接口Sourceable。

三 测试

首先是父接口
Animal.java

  1. package com.lxj.proxy;
  2. public interface Animal {
  3. public void action();
  4. public void breath();
  5. }

Cat.java

  1. package com.lxj.proxy;
  2. //被代理类Cat
  3. public class Cat implements Animal{
  4. @Override
  5. public void action() {
  6. System.out.println("喵喵喵~~~~");
  7. }
  8. @Override
  9. public void breath() {
  10. System.out.println("猫式呼吸法~~~~");
  11. }
  12. }

CatProxy.java

  1. package com.lxj.proxy;
  2. //代理类
  3. public class CatProxy implements Animal{
  4. //真正要代理的类
  5. Cat cat;
  6. public CatProxy(Cat cat){
  7. this.cat = cat;
  8. }
  9. @Override
  10. public void action() {
  11. System.out.println("==========DogProxy 代理类执行开始!=============");
  12. //实质上在代理类中是调用了被代理实现接口的方法
  13. cat.action();
  14. System.out.println("==========DogProxy 代理类执行结束!===========");
  15. }
  16. @Override
  17. public void breath() {
  18. System.out.println("==========DogProxy 代理类执行开始!=============");
  19. cat.breath();
  20. System.out.println("==========DogProxy 代理类执行结束!===========");
  21. }
  22. }

TestStaticProxy.java

  1. package com.lxj.proxy;
  2. public class TestStaticProxy {
  3. public static void main(String[] args) {
  4. //被代理的类Cat,Cat实现了Animal接口
  5. Cat cat = new Cat();
  6. //代理类CatProxy,也实现了Animal接口
  7. CatProxy catProxy = new CatProxy(cat);
  8. //代理类来调用方法,实际上调用的是Cat的action(),breath()方法
  9. catProxy.action();
  10. catProxy.breath();
  11. }
  12. }

运行结果如下:
image.png

从运行结果可以看到其实执行的是被代理类的对象.

从这里我们会想,如果我想再创建一个Dog对象,又需要重新为Dog创建一个代理对象,如下:
Dog.java

  1. package com.lxj.proxy;
  2. //被代理类 Dog
  3. public class Dog implements Animal {
  4. @Override
  5. public void action() {
  6. System.out.println("汪汪汪~~~~~");
  7. }
  8. @Override
  9. public void breath() {
  10. System.out.println("狗式呼吸法~~~~");
  11. }
  12. }

DogProxy.java

  1. package com.lxj.proxy;
  2. //Dog的代理类
  3. public class DogProxy implements Animal {
  4. Dog dog;
  5. public DogProxy(Dog dog) {
  6. this.dog = dog;
  7. }
  8. @Override
  9. public void action() {
  10. System.out.println("==========DogProxy 代理类执行开始!=============");
  11. dog.action();
  12. System.out.println("==========DogProxy 代理类执行结束!===========");
  13. }
  14. @Override
  15. public void breath() {
  16. System.out.println("==========DogProxy 代理类执行开始!=============");
  17. dog.breath();
  18. System.out.println("==========DogProxy 代理类执行结束!===========");
  19. }
  20. }

TestStaticProxy.java

  1. package com.lxj.proxy;
  2. public class TestStaticProxy {
  3. public static void main(String[] args) {
  4. Cat cat = new Cat();
  5. CatProxy catProxy = new CatProxy(cat);
  6. catProxy.action();
  7. catProxy.breath();
  8. Dog dog = new Dog();
  9. DogProxy dogProxy = new DogProxy(dog);
  10. dogProxy.action();
  11. dogProxy.breath();
  12. }
  13. }

运行结果如下:
image.png