代理模式(Proxy Pattern),通过一个代理类,来支持原本想调用类的功能,并能在原有类的基础上,附加其他功能。也就是说我原本想调用A类,但是现在我改成调用B类,并且B类拥有完整的A的功能,对调用方依然可以拿到A的结果,而且还可以在调用前后附加其他功能,或者是修改结果。
但是为什么这么做呢?
通过代理类,可以在调用A类目标方法的前后,附加一些功能,比如在A类的business()方法前后记录日志、记录时间进行性能监控等。
这样就能让我们即拥有A的完整功能,又能扩展出其他我们需要的功能。
总结来说:代理模式将和业务不相关的功能,剥离出来,交给其他角儿来完成,从而使我们的业务类更专注与业务代码。
代理类分为静态代理和动态代理。
我们先来看看静态代理。
我们在demo中添加两个基于用户的方法,一个是用户登录,一个是模拟一个用户业务计算的方法。其中用户登录,我们让代理类除了登录以外,还附加日志记录功能,用户每次登录时都进行日志记录;另一个业务计算方法,我们让代理类另外完成性能监控功能。
1、建立抽象用户类
package com.my.study.design.proxy;
/**
* www.itzhimei.com
*/
public interface IUser {
void login(String userName,String pwd);
void business() throws InterruptedException;
}
2、实现用户类
package com.my.study.design.proxy;
/**
* www.itzhimei.com
*/
public class User implements IUser {
@Override
public void login(String userName,String pwd) {
System.out.println("用户["+userName +"]登录.");
}
@Override
public void business() throws InterruptedException {
System.out.println("执行业务方法计算中....");
Thread.sleep(500L);
System.out.println("执行业务方法计算完成");
}
}
3、定义代理类,代理类也实现抽象用户方法,让代理类看起来和用户类是一样的,具备相同能力。
package com.my.study.design.proxy;
/**
* www.itzhimei.com
*/
public class Proxy implements IUser {
private IUser user;
public Proxy(IUser user) {
this.user = user;
}
@Override
public void login(String userName, String pwd) {
//登录时进行日志打印
System.out.println("用户["+userName +"]登录日志记录开始...");
user.login(userName, pwd);
System.out.println("用户["+userName +"]登录日志记录结束...");
}
@Override
public void business() throws InterruptedException {
long startTimestamp = System.currentTimeMillis();
user.business();
long endTimeStamp = System.currentTimeMillis();
long t = endTimeStamp - startTimestamp;
System.out.println("用户执行业务计算总用时:"+ t);
}
}
在代理类中,持有了一个User对象,真正的用户业务,代理类会调用用户类来处理,代理类在调用用户类之前或之后附加其他功能。
4、测试
package com.my.study.design.proxy;
/**
* www.itzhimei.com
*/
public class Client {
public static void main(String[] args) throws InterruptedException {
IUser user = new User();
IUser proxy = new Proxy(user);
proxy.login("张三","123");
System.out.println("----------------------------------");
proxy.business();
}
}
输出:
用户[张三]登录日志记录开始...
用户类输出:用户[张三]登录.
代理类输出:用户[张三]登录日志记录结束...
----------------------------------
用户类输出:执行业务方法计算中....
用户类输出:执行业务方法计算完成
代理类输出:用户执行业务计算总用时:500
以上就是一个静态代理的完整实现。
类关系图: