Modo proxy
Hoje aprenderemos o décimo segundo dos 23 padrões de projeto - o padrão proxy. O modo proxy é fornecer um proxy para um objeto, e o objeto proxy controla a referência ao objeto original. Isso torna impossível para os clientes se comunicarem diretamente com o objeto de destino real. O objeto proxy é o representante do objeto de destino e outras operações que precisam lidar com esse objeto de destino estão todas negociando com esse objeto de proxy.
conceito:
O modo proxy é que, por algum motivo, é necessário fornecer um objeto com um proxy para controlar o acesso ao objeto. Neste momento, o objeto de acesso não é adequado ou não pode se referir diretamente ao objeto de destino, e o objeto de proxy atuará como um intermediário entre o objeto de acesso e o objeto de destino.
Características:
vantagem:
- O modo proxy desempenha um papel intermediário entre o cliente e o objeto de destino e protege o objeto de destino;
- O objeto proxy pode estender a funcionalidade do objeto de destino;
- O modo proxy pode separar o cliente do objeto de destino, reduzindo o acoplamento do sistema até certo ponto.
deficiência:
- Adicionar um objeto proxy entre o cliente e o objeto de destino diminuirá a velocidade de processamento da solicitação;
- Maior complexidade do sistema.
código:
1. Proxy estático
目标接口
package cn.ppdxzz.proxy.staticproxy;
/**
* description:目标接口
* @author: PeiChen JavaAnything
*/
public interface ITeacherDao {
/**
* 教师授课的方法
*/
void teach();
}
目标对象(被代理对象)
package cn.ppdxzz.proxy.staticproxy;
/**
* description:目标对象(被代理对象)
* @author: PeiChen JavaAnything
*/
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("教师授课中...");
}
}
代理对象
package cn.ppdxzz.proxy.staticproxy;
/**
* description:代理对象
* @author: PeiChen JavaAnything
*/
public class TeacherDaoProxy implements ITeacherDao {
/**
* 目标对象,通过接口来聚合
*/
private final ITeacherDao targetObject;
public TeacherDaoProxy(ITeacherDao targetObject) {
this.targetObject = targetObject;
}
/**
* 具体代理操作的实现
*/
@Override
public void teach() {
System.out.println("开始代理某些操作...");
targetObject.teach();
System.out.println("代理操作完成");
}
}
静态代理客户端
package cn.ppdxzz.proxy.staticproxy;
/**
* description:静态代理客户端
* @author: PeiChen JavaAnything
*/
public class Client {
public static void main(String[] args) {
//1. 创建目标对象(被代理对象)
TeacherDao targetObject = new TeacherDao();
//2. 创建代理对象,把被代理对象传给代理对象
TeacherDaoProxy proxy = new TeacherDaoProxy(targetObject);
//3. 通过代理对象,去调用被代理对象的方法,执行的是代理对象的方法,代理对象再去调用目标对象的方法
proxy.teach();
}
}
resultado da operação:
[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-eTEgcLkh-1591153932251)(D:\cloudnote\images\image-20200426101603467.png )]
Vantagens e desvantagens do proxy estático:
vantagem:
- Com a premissa de não modificar a função do objeto de destino, a função de destino pode ser estendida por meio do objeto proxy.
deficiência:
-
Como o objeto proxy precisa implementar a mesma interface que o objeto de destino, haverá muitas classes proxy.
-
Depois que o método é adicionado à interface, o objeto de destino e o objeto proxy devem ser mantidos.
2. Proxy dinâmico
目标接口
package cn.ppdxzz.proxy.dynamicproxy;
/**
* description:目标接口
* @author: PeiChen JavaAnything
*/
public interface ITeacherDao {
/**
* 授课
*/
void teach();
/**
* 问好
* @param name 姓名
*/
void sayHello(String name);
}
目标对象(被代理对象)
package cn.ppdxzz.proxy.dynamicproxy;
/**
* description:目标对象(被代理对象)
* @author: PeiChen JavaAnything
*/
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("教师授课中...");
}
@Override
public void sayHello(String name) {
System.out.println("hello" + name);
}
}
代理对象
package cn.ppdxzz.proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* description:代理对象
* @author: PeiChen JavaAnything
*/
public class ProxyFactory {
/**
* 维护一个Object类型的目标对象
*/
private Object target;
public ProxyFactory(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("JDK代理开始...");
//反射机制调用目标对象的方法
Object returnVal = method.invoke(target, args);
System.out.println("JDK代理提交");
return returnVal;
}
});
}
}
动态代理客户端
package cn.ppdxzz.proxy.dynamicproxy;
/**
* description:动态代理客户端
* @author: PeiChen JavaAnything
*/
public class Client {
public static void main(String[] args) {
//创建目标对象
ITeacherDao target = new TeacherDao();
//创建代理对象
ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();
proxyInstance.teach();
proxyInstance.sayHello("小万");
}
}
resultado da operação:
O modo proxy é muito comum na vida real, por exemplo, a intranet penetra no firewall através de um proxy para obter acesso à rede pública, que usa o modo proxy.