代理可以理解为替代代理者完成的一些任务,可能是变的、可能需要一些专业知识、可能需要一些特定的资源…总之,这些任务,被代理者自己处理会很麻烦,那么我们就交给代理者完成。比如,拿生活中我们买房子的例子,一般买房子我们一般会找中介,中介能到了什么样的作用?资金监管、解读购房政策,因为更专业、拥有更丰富的资源、明白购房的手续等等,所以中介这个角色起到了至关重要的作用。同样在Java中,在执行某些类的方法之前,我们也要做这样的一些事情:事物的开启与提交、权限的验证、日志的打印、时间的统计…这些事情不属于我们项目的业务逻辑部分,因为他们多变、繁琐、覆盖面广…不适合每一个类的每一个方法对应的添加。这样一说是不是更好的理解了?
1.什么是代理模式?
静态代理类只能替一个主题接口进行代理工作。如果主题接口不同,代理工作相同,也需要编写两个代理类。
(1)被代理者,主要负责业务逻辑
(2)代理者,类似后勤保障的
(3)主题:类似接口(需要实现)
2.静态代理模式
(1)被代理者,主要负责业务逻辑
(2)代理者,手动编写一个代理类
(3)主题:类似接口(需要实现)
优点:代码简洁、容易理解 缺点:代码冗余(多个主题接口)
代码演示1:
package com.conding0110lin.example;
/*代理设计模式*/
public class AgencyTest {
public static void main(String[] args) {
/*House house = new Agency();//多态引用
house.buy();*/
//中介会代理顾客做一些繁琐的业务事情。
//(中介)验证房源是否合法、有效、尾款处理...
House house = new Agency(new Customer());//多态引用--两次向上转型
house.buy();
/*中介会代理顾客做一些繁琐的业务事情。
(中介)验证房源是否合法、有效、尾款处理...
顾客需要自己交钱、签合同、拿钥匙...(核心事情)*/
}
}
//主题接口(实现的功能)
interface House{
void buy();
}
//被代理者(顾客)
class Customer implements House{
@Override
public void buy() {
//核心的事情由自己去做,非核心的事情由代理(中介)去做
System.out.println("顾客需要自己交钱、签合同、拿钥匙...(核心事情)");
}
}
//代理者(中介)
class Agency implements House{
private House target;
public Agency(House target) {
super();
this.target = target;
}
@Override
public void buy() {
System.out.println("中介会代理顾客做一些繁琐的业务事情。");
System.out.println("(中介)验证房源是否合法、有效、尾款处理...");
target.buy();//被代理者(顾客)处理的核心事情
}
}
☞思考:现在被代理者(顾客)不仅仅是买房子的,还有租房子的,意思就是被代理者(顾客)不止一个了,这里解决的方式之一就是需要再写一个代理类(中介)【为租房子的主题接口编写一个代理类】。想想在我们实际生活中,不管是顾客租房子还是买房子,一个中介就能同时满足多个顾客的需求,所以在Java设计模式中,两个主题接口,代理者应该一个就能解决。显然这种静态设计模式实现就比较麻烦,接下里就会采用动态设计模式进行实现。
3.动态代理模式
(1)被代理者,主要负责业务逻辑
(2)不直接编写代理类,编写一个叫做代理工作处理器的类
代理工作处理器必须实现一个java.lang.reflect.InvocationHandler接口
(3)主题:类似接口(需要实现)
(4)动态的创建代理类或代理类的对象
java.lang.reflect .Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
引用JDK_API_1.6
代码演示2:
package com.conding0110lin.example;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*代理设计模式*/
public class AgencyTest {
public static void main(String[] args) {
// (1)创建被代理者对象(买房子顾客)
Customer buyCustomer = new Customer();
//(2)获取被代理者的类加载器
ClassLoader loader = buyCustomer.getClass().getClassLoader();
//(3)获取被代理者的实现的实现的接口们
Class<?>[] interfaces = buyCustomer.getClass().getInterfaces();
//(4)创建代理工作处理器对象
Handler h =new Handler(buyCustomer);
/**
* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
* 参数1:表示被代理者的类加载器
* 参数2:被代理者实现的接口们
* 参数3:代理者要替被代理者,做的代理工作处理器对象
*/
Object proxy = Proxy.newProxyInstance(loader, interfaces, h);
BuyHouse buyHouse = (BuyHouse)proxy;
buyHouse.buy();
/* 中介会代理顾客做一些繁琐的业务事情。
(中介)验证房源是否合法、有效、尾款处理...
买房子顾客需要自己交钱、签合同、拿钥匙...(核心事情)*/
Renter renter = new Renter();
ClassLoader loader2 = renter.getClass().getClassLoader();
Class<?>[] interfaces2 = renter.getClass().getInterfaces();
Handler h2 =new Handler(renter);
Object proxy2 = Proxy.newProxyInstance(loader2, interfaces2, h2);
RentHouse rentHouse = (RentHouse)proxy2;
rentHouse.buy();
/* 中介会代理顾客做一些繁琐的业务事情。
(中介)验证房源是否合法、有效、尾款处理...
租房子顾客需要自己交钱、选房、配钥匙...(核心事情)*/
}
}
// 主题接口(实现的功能)
interface BuyHouse {
void buy();
}
interface RentHouse {
void buy();
}
// 被代理者(买房子顾客)
class Customer implements BuyHouse {
@Override
public void buy() {
// 核心的事情由自己去做,非核心的事情由代理(中介)去做
System.out.println("买房子顾客需要自己交钱、签合同、拿钥匙...(核心事情)");
}
}
// 被代理者(租房子顾客)
class Renter implements RentHouse {
@Override
public void buy() {
// 核心的事情由自己去做,非核心的事情由代理(中介)去做
System.out.println("租房子顾客需要自己交钱、选房、配钥匙...(核心事情)");
}
}
//代理工作器-无固定为哪个主题接口的实现类代理
class Handler implements InvocationHandler {
private Object target;
public Handler(Object target) {
super();
this.target = target;
}
/*
* 此方法体:
* (1)代理工作的代码
* (2)被代理者调用自己的核心逻辑方法
* 形参一:proxy 表示代理类的对象
* 形参二:method 表示被代理者真正要代用的方法
* 形参三:args 表示method方法执行时需要的实参
* Method类object invoke(object obj ,object...args) obj调用方法的对象,args表示方法的实参列表
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("中介会代理顾客做一些繁琐的业务事情。");
System.out.println("(中介)验证房源是否合法、有效、尾款处理...");
Object returnvalue = method.invoke(target, args);
return returnvalue;
}
}
推荐阅读往期博文:
•23种设计模式#【代码示例】工厂设计模式(反射&方法实现)
•23种设计模式#【代码示例】单例设计模式(饿汉&懒汉|加锁&双重检查&静态内部类)
#轻松一刻
☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!
☞本人博客:https://coding0110lin.blog.csdn.net/ 欢迎转载,一起技术交流吧!