【设计模式学习笔记】 之 静态代理
简介:静态代理设计模式可以理解为实际操作对象的代理,这个代理拥有实际对象的所有接口,代理对象中持有着实际对象的引用,但是这个代理对象在客户端调用接口的时候,将这些请求进行拦截,对请求数据进行预处理(相当于Filter),可以在预处理中做判断如果满足条件放行实际对象操作,否则代理对象处理并返回。
有几点需要注意:
- 访问代理对象的客户端并不知道这是一个代理对象,他只关心效果
- 代理对象可以对调用传参进行处理
- 特定的情况下代理对象可以代实际对象执行操作
初学亿图画个图,看样子还行,大家凑合看看:)
由于柳大写的代码最开始的实在是太复杂了,后来写的感觉有点怎么说呢……所以自己写了个简单的代理,大家可以对照柳大设计模式第31个静态代理视频进行对照
返回值就不写了,都是使用代理对象的方法返回的,这个毋庸置疑
举例:
周杰伦有个经纪人,找杰伦签约必须找他的经纪人,如果经纪人说档期排满了就不能签约,没排满就让周杰伦去签字。想让杰伦唱歌,只需要让调经纪人的唱歌方法,不管这个经纪人实际会不会唱歌,这个方法是让周杰伦去唱歌。好了看代码吧,写的很简单
首先我们先创建一个歌手的接口,并让经纪人和杰伦都实现这个接口
1 package com.mi.staticproxy; 2 3 /** 4 * 歌手需要实现的接口 5 */ 6 public interface Singer { 7 8 //签约 9 public void signContract(int time); //参数为日期,这里为了简单 年+月+日 例:20180303 10 //唱歌 11 public void sing(String song); //参数为歌名 12 //上台发言 13 public void helloSay(); 14 //下台发言 15 public void byeSay(); 16 }
被代理对象:歌手杰伦
1 package com.mi.staticproxy; 2 3 4 /** 5 * 歌手(被代理者):周杰伦 6 */ 7 public class Jay implements Singer{ 8 9 private String name = "Jay"; 10 public void signContract(int time) { 11 System.out.println(name+"签约中……"); 12 System.out.println("--------签约成功-------"); 13 } 14 15 public void sing(String song) { 16 System.out.println("下面我给大家唱一首"+song+"---------"); 17 System.out.println(name+"正在唱"+song); 18 System.out.println(song+"唱完了,谢谢大家~"); 19 } 20 21 public void helloSay() { 22 System.out.println("大家好,我是"+name+",哎哟,不错啊~"); 23 } 24 25 public void byeSay() { 26 System.out.println("谢谢大家听我唱歌!再见~"); 27 } 28 29 30 }
代理:经纪人
1 package com.mi.staticproxy; 2 3 4 /** 5 * 代理对象:经纪人 6 */ 7 public class Agent implements Singer{ 8 9 private Jay jay; //持有被代理对象引用 10 11 public void signContract(int time){ 12 System.out.println("当前签约时间:"+time); 13 /* 14 * 代理对象自己处理 15 */ 16 if(time<20180606){ //这里就模拟档期已经排到了2018年6月6日 17 System.out.println("杰伦档期排满了,2018年6月6日之后的吧!"); 18 System.out.println("---------签约失败---------"); 19 return; 20 } 21 jay.signContract(time); 22 } 23 24 public void sing(String song) { 25 //预处理:加书名号 26 song = "《"+song+"》"; 27 jay.sing(song); 28 } 29 30 public void helloSay() { 31 jay.helloSay(); 32 } 33 34 public void byeSay() { 35 jay.byeSay(); 36 } 37 38 //setter 39 public void setJay(Jay jay) { 40 this.jay = jay; 41 } 42 }
测试类:
1 package com.mi.staticproxy; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 7 Agent agent = new Agent(); 8 agent.setJay(new Jay()); 9 agent.signContract(20180303); 10 agent.signContract(20180607); 11 agent.helloSay(); 12 agent.sing("发如雪"); 13 agent.sing("稻香"); 14 agent.sing("十里香"); 15 agent.byeSay(); 16 17 } 18 19 }
输出:
当前签约时间:20180303 杰伦档期排满了,2018年6月6日之后的吧! ---------签约失败--------- 当前签约时间:20180607 Jay签约中…… --------签约成功------- 大家好,我是Jay,哎哟,不错啊~ 下面我给大家唱一首《发如雪》--------- Jay正在唱《发如雪》 《发如雪》唱完了,谢谢大家~ 下面我给大家唱一首《稻香》--------- Jay正在唱《稻香》 《稻香》唱完了,谢谢大家~ 下面我给大家唱一首《十里香》--------- Jay正在唱《十里香》 《十里香》唱完了,谢谢大家~ 谢谢大家听我唱歌!再见~
简单总结:
代理模式都是为需要代理的对象提供预处理操作,或者一些比较大的对象不想在启动的时候就加载进内存,可以通过代理进行判断是否创建这个对象,调用前创建对象,减轻系统开支。
学习静态代理的目的是为了更好的理解动态代理,Java的动态代理太强了以至于埋没了静态代理
相较于动态代理分别使用的场景:
- 如果在场景不是很复杂,代理对象确定的情况下,使用静态代理代码更具可读性;
- 场景复杂且被代理对象不确定的情况使用动态代理。
静态代理是在编译期间就已经定义好被代理对象的类,而动态代理用到了字节码技术,在运行期间生成被代理对象
先写这么多,欢迎评论,如有错误,望不吝赐教!