一、代理模式
代理(Proxy)是一种设计模式,提供了间接对目标对象进行访问的方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能。这就符合了设计模式的开闭原则,即在对既有代码不改动的情况下进行功能的扩展。
①静态代理(以租房为例)
在使用静态代理时,被代理对象与代理对象需要一起实现相同的接口或者是继承相同父类,因此要定义一个接口或抽象类.
1、编写接口
package cn.cduestc.proxymode.staticproxy;
public interface Rent {
void rent();
}
2、创建真实出租房屋的对象
package cn.cduestc.proxymode.staticproxy;
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东将房子出租出去");
}
}
3、创建代理对象
package cn.cduestc.proxymode.staticproxy;
public class ProxyManager implements Rent {
private Rent rent;
public ProxyManager(){
}
public ProxyManager(Rent rent){
this.rent = rent;
}
@Override
public void rent() {
seeHouse();
rent.rent();
contract();
}
public void seeHouse(){
System.out.println("带客户去看房");
}
public void contract(){
System.out.println("客户签订合同");
}
}
4、创建客户对象
package cn.cduestc.proxymode.staticproxy;
public class Client {
public static void main(String[] args) {
Host host = new Host();
ProxyManager proxyManager = new ProxyManager(host);
proxyManager.rent();
}
}
优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
②动态代理(用找工作为例)
1、编写被代理接口
package cn.cduestc.proxymode.dynamicproxy;
public interface Job {
void job();
}
2、创建有招人意向的公司
package cn.cduestc.proxymode.dynamicproxy;
public class Company implements Job {
@Override
public void job() {
System.out.println("公司有职位需要招人");
}
}
3、编写创建代理类的类
package cn.cduestc.proxymode.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
private Job job;
public void setJob(Job job) {
this.job = job;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),job.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(job, args);
return result;
}
public void log(String msg){
System.out.println("[Debug] 执行了" + msg);
}
}
4、测试(创建找工作的人)
package cn.cduestc.proxymode.dynamicproxy;
public class Client {
public static void main(String[] args) {
Company company = new Company();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setJob(company);
Job proxy = (Job) pih.getProxy();
proxy.job();
}
}
③创建代理类的模板
package cn.cduestc.proxymode;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandlerDemo implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String msg){
System.out.println("[Debug] 执行了" + msg);
}
}