转账类里有一个转账方法
public class 转账{
public void 转账(String A,String B,Integer money){
System.out.println("A转给B“+money+"元");
}
}
市面上常用的转账方法是ZFB和VX,银联二维码等被ZFB、VX扫码后执行支付功能。这里的二维码实现了跨平台功能。
因为以ZFB为例,银联只需开发转账方法(如上),ZFB实现代理功能,通过支付宝平台 无需开发自己的支付软件 便可得到收益且规避了一定的风险。即给目标对象一个代理对象,由代理对象控制着对目标对象的引用。
1、功能增强:通过代理业务对原有业务进行增强
2、用户只能通过代理对象间接的访问目标对象,防止用户直接访问目标对象给系统带来不必要的复杂性!
/**
* 衣服工厂 目标类
*/
public class ClothesFactory implements Clothes{ //实现相应接口
//核心方法
public void byClothes(String size){
System.out.println("为您定制一件大小为"+size+"的衣服");
}
}
/**
* 鞋子工厂 目标类
*/
public class ShootFactory implements Shoot{
//核心方法
public void byShoot(String size){
System.out.println("为您定制一双大小为"+size+"的鞋子");
}
}
/**
* 鞋子接口
*/
public interface Shoot {
public void byShoot(String size);
}
/**
* 衣服接口
*/
public interface Clothes {
public void byClothes(String size);
}
/**
* 静态代理类
*/
public class Agent implements Clothes,Shoot{
//1、控制访问
ClothesFactory clothesFactory=new ClothesFactory();
ShootFactory shootFactory=new ShootFactory();
//2、提供方法
public void byClothes(String size){
System.out.println("量身定制");
clothesFactory.byClothes(size);
System.out.println("打包快递");
System.out.println("*********************");
}
public void byShoot(String size){
System.out.println("量身定制");
shootFactory.byShoot(size);
System.out.println("打包快递");
System.out.println("*********************");
}
}
/**
* 顾客
*/
public class Person {
public static void main(String[] args) {
Agent proxy=new Agent(); //proxy代理对象
proxy.byClothes("xl");
proxy.byShoot("42");
}
}
随着目标类(被代理的类)的增多,代理类需要代理的目标类也会增多,一个代理类生成多个对象。每一个目标对象都是代理着多个目标对象
=====> 静态代理问题:当我们的目标类增多的时候,代理类需要代理的目标类增多,可能会出现代理关系不便。当我们的目标类进行修改或增多的时候,会影响目类以及要改动代理类
(1)代理复杂,难于管理
代理类和目标类实现了相同的接口,每个代理都需要实现目标类的方法,这样就出现了大量的代码重复。如果接口增加一个方法,除了所有目标类需要实现这个方法外,所有代理类也需要实现此方法。——>增加了代码维护的复杂度。
(2)代理类依赖目标类+代理类过多
代理类只服务于一种类型的目标类,如果要服务多个类型。势必要为每一种目标类都进行代理,静态代理在程序规模稍大时就无法胜任了,代理类数量过多。
补充:静态代理只适合业务功能固定不变的情况。(业务接口方法不进行增加和减少,实现类就不需要改动)
静态
要实现动态问题在于如何让一个类生成不同类的对象,但ABC理论上是相同的 因为同一类对象有相同的类模板。
为什么让不同的代理对象代理不同的类? 便于添加新的目标类(例如新添加袜子工厂时无需再去改动代理类,而是通过添加新的代理对象来实现)
动态代理:生成不同的代理对象,每一个代理对象都代理着自己的目标对象(术业有专攻)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理类
* 1、目标类的引用
* 2、调用目标类的核心方法,并实现功能的增强
* 核心方法在于目标类实现的接口当中
* 如何找到目标类的接口-------》反射(找到类信息)
*/
public class Agent_Dynamic implements InvocationHandler{
//1、目标类的引用 与静态相比较灵活
private Object factory;
public Agent_Dynamic(Object factory){
this.factory=factory;
}
//反射找到目标类接口
public Object getProxyInterface(){
return Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(), (InvocationHandler) this);
}
/**
* 如何调用核心方法?? -----》 jdk(java的开发者)给我们提供了调用核心方法的接口
* @param proxy
* @param method 通过反射带来的核心方法
* @param args 核心方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("----前期准备----");
method.invoke(factory,args); //invoke里边是对象和参数
System.out.println("----打包发货----");
return null;
}
}
/**
*客户
*/
public class Person {
public static void main(String[] args) {
ClothesFactory clothesFactory=new ClothesFactory();
Clothes proxy1=(Clothes) new Agent_Dynamic(clothesFactory).getProxyInterface(); //生成代理类对象
proxy1.byClothes("xxl");
ShootFactory shootFactory=new ShootFactory();
Shoot proxy2=(Shoot) new Agent_Dynamic(shootFactory).getProxyInterface();
proxy2.byShoot("37");
}
}
(接口 工厂类与静态代理相同)