由于某些原因,客户端不想或不能直接访问一个对象,此时可以通过一个称为“代理”的第三者来实现间接访问,该方案对应的设计模式被称为代理模式。
定义如下:
代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。
代理模式包含3个角色:
代理模式有很多种实现,根据目的和实现方式不同可以分为很多种。
本文demo案例介绍下静态代理和JDK动态代理这两种。
静态代理
//抽象主题对象
public interface Subject {
void request();
}
//具体的真实主题对象
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("真实主题的业务方法");
}
}
//代理对象
public class ProxySubject implements Subject{
private Subject subject = new RealSubject();
@Override
public void request() {
System.out.println("前置方法代码");
subject.request();
System.out.println("后置方法代码");
}
}
动态代理
//抽象主题对象
public interface IUserDao {
void save();
}
//具体的真实主题对象
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("保存了数据");
}
}
//代理对象
public class IUserDaoFactory {
//代理的目标对象
private Object target;
public IUserDaoFactory(Object target) {
this.target = target;
}
//对目标对象进行动态代理
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("做一些操作A");
Object resultValue = method.invoke(target, args);
System.out.println("做一些操作B");
return resultValue;
}
});
}
}
//客户端
public class Client {
public static void main(String[] args) {
//静态代理
Subject subject = new ProxySubject();
subject.request();
//JDK动态代理demo
IUserDao userDao = new UserDao();
IUserDaoFactory factory = new IUserDaoFactory(userDao);
IUserDao proxyUserDao = (IUserDao) factory.getProxyInstance();
proxyUserDao.save();
}
}
代理模式的类型较多,不同类型的代理模式有不同的优缺点,应用于不同的场合。
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git