当当当当~~~~欢迎大家阅读,今天我们学习六大常用软件设计模式中的代理模式
一:代理模式的介绍
在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象
二:代理模式的定义
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
三:代理模式的缺点和解决方式
1、优点
(1)可以是真实角色的操作更加纯粹!不用去关注一些公共业务
(2)公共业务就交给代理角色!实现了业务的分工
(3)公共业务发生扩展时,方便集中管理
2、缺点
(1)代理模式会造成系统设计中类的数量增加;
(2)在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
(3)增加了系统的复杂度;
3、解决方式:
如何解决以上提到的缺点?
可以使用动态代理方式
四:代理模式的结构
代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问
五:代理模式分类
静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
静态代理
一、角色分析
抽象角色:一般会使用接口或者抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
客户:访问代理对象的人。
二、代理实例
先看问题:租房子
租房接口类
/**租房的接口*/
public interface Rent {
public void rent();
}
房东类
/**房东*/
public class Host implements Rent{
//这里如果不适用代理模式也完全可以不适用上面的接口就可以实现了
@Override
public void rent(){
System.out.println("房东出租房子!");
}
}
租客类
/**租客*/
public class Client {
public static void main(String[] args) {
Host host = new Host();
host.rent();
}
}
问题:在上面的代码中,我们肯定可以租到房子,但是现实却是我们并不知道谁会出租房子,我们要是租房子,肯定是更多的来源是需要中介来进行代理租房的。
中介代理
/**中介*/
public class Proxy implements Rent{
private Host host;
public Proxy(){
}
/**接受房东的访客*/
public Proxy(Host host){
this.host=host;
}
/**帮房东出租房子,并拿到该租客的客户*/
@Override
public void rent() {
host.rent();
}
/**下面时实现一些房东不方便的操作!!!*/
/**带租客看房*/
public void SeeHouse(){
System.out.println("中介带你逛其他别墅");
}
/**收中介费*/
public void Fare(){
System.out.println("中介收中介费");
}
/**签租赁合同*/
public void HeTong(){
System.out.println("签租赁合同");
}
}
/**租客*/
public class Client {
public static void main(String[] args) {
/*Host host = new Host();
host.rent();*/
//房东租房子
Host host = new Host();
//代理,中介帮房东租房子,
//但是呢?代理一般会有一些附属操作
Proxy proxy = new Proxy(host);
//不用去找房东了,可以直接找中介租房就可
//看房
proxy.SeeHouse();
//签合同
proxy.HeTong();
//租房到手
proxy.rent();
}
}
动态代理
一、动态代理介绍
动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的
动态代理分为两大类:基于接口的动态管理,基于类的动态管理
基于接口——JDK动态管理【我们这里使用原生jdk】
基于类:cglib
Java字节码实现:javasist
需要两个类:Proxy :代理,InvocationHandler :调用处理程序
InvocationHandler(Java.lang,reflect)反射包下面的接口
InvocationHandler是由代理实例的调用处理程序实现的接口。每个代理实例都有一个关联的调用处理程序,当在代理实例上调用方法,昂奋调用将被编码并分派到其调用处理程序的invoke方法。
Proxy(java.lang.reflect)反射包下面的类
Proxy提供了动态代理类和实例的静态方法,他也是由这些方法创建的所有动态代理类的超类。
二、代理实例
接口
public interface Rent {
/**房东*/
public void rent();
}
房东
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东租房子");
}
}
代理类
/**使用这个类自动生成代理类*/
public class ProxyInvocationHandler implements InvocationHandler {
/**被代理的接口*/
private Rent rent;
public void setRent(Rent rent){
this.rent=rent;
}
public Object getProxy(){
/*
* this.getClass().getClassLoader()
* rent.getClass().getInterfaces()定义的接口
* this指类本身
* 我们使用时只需要修改这个不同的接口就可以了,即修改rent*/
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
/**处理代理实例,并返回结果(核心)*/
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
/*method是反射包下面的方法
* method执行的时上面接口的方法
* 动态代理的本质,就是使用反射实现!
* */
seeHouse();
Object result = method.invoke(rent,args);
fare();
return null;
}
public void seeHouse(){
System.out.println("中介带看房子");
}
public void fare(){
System.out.println("中介收中介费");
}
}
实现类
public class client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理角色,现在没有
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//通过调用程序处理角色来处理我们需要调用的接口对象!
pih.setRent(host);
//这里的proxy就是动态生成的,我们并没有写
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}
以上就是六大常用软件设计模式中代理模式的内容啦,希望我的文章对你有所帮助,如果有错误的地方还望大家批评指正,谢谢大家阅读!