• java设计模式-代理模式


    模式导读:

        随着时代的发展,社会的进步,思想的提升,我们的世界变得更加的多元化。明星众所周知是一个比较时尚,fashion的职业,他们或唱歌,或跳舞,或文武双全,但他们也有可能会像一个普通员工一样一天忙不完的事情,所以出现了经纪人这个字眼,由他们去负责一些被代理角色不必要的工作,减轻他们的负担。这便是代理角色在生活中最经典的例子。

    分类:
    1.静态代理:静态定义代理类
    2.动态代理:动态生成代理类

    动态代理:
    1.jdk自带的动态代理:
    (1)Java.lang.reflect.Proxy
    作用:动态生成类和对象;
    (2)java.lang.reflect.InvocationHandler(处理器接口)
    可以通过invoke()方法实现对真实角色的代理访问。
    每次通过Proxy生成代理类对象时都要指定对应的处理器对象。

    参考类图:

    1.抽象角色:定义代理角色和抽象角色的公共对外方法。
    2.真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用,关注真正的业务逻辑。
    3.代理角色:真正角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作,将统一的流程控制放到代理角色中处理。

    静态代理代码实现:

    1.抽象角色

    1 package com.etc;
    2 
    3 public interface AbstractSinger {
    4     //抽象角色的操作
    5     void sing();
    6 }

    2.真实角色

     1 package com.etc;
     2 
     3 public class Singer implements AbstractSinger {
     4 
     5     private String name;
     6     private int age;
     7 
     8     public Singer(String name, int age) {
     9         super();
    10         this.name = name;
    11         this.age = age;
    12     }
    13     
    14     public Singer() {
    15         super();
    16     }
    17 
    18     public String getName() {
    19         return name;
    20     }
    21     public void setName(String name) {
    22         this.name = name;
    23     }
    24     public int getAge() {
    25         return age;
    26     }
    27     public void setAge(int age) {
    28         this.age = age;
    29     }
    30     //歌手的具体操作
    31     public void sing() {
    32         System.out.println(age+"岁的歌手"+name+"正在演唱歌曲!");
    33     }
    34 }

    3.代理角色

     1 package com.etc;
     2 /*设置一个代理角色
     3  * 通过代理控制对对象的访问,
     4  * 可以详细的控制访问某个类或对象的方法,
     5  * 在调用这个方法前做前置处理,
     6  * 调用这个方法后做后置处理
     7 */
     8 public class Proxy  {
     9     //保持对被代理角色的引用
    10     Singer singer;
    11     //代理者角色自身的方法plan()
    12     public static void plan() {
    13         System.out.println("-->代理员计划好歌手的行程!");
    14     }
    15     //代理者角色自身的方法startSing()
    16     public static void startSing() {
    17         System.out.println("-->代理员处理好歌手唱歌前的准备工作!");
    18     }
    19     //代理者角色自身的方法overSing()
    20     public static void overSing() {
    21         System.out.println("-->代理员处理好歌手唱歌后的结束工作!");
    22     }
    23     
    24     //真正代理后实现流程操作
    25     public void toProxy(Singer singer) {
    26         plan();
    27         startSing();
    28         singer.sing();
    29         overSing();
    30     }
    31 }

    4.客户端类

     1 package com.etc;
     2 
     3 public class Client {
     4 
     5     public static void main(String[] args) {
     6         
     7         Singer singer=new Singer("周杰伦",25);
     8         Proxy p=new Proxy();
     9         //代理后具体的流程实现
    10         p.toProxy(singer);
    11 
    12     }
    13 
    14 }

    效果截图:

    动态代理代码实现:

    1.抽象角色

    1 package com.etc.dynamicproxy;
    2 
    3 public interface AbstractSinger {
    4     //抽象角色的操作
    5     void sing();
    6 }

    2.具体角色

     1 package com.etc.dynamicproxy;
     2 
     3 public class Singer implements AbstractSinger {
     4 
     5     private String name;
     6     private int age;
     7 
     8     public Singer(String name, int age) {
     9         super();
    10         this.name = name;
    11         this.age = age;
    12     }
    13     
    14     public Singer() {
    15         super();
    16     }
    17 
    18     public String getName() {
    19         return name;
    20     }
    21     public void setName(String name) {
    22         this.name = name;
    23     }
    24     public int getAge() {
    25         return age;
    26     }
    27     public void setAge(int age) {
    28         this.age = age;
    29     }
    30     //歌手的具体操作
    31     public void sing() {
    32         System.out.println(age+"岁的歌手"+name+"正在演唱歌曲!");
    33     }
    34 }

    3.处理者角色

     1 package com.etc.dynamicproxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 public class Handler implements InvocationHandler{
     7     //保持对角色的引用
     8     AbstractSinger singer;
     9     //构造器,传入角色对象
    10     public Handler(AbstractSinger singer) {
    11         super();
    12         this.singer = singer;
    13     }
    14     public static void startPlan() {
    15         System.out.println("代理员为歌手准备好开始唱歌的准备工作!");
    16     }
    17     public static void overPlan() {
    18         System.out.println("代理员为歌手准备好结束唱歌的准备工作!");
    19     }
    20     //实现具体代理功能
    21     @Override
    22     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    23         startPlan(); 
    24         //激活歌手的唱歌操作
    25         method.invoke(singer, args);
    26         overPlan();
    27         return null;
    28         
    29     }
    30 
    31 }

    4.客户端

     1 package com.etc.dynamicproxy;
     2 
     3 import java.lang.reflect.Proxy;
     4 
     5 public class Client {
     6 
     7     public static void main(String[] args) {
     8         AbstractSinger singer=new Singer("周杰伦",28);
     9         Handler hd=new Handler(singer);
    10         AbstractSinger proxy=(AbstractSinger) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {AbstractSinger.class},hd);
    11         proxy.sing();
    12     }
    13 
    14 }

    效果截图:

    代理模式优缺点:

    优点:

    1、职责清晰。
    2、高扩展性。
    3、智能化。

    缺点:

    1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
    2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

    适用场景:

    1、远程代理。
    2、虚拟代理。
    3、Copy-on-Write 代理。
    4、保护(Protect or Access)代理。
    5、Cache代理。
    6、防火墙(Firewall)代理。
    7、同步化(Synchronization)代理。
    8、智能引用(Smart Reference)代理。

  • 相关阅读:
    自动滑块验证登录QQ-java实现
    今日校园自动提交问卷-Java实现
    文库下载实现自动化
    测试
    软件工程结课小结
    结对项目-java生成四则运算
    JS判断对象为空的三种方法
    vue 组件间 8 大通讯方式 之三 eventBus
    vue 组件间 8 大通讯方式 之二 provide/ inject ref / refs
    vue 组件间 8 大通讯方式 之一 props / $emit $children / $parent
  • 原文地址:https://www.cnblogs.com/weekstart/p/proxy.html
Copyright © 2020-2023  润新知