设计模式之Proxy

继续学习代理模式:
我要找咱公司老总办事,可无奈,我认识他,他不认识我,无法直接找到他,这件事眼看就要黄。这时突然想起,咱之前给老总的秘书小刘跑过腿,咱可以试试通过小刘来帮我把礼送到老总那,看能不能同样把事情办好。这秘书小刘平常在公司就经常挂着个牌子,找老总办事,先通过我。。。
现实中,代理模式的例子举不胜举,比如销售代理也是最常见的一种,这里我们举一个电脑销售的例子,来简单的学习一下代理模式的核心思想。

一。提供一个公共接口,真实的对象(被代理对象)--电脑厂商以及代理对象--电脑代理商都具有销售掉闹的方法。
public interface SaleComputer {

public void sale();
}


二。真实对象(被代理对象)--电脑厂商,实现公共接口
public class ComputerMaker implements SaleComputer {

public void sale() {
System.out.println("电脑卖给你");

}

}


三。代理对象--电脑代理商,也实现该接口,并持有被代理对象的一个引用,并在公共接口方法里调用真实对象的方法,并且增加自己的特有内容

public class ComputerProxy implements SaleComputer {
private ComputerMaker maker;

/*public ComputerMaker getMaker(){
if(null == maker){
maker = new ComputerMaker();
}
return maker;
}*///通常此方法对客户是不可见的,不然,咱直接就找电脑商买了~~
public void sale() {
preSale();
if(null == maker){
maker = new ComputerMaker();
}
maker.sale();
postSale();

}

public void preSale(){
System.out.println("来代理商这里买就送你一个鼠标");
}

public void postSale(){
System.out.println("代理商送你一个鼠标");
}

}


四。客户端,测试一下
public class Client
{
public static void main(String[] args)
{
ComputerProxy proxy = new ComputerProxy();
proxy.sale();
}
}



以上是最简单的代理模式的一个例子了,但却也包含了代理模式的实质内涵。

接着是动态代理:被代理对象可以在运行时动态改变,需要控制的接口可以在运行时改变,控制的方式也可以动态改变,从而实现了非常灵活的动态代理关系。
动态代理的适用场合:调试;RMI调用
动态代理的创建步骤:1.创建一个实现java.lang.reflect.InvocationHandler接口的类,并实现invoke方法
2.创建被代理的类以及接口
3.通过java.lang.reflect.Proxy的静态方法newProxyInstance创建一个代理。
4.通过代理调用公共接口方法(会自动调用invoke方法)

我们仍然使用电脑代理商的例子:
1.创建一个实现InvocationHandler接口的代理手柄(ProxyHandler)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {
private Object obj;//这里是Object类型的引用,使得在运行时动态加
//载被代理对象
public ProxyHandler(Object obj){
this.obj = obj;
}


public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
String type = (String) arg2[0];
if("联想"==type||"华硕"==type){
preInvoke();
arg1.invoke(obj, arg2);
postInvoke();
}
else System.out.println("这里没有"+type+"牌子的电脑");
return null;
}

public void preInvoke(){
System.out.println("来代理商这里买就给送你一个鼠标");
}

public void postInvoke(){
System.out.println("代理商送你一个鼠标");
}

}

2.创建真实对象(ComputerMaker)和公共接口(SaleComputer)


public interface SaleComputer {

public void sale(String type);
}



public class ComputerMaker implements SaleComputer {

public void sale(String type) {
System.out.println("卖给你一台"+type+"电脑");

}

}

3.创建一个客户端来测试
import java.lang.reflect.Proxy;

public class Buyer {


public static void main(String[] args) {
ComputerMaker maker = new ComputerMaker();
Class<?> classType = maker.getClass();
ProxyHandler handler = new ProxyHandler(maker);
SaleComputer proxy = (SaleComputer) Proxy.newProxyInstance(classType.getClassLoader(), classType.getInterfaces(), handler);
proxy.sale("Dell");
}

}



动态代理还是相当重要的,其实原理还是基于反射。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值