服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服务器之家 - 编程语言 - JAVA教程 - 实例讲解Java设计模式编程中如何运用代理模式

实例讲解Java设计模式编程中如何运用代理模式

2020-03-27 19:50Zhang_H JAVA教程

这篇文章主要介绍了Java设计模式编程中如何运用代理模式,文中举了普通代理和强制代理的例子作为代理模式的扩展内容,需要的朋友可以参考下

定义:   

    Provide a surrogate or placeholder for another object to control access to it.

    为其他对象一种代理以控制对这个对象的访问。

一般描述:

    一般包含的三个角色:抽象主题、具体主题、代理主题。

  1.     抽象主题:是一个抽象类或接口,是一个普通的业务类型定义。
  2.     具体主题:业务逻辑的具体执行者
  3.     代理角色:负责对真是角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现。

通用类图:

实例讲解Java设计模式编程中如何运用代理模式

通用代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package Proxy;
//抽象主题类:
public interface Subject {
  public void doSomething();
}
 
package Proxy;
//具体主题类
public class RealSubject implements Subject{
  @Override
  public void doSomething() {
    System.out.println("业务逻辑...");
  }
}
 
package Proxy;
//代理主题类
public class Proxy implements Subject{
   
  private Subject sub = null;
   
  @Override
  public void doSomething() {
    this.sub.doSomething();  
  }
   
  public Proxy(Subject sub){
    this.sub = sub;
  }
   
   
}
 
package Proxy;
//客户端
public class Client {
  public static void main(String[] args) {
     
    Subject realsub = new RealSubject();
    Subject proxy = new Proxy(realsub);
     
    proxy.doSomething();
  }
}

优点

    1. 职责清晰

    2. 高扩展

代理模式的扩展:

普通代理:

    具体主题类对高层透明,在代理主题类中构造具体主题类

代码实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package GeneralProxy;
 
public interface Subject {
  public void doSomething();
}
 
package GeneralProxy;
 
public class RealSubject implements Subject{
   
  private String name = null;
   
  @Override
  public void doSomething() {
    System.out.println(this.name + "被代理,正在执行业务逻辑...");
  }
   
  public RealSubject(Subject proxy,String name) throws Exception{
    if(proxy == null){
      throw new Exception("无法创建被代理对象");
    }else{
      this.name = name;
    }
       
  }
}
 
package GeneralProxy;
 
public class Proxy implements Subject{
 
  private Subject realsub = null;
     
  public Proxy(String name) {
    try {
      realsub = new RealSubject(this, name);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
   
  public void doSomething() {
    realsub.doSomething();
  }
}
 
package GeneralProxy;
 
public class Client {
  public static void main(String[] args) {
    //普通代理
    Subject proxy = new Proxy("张三");       
    proxy.doSomethaing();
  }
   
}


强制代理:

    必须通过访问具体主题类获取代理主题类的对象,然后用代理主题类控制访问   

代码实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package MustProxy;
 
public interface Subject {
  public void doSomething();
   
  public Subject getProxy();
}
 
package MustProxy;
 
public class RealSubject implements Subject{
   
  private String name = null;
  private Subject proxy = null;
   
  @Override
  public void doSomething() {
    if(isProxy()){
      System.out.println(this.name + "被代理,正在执行业务逻辑...");
    }else{
      System.out.println("请先访问代理...");
    }
     
  }
   
  public RealSubject(String name) {
    this.name = name;
  }
   
  public Subject getProxy() {
 
    proxy = new Proxy(this);
    return this.proxy;
  }
   
  private boolean isProxy(){
    if(this.proxy == null){
      return false;
    }else{
      return true;
    }
       
  }
}
 
package MustProxy;
 
public class Proxy implements Subject{
 
  private Subject realSub = null;
   
  public Proxy(Subject realSub) {
    this.realSub = realSub;
  }
   
  public void doSomething() {  
    this.realSub.doSomething();
  }
   
 
  public Subject getProxy() {
 
    return this;
  }
}
 
package MustProxy;
 
public class Client {
  public static void main(String[] args) {
    Subject realSub = new RealSubject("张三");
    realSub.doSomething();
     
    Subject proxy = realSub.getProxy();
    proxy.doSomething();
  }
}

应用场景
现实世界中,秘书就相当于一个代理,老板开会,那么通知员工开会时间、布置会场、会后整理会场等等开会相关工作就可以交给秘书做,老板就只需要开会就行了,不需要亲自做那些事。同理,在我们程序设计中也可使用代理模式来将由一系列无关逻辑组合在一起的代码进行解耦合,比如业务代码中的日志代码就可以在代理中进行。Spring的AOP就是典型的动态代理应用。


代理模式的应用形式
(1)远程代理(Remote Proxy) -可以隐藏一个对象存在于不同地址空间的事实。也使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
(2)虚拟代理(Virtual Proxy) – 允许内存开销较大的对象在需要的时候创建。只有我们真正需要这个对象的时候才创建。
(3)写入时复制代理(Copy-On-Write Proxy) – 用来控制对象的复制,方法是延迟对象的复制,直到客户真的需要为止。是虚拟代理的一个变体。
(4)保护代理(Protection (Access)Proxy) – 为不同的客户提供不同级别的目标对象访问权限
(5)缓存代理(Cache Proxy) – 为开销大的运算结果提供暂时存储,它允许多个客户共享结果,以减少计算或网络延迟。
(6)防火墙代理(Firewall Proxy) – 控制网络资源的访问,保护主题免于恶意客户的侵害。
(7)同步代理(SynchronizationProxy) – 在多线程的情况下为主题提供安全的访问。
(8)智能引用代理(Smart ReferenceProxy) - 当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
(9)复杂隐藏代理(Complexity HidingProxy) – 用来隐藏一个类的复杂集合的复杂度,并进行访问控制。有时候也称为外观代理(Façade Proxy),这不难理解。复杂隐藏代理和外观模式是不一样的,因为代理控制访问,而外观模式是不一样的,因为代理控制访问,而外观模式只提供另一组接口。
 

延伸 · 阅读

精彩推荐
  • JAVA教程java采用中文方式显示时间的方法

    java采用中文方式显示时间的方法

    这篇文章主要介绍了java采用中文方式显示时间的方法,实例分析了java时间操作及字符串转换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    罪恶的花生2312019-12-26
  • JAVA教程Java代码注释规范详解

    Java代码注释规范详解

    代码附有注释对程序开发者来说非常重要,随着技术的发展,在项目开发过程中,必须要求程序员写好代码注释,这样有利于代码后续的编写和使用。下面...

    杨鑫newlfe2172020-03-27
  • JAVA教程java使用OGEngine开发2048

    java使用OGEngine开发2048

    众所周知OGEngine是国人对AndEngine改进后的国产Java编程的游戏引擎,除了支持3D游戏这个鸡肋功能之外AndEngine的功能OGEngine都有,而且AndEngine缺少的多点触摸功...

    hebedich2972019-12-14
  • JAVA教程htmlcleaner使用方法及xpath语法初探

    htmlcleaner使用方法及xpath语法初探

    HtmlCleaner是一个开源的Java语言的Html文档解析器。HtmlCleaner能够重新整理HTML文档的每个元素并生成结构良好(Well-Formed)的 HTML 文档...

    mdxy-dxy2442020-01-02
  • JAVA教程Java创建ZIP压缩文件的方法

    Java创建ZIP压缩文件的方法

    这篇文章主要介绍了Java创建ZIP压缩文件的方法,实例分析了java创建zip文件的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    华宰3792019-12-27
  • JAVA教程Java生成随机数的2种示例方法代码

    Java生成随机数的2种示例方法代码

    在Java中,生成随机数有两种方法。1是使用Random类。2是使用Math类中的random方法。看下面的例子使用吧 ...

    java代码网3952019-10-21
  • JAVA教程java使用颜色选择器示例分享

    java使用颜色选择器示例分享

    这篇文章主要介绍了java使用颜色选择器示例,需要的朋友可以参考下 ...

    java教程网3282019-11-13
  • JAVA教程JavaMe开发绘制可自动换行文本

    JavaMe开发绘制可自动换行文本

    JavaMe Graphics类中的drawString不支持文本换行,这样绘制比较长的字符串时,文本被绘制在同一行,超过屏幕部分的字符串被截断了。如何使绘制的文本能自动...

    tandesir2472020-01-05