增强对象的功能
我们需要用到设计模式去实现增强对象的功能,23种设计模式中的装饰模式和代理模式都可以实现,我们使用代理模式:
代理模式
以下以购买笔记本电脑为情景
不考虑网购的情况,用户买电脑无需跑到北京去购买,只需要去本地的代理商购买。反过来思考,相当于增强了北京联系公司的功能。
- 概念:
1.真实对象:被代理的对象(北京联想公司)
2.代理对象:(西安联想代理商)
3.代理模式:代理对象代理真实对象,达到增强真实对象功能的目的 - 实现方式:
1.静态代理:有一个类文件描述代理模式(即代理商固定就那几家)
2.动态代理:在内存中形成代理类(你在哪里购买电脑,哪里就动态生成代理商)
注意:我们使用动态代理模式 - 实现步骤:
1.代理模式和真实对象实现相同的接口
2.使用**Proxy.newProxyInstance()**方法获取代理对象
3.使用代理对象调用方法
4.增强方法 - 增强方式:
1.增强参数列表
2.增强返回值类型
3.增强方法执行逻辑
代码实现(代理对象实现基本业务功能)
注意:Proxy.newProxyInstance()
方法需要传的三个参数如下:
1.类加载器:真实对象.getClass().getClassLoader()
2.接口数组:真实对象.getClass().getInterfaces()
3.处理器:new InvocationHandler()
注意:代理对象调用的所有方法都会触发**invoke()**方法执行,方法需要传递的三个参数如下:
1.proxy:代理对象
2.method:代理对象调用的方法被封装成Method对象
3.args:代理对象调用方法时,传递的实际参数
注意:代理对象并不能直接执行真实对象的方法,就像西安联想代理商不能直接出售电脑,需要从北京联想公司进货。所以代理对象需要传递真实对象去调用方法
SaleComputer.java:
public interface SaleComputer {
public String sale(double money);
public void show();
}
Lenvo.java:
/**
* 真实类
*/
public class Lenovo implements SaleComputer {
@Override
public String sale(double money) {
System.out.println("花了" + money + "元购买了一台联想电脑");
return "联想电脑";
}
@Override
public void show() {
System.out.println("展示电脑....");
}
}
ProxyTest.java:
public class ProxyTest {
public static void main(String[] args) {
//1.创建真实对象
Lenovo lenovo = new Lenovo();
//2.动态代理增强Lenovo对象
/*
三个参数:
1.类加载器:真实对象.getClass().getClassLoader()
2.接口数组:真实对象.getClass().getInterfaces()
3.处理器:new InvocationHandler()
*/
SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(),
lenovo.getClass().getInterfaces(), new InvocationHandler() {
/*
代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
参数:
1.proxy:代理对象
2.method:代理对象调用的方法被封装成Method对象
3.args:代理对象调用方法时,传递的实际参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//使用真实对象调用该方法
Object obj = method.invoke(lenovo, args);
return obj;
}
});
//3.调用方法
String computer = proxy_lenovo.sale(8000);
System.out.println(computer);
}
}
此时执行ProxyTest会发现代理对象能够正常实现业务需求
代码实现(用代理对象增强真实对象的功能)
- 增强参数列表
西安代理商可以以更便宜的价格从北京联想公司进货,假设代理商只需要用**出售价的85%**的价格进货
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断是否是sale方法
if (method.getName().equals("sale")) {
//增强参数
double money = (double) args[0];
money = money * 0.85;
//使用真实对象调用该方法
Object obj = method.invoke(lenovo, money);
return obj;
} else {
Object obj = method.invoke(lenovo, args);
return obj;
}
}
用户使用了8000元购买,所以代理商**赚了15%**的利润
- 增强返回值类型
由于代理商赚了**15%**的利润,所以代理商可以附赠一些赠品
- 增强方法执行逻辑
比如说提供售前服务