1.ProxyTest 代理模式
package com.zhaoshuangjian.mode04_代理模式; import com.zhaoshuangjian.mode04_代理模式.mode04.NP非代理.UserOwn; import com.zhaoshuangjian.mode04_代理模式.mode04.ProxyFactory; import com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理.Secretary; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.DogImpl; import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.UserImpl; /** * ProxyTest 代理模式 * * @Auther: zhaoshuangjian 2023-03-23 下午10:39 */ public class ProxyTest { public static void main(String[] args) { String uName = "奥利奥饼干"; String dName = "狗粮"; // 1、不使用代理 noProxy(uName); // 2、使用静态代理 useStaticProxy(uName,dName); // 3、使用动态代理 useDynamicProxy(uName, dName); int second = 5; // 4、使用虚拟代理 useVirtualProxy(second); /** * 不使用代理:没有对比就没有伤害,主要和下面使用了代理模式的对象进行比较 * 静态代理:针对特定对象的访问进行"装饰",虽和装饰者模式很像,但也只是很像,切记搞混淆 * 动态代理:区别静态代理,静态代理模式在程序编译时即确定了被代理的对象 * 而动态代理只有在程序运行时才确定要被代理的对象是谁 * 动态代理主要应用于框架,即反射技术一般用不到,如果用到了,那多半是用于框架级的项目 * 典型代表:Spring框架 -- AOP【面向切面编程】 * 虚拟代理:可延缓被代理对象的创建 * 优点: 程序启动快 * 缺点: 因为被代理的实例不是在第一时间创建的,因此在使用的时候, * 需要狠小心的判断null值,以防止NullPointException * * 还有其他代理模式,就不一一列举了 */ } /** * 不使用代理 * @param uName 用户商品名称 */ private static void noProxy(String uName) { // 不使用代理模式,用户自己去超市买商品 UserOwn userOwn = new UserOwn(); userOwn.getCommodity(uName); System.out.println("===========分割线==========="); } /** * 使用静态代理 * @param uName 用户商品名称 * @param dName 宠物狗商品名称 */ private static void useStaticProxy(String uName,String dName) { // 使用静态代理模式,通过UU跑腿服务,用户拿到自己要的薯片 ProxyFactory.getUserProxy().getCommodity(uName); System.out.println("===========分割线==========="); // 使用静态代理模式,通过UU跑腿服务,宠物狗拿到自己要的狗粮 ProxyFactory.getDogProxy().getCommodity(dName); System.out.println("===========分割线==========="); } /** * 使用动态代理 * @param uName 用户商品名称 * @param dName 宠物狗商品名称 */ private static void useDynamicProxy(String uName, String dName) { // 使用动态代理模式,通过UU跑腿服务,用户拿到自己要的薯片 CommodityService userProxy =(CommodityService)( ProxyFactory.getDynProxy(new UserImpl())); userProxy.getCommodity(uName); System.out.println("===========分割线==========="); // 使用动态代理模式,通过UU跑腿服务,宠物狗拿到自己要的狗粮 CommodityService dogProxy =(CommodityService)( ProxyFactory.getDynProxy(new DogImpl())); dogProxy.getCommodity(dName); System.out.println("===========分割线==========="); } /** * 使用虚拟代理 * @param second 秒数 */ private static void useVirtualProxy(int second){ Secretary secretary = new Secretary(); secretary.addDeal("合同1"); secretary.addDeal("合同2"); secretary.sign(); // 期望领导什么时候出现 secretary.initLeader(second); secretary.addDeal("合同3"); secretary.addDeal("合同4"); secretary.sign(); } }
2.代理类工厂
package com.zhaoshuangjian.mode04_代理模式.mode04; import com.zhaoshuangjian.mode04_代理模式.mode04.DP动态代理.DynamicProxy; import com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理.DogProxy; import com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理.UserProxy; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * <p>代理类工厂</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class ProxyFactory { /** * 获取一个静态用户代理类对象 */ public static CommodityService getUserProxy() { return new UserProxy(); } /** * 获取一个静态宠物狗的代理类对象 */ public static CommodityService getDogProxy() { return new DogProxy(); } /** * 获取动态代理对象 * @param target * @return */ public static Object getDynProxy(Object target) { InvocationHandler handler = new DynamicProxy(target); return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler); } }
3.动态代理类 == 程序运行时,代理类才知道被代理的对象是哪个
package com.zhaoshuangjian.mode04_代理模式.mode04.DP动态代理; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * <p>动态代理类 == 程序运行时,代理类才知道被代理的对象是哪个</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class DynamicProxy implements InvocationHandler { /** * 被代理的目标对象 */ private Object targetObj; /** * 暂时不知道被代理的对象是人还是动物或是其它...etc */ public DynamicProxy(Object object) { this.targetObj = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是UU跑腿的工作人员,我去超市帮助客户取商品:"+args[0]); Object object = method.invoke(targetObj, args); System.out.println("拿到被代理对象调用的方法名:"+method.getName()+",方法参数个数:"+method.getParameterCount()); System.out.println("商品已成功转交给被代理的对象,期待对象好评"); return object; } }
4.用户自己去超市取商品
package com.zhaoshuangjian.mode04_代理模式.mode04.NP非代理; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; /** * <p>用户自己去超市取商品 </p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class UserOwn implements CommodityService { @Override public void getCommodity(String name) { goSuperMarket(); choose(name); pay(); System.out.println("用户获得商品:"+name); goHome(); } private void goSuperMarket() { System.out.println("去超市"); } private void choose(String name) { System.out.println("选商品: " + name); } private void pay() { System.out.println("付钱"); } private void goHome() { System.out.println("买完商品,回家"); } }
5.商品接口
package com.zhaoshuangjian.mode04_代理模式.mode04.service; /** * <p>商品接口</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public interface CommodityService { /** * 获取指定商品 */ void getCommodity(String name); }
6.宠物狗实现商品接口 == 获取狗粮
package com.zhaoshuangjian.mode04_代理模式.mode04.service.impl; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; /** * <p>宠物狗实现商品接口 == 获取狗粮</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class DogImpl implements CommodityService{ @Override public void getCommodity(String name) { System.out.println("宠物狗获得商品:"+name); } }
7.用户实现商品类 == 获取吃的
package com.zhaoshuangjian.mode04_代理模式.mode04.service.impl; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; /** * <p>用户实现商品类 == 获取吃的</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class UserImpl implements CommodityService{ @Override public void getCommodity(String name) { System.out.println("用户获得商品:"+name); } }
8.宠物狗代理类 == 静态代理模式
package com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.DogImpl; /** * <p>宠物狗代理类 == 静态代理模式</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class DogProxy implements CommodityService{ private DogImpl dog; public DogProxy(){ // 预先确定代理与被代理者的关系 -- 被代理的对象是宠物狗 dog = new DogImpl(); } @Override public void getCommodity(String name) { System.out.println("我是UU跑腿的工作人员,我去超市帮助狗狗取狗粮:"+name); dog.getCommodity(name); System.out.println("商品已成功交给狗狗,期待狗狗的主人好评"); } }
9.用户代理类 == 静态代理模式,被代理的对象在编译时就知道了
package com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理; import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService; import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.UserImpl; /** * <p>用户代理类 == 静态代理模式,被代理的对象在编译时就知道了</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class UserProxy implements CommodityService{ /** * 区别于装饰者模式,这里的被代理的对象的实例是在代理的类中完成实例化的,不对外暴露 * 虽然代理模式有点类似于装饰者模式,但是本质上还是有区别的 * 1、代理模式主要是控制某个特定对象的访问 * 2、装饰模式主要是给对象添加行为 * 3、不是所有实现了接口的类对象都可以成为被代理的对象【要深刻理解这句话】 * 4、所有实现了接口的类对象都可以成为被装饰的对象 */ private UserImpl user; public UserProxy() { // 预先确定代理与被代理者的关系 -- 被代理的对象是人 user = new UserImpl(); } @Override public void getCommodity(String name) { System.out.println("我是UU跑腿的工作人员,我去超市帮助用户取商品:"+name); user.getCommodity(name); System.out.println("商品已成功交给用户,期待用户好评"); } }
10.领导 == 实现签订接口
package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * <p>领导 == 实现签订接口</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class Leader implements Signable{ { System.out.println("各位久等了,我来了!"); } /** * 合同列表 */ private List<String> deals; public Leader() { deals = new LinkedList<>(); } public List<String> getDeals() { return deals; } public void setDeals(List<String> deals) { this.deals = deals; } public void addDeal(String deal){ this.deals.add(deal); } public void addDeals(List<String> deals){ this.deals.addAll(deals); } @Override public void sign() { Collections.sort(this.deals); for (String deal : deals) { System.out.println("领导签订了合同:"+deal); } System.out.println(); } }
11.领导身边的秘书 == 将领导作为被代理的对象,但是会延缓被代理对象的创建时间,最后实现签订接口
package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理; import java.util.LinkedList; import java.util.List; /** * <p>领导身边的秘书 == 将领导作为被代理的对象,但是会延缓被代理对象的创建时间,最后实现签订接口</p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public class Secretary implements Signable{ /** * 合同列表 == 当领导在的时候,这个合同列表会递交给老板,反之,则先放在秘书这里 */ private List<String> deals; private Leader leader; public Secretary() { this.deals = new LinkedList<>(); } /** * 添加一份合同 */ public void addDeal(String deal){ // 如果领导不在的话,秘书先揽收 if(leader == null){ this.deals.add(deal); System.out.println("秘书揽收了合同:"+deal); }else{ // 否则,直接递交给领导 this.leader.addDeal(deal); System.out.println("领导亲自揽收了合同:"+deal); } } @Override public void sign() { if(leader == null){ System.out.println("领导不在,请稍等"); }else{ // 否者的话,领导将秘书揽收的合同拿过来 this.leader.addDeals(this.deals); this.leader.sign(); } } static class LeaderFactory{ public static Leader getLeader(){ return new Leader(); } } public void initLeader(int second){ int n = 0; do{ System.out.println("等待领导出现:"+(++n)+"秒"); }while(--second>0); this.leader = LeaderFactory.getLeader(); } }
12.签订接口
package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理; /** * <p>签订接口 </p> * * @Author zhaoshuangjian 2023-03-23 下午10:39 */ public interface Signable { /** * 定义签订方法 */ void sign(); }