【设计模式学习笔记】 之 静态代理

简介:静态代理设计模式可以理解为实际操作对象的代理,这个代理拥有实际对象的所有接口,代理对象中持有着实际对象的引用,但是这个代理对象在客户端调用接口的时候,将这些请求进行拦截,对请求数据进行预处理(相当于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的动态代理太强了以至于埋没了静态代理

相较于动态代理分别使用的场景:

  • 如果在场景不是很复杂,代理对象确定的情况下,使用静态代理代码更具可读性;
  • 场景复杂且被代理对象不确定的情况使用动态代理。

静态代理是在编译期间就已经定义好被代理对象的类,而动态代理用到了字节码技术,在运行期间生成被代理对象

先写这么多,欢迎评论,如有错误,望不吝赐教!

原文地址:https://www.cnblogs.com/hellxz/p/8496203.html