在阎宏博士的《JAVA与模式》一书中开头是这样描述代理(Proxy)模式的:
代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
代理模式的结构
所谓代理,就是一个人或者机构代表另一个人或者机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式类图如下:
在代理模式中的角色:
● 抽象对象角色:声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
● 目标对象角色:定义了代理对象所代表的目标对象。
● 代理对象角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。
源代码
抽象对象角色
package com.java.thread;
//定义接口 定义照看孩子方法 抽象对象角色
public interface People {
public void LookAfterChild();
}
目标对象角色
package com.java.thread;
public class Parent implements People {
//父母会照看孩子 目标对象角色
public Parent() {
}
@Override
public void LookAfterChild() {
// TODO Auto-generated method stub
System.out.println("照看孩子!");
}
}
代理对象角色
package com.java.thread;
public class Other implements People {
//别人替父母照看孩子 代理类 代理对象角色
People people;
public Other(People people) {
this.people=people;
}
@Override
public void LookAfterChild() {
//调用目标对象之前的操作
System.out.println("孩子父母很忙!");
this.people.LookAfterChild();
//调用目标对现之后的操作
System.out.println("孩子父母回来,我就不管了!");
}
}
客户端
package com.java.thread;
public class TestProxy {
/**
* @param args
*/
public static void main(String[] args) {
People p = new Parent();
Other ot = new Other(p);
ot.LookAfterChild();
}
}
运行结果:
孩子父母很忙!
照看孩子!
孩子父母回来,我就不管了!
常见的代理模式
我们知道新建一个线程有两种方式 继承Thread类,或者实现Runnable接口。
观察Thread的源码,我们发现Thread实现了Runnable接口。
//代理模式类
public
class Thread implements Runnable {
public Thread(Runnable target, String name) {
............
}
}
自定义的实现Runnable接口的类
我认为的目标角色类
package com.java.thread;
public class new_thread implements Runnable {
public new_thread() {
}
@Override
public void run() {
//自定义耗时操作
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()
+ "继承runnable接口!!");
}
}
}
客户端
package com.java.thread;
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
// 启动新的线程 大家有没有觉得眼熟 Thread和new_thread都实现了Runnable接口 调用Thread的start方法,其实调用的
// 是new_thread线程的耗时操作 没错就是代理模式
new Thread(new new_thread(), "A").start();
new Thread(new new_thread(), "B").start();
}
}