zoukankan      html  css  js  c++  java
  • 【设计模式学习笔记】 之 静态代理

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

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

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

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

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

  • 相关阅读:
    mysql workbench 建表时PK, NN, UQ, BIN, UN, ZF, AI
    Asan检测内存读越界
    C 实现 C++ 的面向对象特性(封装、继承、多态)
    VIBE算法
    Go 大坑 nil
    求二叉树中节点的最大距离
    计算[1,N]范围内含有7的数字的个数
    一组便于创建线程和线程池的简单封装函数
    用C#执行doc命令
    可以自由停靠的窗体!
  • 原文地址:https://www.cnblogs.com/hellxz/p/8496203.html
Copyright © 2011-2022 走看看