设计模式学习_代理模式

设计模式学习_代理模式

问题

最近在做项目时,要封装一个树状对象的对话框,于是上网百度了一个别人做好的东西移植过来。突然发现,如果项目的树状对象要套在他这个控件上面要加多几个属性,那不是我要装上去的对象都要加多几个与它无关的属性?那以后这个对象做其他用途是不是也要加多几个无关属性?想想感觉不对头,就好像你要跑步难道就要给你移植双猪脚?你要去北京难道要给你移植对鸡翅?这样明显不合理嘛,勉强有幸福么?我只需要个代步工具而已。这时牛逼的同事问:“你是不是要用代理模式?”我脑袋上的灯,顿时亮了起来。百度之。。。

意图

通过一个代理(proxy)或者占位符来控制对该对象的访问。

模型图——无

举例

这里讲一个借刀杀怪的故事吧。我们玩游戏时,喜欢带妹纸杀怪升级。至于为何喜欢带妹纸杀怪升级?那是因为游戏玩家都是新时代的活雷锋,以助人为乐。话说有一天,小明头顶着“杀怪大湿”光环身穿着一身极品而且闪耀着非常耀眼光芒的装备站在大街上。不时发出嘹亮的笑声。听说这不是在装B而是为了给城外的妖怪压力。这时,一个身材丰满,但装备破烂的美女跑过来嘀咕了几句。然后他们两就兴高采烈的踏上了杀怪之旅。

杀角色需求分析:杀怪需要杀怪的能力 ,杀怪后可以获得任务物品。小明有杀怪能力,但他不需要任务物品。妹纸没杀怪能力,但需要捡任务物品。于是就有了这样的分工:小明杀怪,妹纸捡任务物品。

首先我们先定义杀怪能力接口,必须实现这个接口才可以杀怪

public interface Killable {
	
	public void KillAction(String str);

}

然后小明实现了这个接口

public class Role implements Killable{
	
	private String name;
	
	public Role(String name) {
		// TODO Auto-generated constructor stub
		this.name=name;
	}
	
	@Override
	public void KillAction(String str) {
		// TODO Auto-generated method stub
		System.out.println(this.name+"使出了降龙十八掌杀死"+str);
		
	}

}

然后妹纸作为了一个没能力杀怪的代理角色,也要实现接口

public class KillProxy  implements Killable{
	
	private Killable killable;
	
	public KillProxy(Killable killable) {
		// TODO Auto-generated constructor stub
		this.killable=killable;
	}

	@Override
	public void KillAction(String str) {
		// TODO Auto-generated method stub
		sneerMonster(str);
		killable.KillAction(str);
		makeMoney(str);
	}
	
	public void sneerMonster(String name)
	{
		System.out.println("妹纸跳了段牛逼肚皮舞吸引"+name+"过来");
	}

	public void makeMoney(String name)
	{
		System.out.println("妹纸从"+name+"口袋捡起了任务物品");
	}
}
开始杀怪了

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Killable killable=new KillProxy(new Role("小明"));
		killable.KillAction("巨兽");
			
	}

}
运行结果print:

妹纸跳了段牛逼肚皮舞吸引巨兽过来
小明使出了降龙十八掌杀死巨兽
妹纸从巨兽口袋捡起了任务物品


结果分析

看调用方法,我明显new 出来的是妹纸,小明明显没有和巨兽有接触。巨兽以为是被妹纸杀死的,其实是被妹纸借用小明杀怪方法杀死的。者就是传说中的借刀杀怪了。

任务完成

 就这样,小明和妹纸过上了幸福生活。


幕后分析

上面的代理模式是通过实现接口类完成的,而且只能对实现这个接口的对象有用。网上说如果一个接口一个代理类,那是不是造成代理类增多,于是我有百度下——据说百度的码农不是好码农。好吧我承认自己是低手。但我觉得一个人愿意查找问题解决问题就是一个好的开始。


动态代理模式

对于动态代理,我的理解是,做个通用的代理类,可以代理实现任何接口的对象。就是比上面那个更通用。


动态代理实现方法

用java的放射机制生产目标对象的代理类,就是动态实现上面例子的妹纸代理类。任何执行接口方法。你可以在执行接口方法的前后加上自己的一些处理。

/**
 * java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力
 * @author Administrator
 *
 */
public class Xproxy implements InvocationHandler{

	private Object object;
	
	public Object bind(Object object)
	{
		this.object=object;
		
		 //取得代理对象  
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),  
        		object.getClass().getInterfaces(), this);   
	}
	
	/**
	 * method 目标对象实现的接口 接口方法
	 * args方法执行所需的参数
	 * proxy听说是被代理对象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		Object result=null;
		if(args.length>0)
		System.out.println("妹纸跳了段牛逼肚皮舞吸引"+args[0]+"过来");
		result=method.invoke(this.object, args);  
		if(args.length>0)
		System.out.println("妹纸从"+args[0]+"口袋捡起了几毛钱");
		return result;
	}
}


实现代理代码

public class Main {


	public static void main(String[] args) {
		// TODO Auto-generated method stub


		/*Killable killable=new KillProxy(new Role("小明"));
		killable.KillAction("巨兽");*/
		
		Role role=new Role("小明");
		Xproxy xproxy=new Xproxy();
		Killable killable=(Killable) xproxy.bind(role);
		killable.KillAction("哥布林");
		
	}


}

运行结果:

妹纸跳了段牛逼肚皮舞吸引哥布林过来
小明使出了降龙十八掌杀死哥布林
妹纸从哥布林口袋捡起了几毛钱


代理模式就先告一段落。

备注:上面的故事例子纯属扯淡,有被污染者,自行洗脑。关于何时用这个模式,看自己实际需求,起码先掌握了,脑里有这个概念,可能后面碰到有很适合这个代理模式的需求的,你写起代码来就得心应手了。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值