增强对象的功能
我们需要用到设计模式去实现增强对象的功能,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%
的利润,所以代理商可以附赠一些赠品
-
增强方法执行逻辑
比如说提供
售前服务