代理系列的开篇,主要讲什么叫代理,什么叫代理模式。
概念:
百度了好久,没遇到满意的下定义,大白话说下个人理解:所谓的代理,便是自己无法直接完成或者直接完成需要很高成本的事情,转接给第三方,由第三方完成,而完成的效果在一定的范围内是等效的。这么一个过程,称之为代理。举个例子:
A同学 喜欢 B同学,想送花,送小礼物给她,但是太过于羞涩,让C同学代替送了。之后,每逢年过节,鲜花,礼物什么的C同学很乐意代劳,最后的最后,B 同学跟C同学可耻的在一起了。
这里,A同学是被代理方, C同学是代理方(第三方) B同学是接收方。如果抛弃B同学跟C同学在一起这残酷现实,单纯以理论分析:
A同学负责送花,送礼物,B同学负责收花,收礼物,C同学是第三方,仅起到中间媒介的作用。
代理模式:
代理模式(Proxy Pattern)是GoF 23种Java常用设计模式之一。代理模式的定义:Provide a surrogate or placeholder for another object to controlaccess to it(为其他对象提供一种代理以控制对这个对象的访问)。使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。
看懵逼了吧,这些呢都是概念,拿来装逼用的。干我们it这行的,还是以代码说话。下面的UML图:
Subject
定义RealSubject 跟proxy 需要实现的操作(例子中的:送花,送礼物), 这样,根据接口多态在使用RealSubject的地方边可使用proxy。
RealSubject
例子中A同学,真实动作的发起者,实现Subject接口。
Proxy
例子中的C同学,A同学的代理者,A同学委托C同学给B同学送花,送礼物,故,C同学也必须具有送花,这一动作,所有Proxy也实现了Subject接口,同时必须具有RealSubject 这是对象。否则,无法代理A同学,完成送花,送礼物动作。
上面UML图代码:
//代理规范动作 public interface Subject { public void operation(); }
//真实对象 public class RealSubject implements Subject{ public void operation() { System.out.println("真实操作"); } }
//代理对象 public class Proxy implements Subject{ //真实对象 private Subject subject; //使用构造函数初始化 public Proxy(Subject subject) { this.subject = subject; } //代理动作,实际上依然是调用真实对象的方法 public void operation() { System.out.println("执行真实操作前"); if(subject != null){ subject.operation(); } System.out.println("执行真实操作后"); } }
//测试 public class App { public static void main(String[] args) { RealSubject subject = new RealSubject(); Proxy proxy = new Proxy(subject); proxy.operation(); } }
例题中的代码:
//代理动作 public interface Giving { public void giveFlower(); public void giveGift(); }
//真实对象 public class StudentA implements Giving{ @Override public void giveFlower() { System.out.println("送花..."); } @Override public void giveGift() { System.out.println("送礼物..."); } }
//接受方(酱油角色) public class StudentB { }
//代理对象 public class StudentC implements Giving{ public StudentA studentA; public StudentB studnetB; //需要联系A同学, 跟B同学 public StudentC(StudentA studentA, StudentB studnetB) { super(); this.studentA = studentA; this.studnetB = studnetB; } @Override public void giveFlower() { System.out.print("C代A同学给B同学:"); studentA.giveFlower(); } @Override public void giveGift() { System.out.print("C代A同学给B同学:"); studentA.giveGift(); } }
public class App { public static void main(String[] args) { StudentA studentA = new StudentA(); StudentB studentB = new StudentB(); StudentC studentC = new StudentC(studentA, studentB); studentC.giveFlower(); studentC.giveGift(); } }
最后总结:
代理模式重点
1、代理动作接口的定义(Subject),规范代理与被代理的动作。
2、代理类需要持有被代理对象,必要时还需要持有接受方对象
代理模式运用场景:
1、VPN, 通俗讲就是翻墙
2、AOP, 切面编程