设计模式-代理模式

代理模式-为其他的对象提供一种代理以控制对这个对象的访问。
我的理解是:当需要某个对象的方法,但是又不能直接直接访问目标对象时候可以使用该模式。目标对象与代理对象具体相同的接口,目标对象与代理对象都应该实现某个具有共同行为的接口。举一个生活中例子,刘德华很出名,天津市电视台想在新年晚会上找刘德华唱歌,一般情况下,天津电视台不能直接找刘德华商谈具体事宜,电视台得找他的经纪人(代理)谈。这个经纪人应该熟知刘德华能够唱什么歌,适合什么样的歌,会跳那些舞蹈,所以,他们应该具有相同的接口。当天津电视台跟经纪人谈好之后,刘德华来到天津演出,真正演出的是刘德华(目标类),而不是跟天津电视台谈话的经纪人(代理类)。我们可以用代理模式表示这个过程:
下面是具体代码:
/**
* 代理与具体类的共同接口
* @author Administrator
*
*/
public interface Singer {
public void sing();
public void dance();
public void kungfu();
}

/**
* 刘德华的具体实现类,也是代理类依赖的类,具体方法的实现类
* @author Administrator
*
*/
public class LiuDeHua implements Singer{

@Override
public void sing() {
// TODO Auto-generated method stub
System.out.println("刘德华在唱歌");
}

@Override
public void dance() {
// TODO Auto-generated method stub
System.out.println("刘德华在跳舞");
}

@Override
public void kungfu() {
// TODO Auto-generated method stub
System.out.println("刘德华在打功夫");
}
}

/**
* 刘德华的代理类,与刘德华具体类有相同的接口,通过内置的刘德华对象调用刘德华具体类的方法。
* @author Administrator
*
*/

public class LiuDeHuaProxy implements Singer{
private static LiuDeHua liudehua;
static{
if(liudehua==null){
liudehua=new LiuDeHua();
}
}
@Override
public void sing() {
// TODO Auto-generated method stub
liudehua.sing();
}
@Override
public void dance() {
// TODO Auto-generated method stub
liudehua.dance();
}
@Override
public void kungfu() {
// TODO Auto-generated method stub
liudehua.kungfu();
}
}

/**
* 客户端,通过刘德华的代理类就可以调用刘德华具体类的方法。
* @author Administrator
*
*/
public class Client {
public static void main(String[] args){
LiuDeHuaProxy proxy=new LiuDeHuaProxy();
proxy.sing();
proxy.dance();
proxy.kungfu();
}
}
使用Java中提供的代理
import java.lang.reflect.*;中提供了一套用于代理模式的方法,简化了该模式写法。
将上面的例子改为使用Java提供的方法来写,那么首先改变的是代理类,代理类变成了如下:
package com.example.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class LiuDeHuaDynamicProxy {
Singer singer=null;
/**
* 初始化需要传入被代理对象
* @param singer
*/
public LiuDeHuaDynamicProxy(Singer singer){
this.singer=singer;
}
public Singer getProxy(){
/**
* Proxy的静态方法newProxyInstance可以获得一个代理对象,该方法需要三个三个参 *数,第一个参数是一个对象,需要传入被代理对象实现接口的类加载器。第二个参数是一个class数组
*第三个参数是实现了InvocationHandler接口类的对象,这里直接使用*InvocationHandler的匿名内部类,
*/
return (Singer)Proxy.newProxyInstance(Singer.class.getClassLoader(), new Class[]{Singer.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//**
* 根据不同的方法名字调用真实目标类的方法
*/
if(method.getName().equals("sing")){
return method.invoke(singer, args);
} if(method.getName().equals("dance")){
return method.invoke(singer, args);
} if(method.getName().equals("kungfu")){
return method.invoke(singer, args);
}
return null;
}
});
}
}

这里需要说明的是,第三个参数可以传入一个实现InvocationHandler的类的对象。
然后的我们修改客户端:
package com.example.proxy;
/**
* 客户端类,通过刘德华的代理类就可以调用刘德华具体类的方法。
* @author Administrator
*
*/
public class Client {
public static void main(String[] args){
// LiuDeHuaProxy proxy=new LiuDeHuaProxy();
// proxy.sing();
// proxy.dance();
// proxy.kungfu();
LiuDeHuaDynamicProxy proxy=new LiuDeHuaDynamicProxy(new LiuDeHua());
//获得一个代理对象
Singer singer=proxy.getProxy();
singer.dance();
singer.sing();
singer.kungfu();
}
}
输出结果:
刘德华在跳舞
刘德华在唱歌
刘德华在打功夫






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值