代理模式的分类:1.远程代理(为不同区域的对象提供一个局域网对象,如有多个分店可以用一个监视器来监视各个分店的情况)<2.虚拟代理(如 有一张图片还没被加载下来的话可以用另外一张默认图片来代替这个图片,加载好以后就可以把这个图片加载进来)3.保护代理(进行一些权限的设置)4.智能代理(提供一些额外的服务,比如方法执行前后输出日志)
通过静态代理和动态代理两种方式来实现代理模式,下面我们来看一个例子
车有一个行驶的方法,假设我们需要在车行驶的过程中记录行车的时间
相关代码(原始方式):
@Car.java
public class Car implements Moveable{
public void move() {
long starttime=System.currentTimeMillis();
System.out.println("车开始行驶...");
//实现打车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("车行驶中...");
} catch (Exception e) {
e.printStackTrace();
}
long endtime=System.currentTimeMillis();
System.out.println("车结束行驶。");
System.out.println("车行驶时间:"+(endtime-starttime)+"毫秒!");
}
}
@Moveable.java
public interface Moveable {
void move();
}
@Client.java
public class Client {
/**
* 测试类
*/
public static void main(String[] args) {
Car car=new Car();
car.move();
}
}
下面通过继承的方法实现代码:
相关代码(继承方式):
@Client.java
public class Client {
/**
* 测试类
*/
public static void main(String[] args) {
//使用继承方式
Moveable m=new Car2();
m.move();
}
}
@Car2.java
public class Car2 extends Car{
@Override
public void move() {
long starttime=System.currentTimeMillis();
System.out.println("车开始行驶...");
super.move();
long endtime=System.currentTimeMillis();
System.out.println("车结束行驶。");
System.out.println("车行驶时间:"+(endtime-starttime)+"毫秒!");
}
}
@Moveable.java
public interface Moveable {
void move();
}
@Car.java
public class Car implements Moveable{
public void move() {
//实现打车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("车行驶中...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
还可以通过集成的方式,实现代码如下:
相关代码(聚合方式:一个类中调用另一个类对象):
@Client.java
public class Client {
/**
* 测试类
*/
public static void main(String[] args) {
//使用聚合方式
Car car=new Car();
Moveable m=new Car3(car);
m.move();
}
}
@Moveable.java
public interface Moveable {
void move();
}
@Car.java
public class Car implements Moveable{
public void move() {
//实现打车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("车行驶中...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Car3.java
public class Car3 implements Moveable {
private Car car;
public Car3(Car car){
super();
this.car=car;
}
public void move() {
long starttime=System.currentTimeMillis();
System.out.println("车开始行驶...");
car.move();
long endtime=System.currentTimeMillis();
System.out.println("车结束行驶。");
System.out.println("车行驶时间:"+(endtime-starttime)+"毫秒!");
}
}
(1)通过继承来实现代理:首先创建接口,然后代理类为子类,被代理类为父类,父类实现接口,子类覆写的方法中通过 super.同名函数 调用父类中同名函数,然后在添加上子类的业务逻辑代码。(2)通过聚合来实现代理:聚合就是在一个类中使用另一个类对象。我们把被代理类作为代理类的属性,然后通过构造方法把被代理类的对象传进去,然后初始化属性对象,然后在覆写方法中调用属性对象的同名方法,然后添加代理对象的业务逻辑。
聚合实现代理比继承更具灵活性,下面通过一个例子来证明
假设车在行驶过程中既需要记录时间又需要日志,那么我们需要两个代理类,我们通过实现接口来实现
//定义一个接口,实现类和代理类都需要实现此接口
public interface Moveable {
void move();
}
//具体实现类
public class Car implements Moveable {
@Override
public void move() {
//实现开车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("汽车行驶中....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//时间代理类
public class CarTimeProxy implements Moveable {
public CarTimeProxy(Moveable m) {
super();
this.m = m;
}
private Moveable m;
@Override
public void move() {
long starttime = System.currentTimeMillis();
System.out.println("汽车开始行驶....");
m.move();
long endtime = System.currentTimeMillis();
System.out.println("汽车结束行驶.... 汽车行驶时间:"
+ (endtime - starttime) + "毫秒!");
}
}
//日志代理类
public class CarLogProxy implements Moveable {
public CarLogProxy(Moveable m) {
super();
this.m = m;
}
private Moveable m;
@Override
public void move() {
System.out.println("日志开始....");
m.move();
System.out.println("日志结束....");
}
}
//测试类
public static void main(String[] args) {
Car car = new Car();
CarLogProxy clp = new CarLogProxy(car);
CarTimeProxy ctp = new CarTimeProxy(clp);
ctp.move();
}
输出结果:
汽车开始行驶....
日志开始....
汽车行驶中....
日志结束....
汽车结束行驶.... 汽车行驶时间:802毫秒!
以上我们为一个车实现了两个代理,这个时候我们可以想象一下,假如火车,自行车也需要这两个代理的功能,怎么办呢?这个时候我们需要动态代理,我们看一篇