java设计模式--代理模式(一)

主要讲智能引用代理

代理实现分为静态代理和动态代理。

静态代理

静态代理模式其实很常见,比如买火车票这件小事:黄牛相当于是火车站的代理,我们可以通过黄牛买票,但只能去火车站进行改签和退票。在代码实现中相当于为一个委托对象realSubject提供一个代理对象proxy,通过proxy可以调用realSubject的部分功能,并添加一些额外的业务处理,同时可以屏蔽realSubject中未开放的接口。


1、RealSubject 是委托类,Proxy 是代理类;
2、Subject 是委托类和代理类的接口;
3、request() 是委托类和代理类的共同方法;

示例1:

抽象对象角色

public abstract class AbstractObject {
    //操作
    public abstract void operation();
}

目标对象角色

public class RealObject extends AbstractObject {
    @Override
    public void operation() {
        //一些操作
        System.out.println("一些操作");
    }
}
代理对象角色

public class ProxyObject extends AbstractObject{
    RealObject realObject = new RealObject();  //代理方法实际上是需要实际对象的
    @Override
    public void operation() {
        //调用目标对象之前可以做相关操作
        System.out.println("before");        
        realObject.operation();        
        //调用目标对象之后可以做相关操作
        System.out.println("after");
    }
}
客户端
public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AbstractObject obj = new ProxyObject();
        obj.operation();
    }

}

从上面的例子可以看出代理对象将客户端的调用委派给目标对象,在调用目标对象的方法之前跟之后都可以执行特定的操作。这个例子实际上是以下要将聚合的方式。

示例2:继承方式和聚合方式的对比

1.代理类继承实际类(委托类)

代理类和委托类的接口:

package proxy;
public interface Moveable {
	void move();
}
委托类:
import java.util.Random;
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 Car2 extends Car {

	@Override
	public void move() {
		long starttime = System.currentTimeMillis();
		System.out.println("汽车开始行驶....");
		super.move();
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶....  汽车行驶时间:" 
				+ (endtime - starttime) + "毫秒!");
	}

	
}
注:代理类继承了委托类,重写了委托类的方法。在重写时,可以直接调用委托类的方法,在之前和之后可以有自己的业务。

2.聚合的方式(代理类实际上是继承的公共来或实现的公共接口)

聚合指在一个类中调用另外一个类

此时的代理类:

public class Car3 implements Moveable {

	public Car3(Car car) {  //也可以像示例1一样new一个car
		super();
		this.car = car;
	}

	private Car car;
	
	@Override
	public void move() {
		long starttime = System.currentTimeMillis();
		System.out.println("汽车开始行驶....");
		car.move();
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶....  汽车行驶时间:" 
				+ (endtime - starttime) + "毫秒!");
	}

}


小结:聚合比继承更适合,原因见示例3


示例3:

实现类实现公共接口,其他的多个代理也实现这个公共接口。某个代理要调用实现类实例或另外的代理类实例,调用的参数也通过接口实现。这样有极大的扩展性。


公共接口:

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();
		}
	}
}

代理之间只知道有实现类方法或代理类方法,具体顺序可以改变时,用如下代码可以实现:

代理1:(增加了时间)
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) + "毫秒!");
	}

}
代理2:(增加了日志)

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 class Client {

	/**
	 * 测试类
	 */
	public static void main(String[] args) {
		Car car = new Car();
		CarLogProxy clp = new CarLogProxy(car);
		CarTimeProxy ctp = new CarTimeProxy(clp);
		ctp.move();
	}

}
//结果
汽车开始行驶....
日志开始....
汽车行驶中....
日志结束....
汽车结束行驶....  汽车行驶时间:362毫秒!
-------------------------------------------------------------------
public class Client {


	/**
	 * 测试类
	 */
	public static void main(String[] args) {
		Car car = new Car();
		CarTimeProxy ctp = new CarTimeProxy(car);
		CarLogProxy clp = new CarLogProxy(ctp);
		clp.move();
	}


}
//结果
日志开始....
汽车开始行驶....
汽车行驶中....
汽车结束行驶....  汽车行驶时间:662毫秒!
日志结束....

小结:示例3的结果表明,聚合的方式灵活


下一篇:动态代理



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值