代理模式个人理解:代理者(Proxy)跟当事人(RealSubject),实现共同的抽象(类/接口),代理者持有当事人的引用,并调用当事人的具体方法。
举个栗子:想买一部Iphone,但是现在国内没有?只能找代购了~
1,创建共同的接口(买手机)
/**
* 代理模式
* @author cuishuxiang
*
*/
public interface Subject {
void buyIphone();
}
2,创建当事人(RealSubject)
/**
* 真实的购买者
* @author cuishuxiang
*
*/
public class RealSubject implements Subject{
@Override
public void buyIphone() {
// TODO Auto-generated method stub
System.out.println("csx 需要买一台iPhone!");
}
}
3,创建代购,并将当事人的需求传递给代购(引用)
package proxy_mode;
/**
* 代购:iPhone
* @author cuishuxiang
*
*/
public class ProxySubject implements Subject {
Subject subject;
public ProxySubject(Subject subject) {
this.subject=subject;
}
@Override
public void buyIphone() {
// 代购在给当事人买手机之前可以做一些事情
// 例如:收取手续费
beforeBuyIphone();
subject.buyIphone();
//代购在给当事人买手机之后,可以做一些事情
afterBuyIphone();
}
private void beforeBuyIphone() {
}
private void afterBuyIphone() {
}
}
4,创建测试类
package proxy_mode;
/**
* 代理模式 :测试类
* @author cuishuxiang
*
*/
public class ClientTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1.创建真正的购买者
Subject realBuyPerson=new RealSubject();
//2,创建代购
Subject proxyPerson=new ProxySubject(realBuyPerson);
//3,代购去买手机
proxyPerson.buyIphone();
}
}
代理类Proxy
中的代码,最终调用的还是当事人RealSubject
中的购买方法,故打印日志如下:
------------------------------------------------我是分隔线-------------------------------------
静态 / 动态代理区别(按照创建时期):
1,静态代理:程序员创建生成代码,在对其编译。在程序运行之前代理类的.class
就已经存在了。
2,动态代理:在程序运行时期,通过反射机制动态创建生成。
动态代理
动态代理,涉及到两个类:Proxy
和InvocationHandler
Java提供了一个便捷的动态代理接口InvocationHandler,动态代理类只要实现这个接口就行;
先按照上面的例子,使用动态代理书写代码如下:
public interface Subject {
void buyPhone();//购买手机
}
/**
* 真正买手机的人
* @author cuisx
*/
public class RealSubject implements Subject{
@Override
public void buyPhone() {
// TODO Auto-generated method stub
System.out.println("需要一部三星手机!");
}
}
/**
* 动态代理
* @author cuisx
*
*/
public class DynamicProxySubject implements InvocationHandler{
private Subject mSubject;
//将被代理的对象,传入
public DynamicProxySubject(Subject subject) {
this.mSubject=subject;
}
@Override
public Object invoke(Object proxy, Method medthod, Object[] arg2) throws Throwable {
//这里可以做一些别的操作
System.out.println("代理买手机之前,加价操作!");
Object obj=medthod.invoke(mSubject, arg2);
return obj;
}
}
/**
* 测试类
* @author cuisx
*
*/
public class DyanmicTest {
public static void main(String[] args) {
//1,创建具体的client
Subject realBuy=new RealSubject();
//2,创建代理
DynamicProxySubject proxy=new DynamicProxySubject(realBuy);
Subject subject=(Subject)Proxy.newProxyInstance(
Subject.class.getClassLoader(),
new Class[] {Subject.class},
proxy);
subject.buyPhone();
}
}