JAVA的23种设计模式---代理模式(二)
来源:互联网 发布:乐清市网络问效平台 编辑:程序博客网 时间:2024/05/29 02:18
概要:
该文章参考了《设计模式之禅》一书及一些前辈的博客文章
1.该文章阐述了代理模式的基础原理及示例代码;
2.该文章适合初学设计模式的技术人员研习;
3.该文章有许多不足之处,请各位大咖指正,喷子绕道;
4.该文章是《JAVA的23种设计模式—代理模式(一)》的续写,点此跳转到第一部分
正文:
4.代理模式的多接口实现示例代码:
package com.csdn;/** * 代理扩展方法接口 * @author Administrator * */public interface IProxy { //代管店铺收取费用方法 public void pay(); }
package com.csdn;/** * 抽象开店 * @author Administrator * */public interface Shop { //开门营业 public void openTheDoor(); //卖东西 public void sell(); //关门打烊 public void closeTheDoor();}
package com.csdn;/** * 具体的一家店 * @author Administrator * */public class Boss implements Shop { //店主名字 private String name = ""; //构造器限制谁能创建对象,并同时传递店主名 public Boss(Shop shop,String _name)throws Exception { if(shop == null){ throw new Exception("不能创建一个店铺"); }else{ this.name = _name; } } //店门打开方法 @Override public void openTheDoor() { System.out.println(this.name+"的店门打开了.."); } //营业、卖东西方法 @Override public void sell() { System.out.println(this.name+"的店开始出售东西.."); } //关门打烊方法 @Override public void closeTheDoor() { System.out.println(this.name+"的店门关上了.."); }}
package com.csdn;/** * 代理开店服务 * @author Administrator * */public class BossProxy implements Shop,IProxy{ private Shop boss = null; //通过构造函数来传递对谁的店进行代理 public BossProxy(String _boss){ try { boss = new Boss(this, _boss); } catch (Exception e) { // TODO: handle exception } } //代理打开店门方法 @Override public void openTheDoor() { this.boss.openTheDoor(); } //代理营业、卖东西方法 @Override public void sell() { this.boss.sell(); } //代理关门打烊方法 @Override public void closeTheDoor() { this.boss.closeTheDoor(); this.pay(); } @Override public void pay() { System.out.println("代理收取代管费100元.."); }}
package com.csdn;/** * 模拟代理经营店铺 * @author Administrator * */public class Business { public static void main(String[] args) { //“小明”的店铺需要代理服务 Shop proxy = new BossProxy("小明"); //代理打开小明的店门 proxy.openTheDoor(); //代理帮小明卖东西 proxy.sell(); //代理关上小明的店门并向小明收取了管理费 proxy.closeTheDoor(); }}
输出:
小明的店门打开了..小明的店开始出售东西..小明的店门关上了..代理收取代管费100元..
注:
a:该示例与之前相比增加了IProxy接口,增加了pay方法以及其实现,并在closeTheDoor方法中调用了它的实现方法
b:代理的职责并不单一,可以组合其他的真实角色,也可以实现自己的职责,它可以为真实角色预处理消息、过滤消息、消息转发、事后处理消息等功能。
5.通用代理模式模板代码实现:
package com.csdn;/** * 抽象类,可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求 * @author Administrator * */public interface Subject { //定义一个方法 public void request(); }
package com.csdn;/** * 具体类,也叫被委托的角色、被代理的角色,它才是最重要的,是业务逻辑的具体执行者。 * @author Administrator * */ public class RealSubject implements Subject { @Override public void request() { //业务逻辑处理 } }
package com.csdn;/** * 代理类 * @author Administrator * */ public class Proxy implements Subject { //要代理哪个实现类 private Subject subject = null; //默认被代理者 public Proxy() { this.subject = new Proxy(); } //通过构造方法传递代理者 public Proxy(Object...objects) { } //实现接口中的方法 @Overrdie public void request() { this.before(); this.subject.request(); this.after(); } //预处理 private void before() { //do something } //善后处理 private void after() { //do something } }
5.虚拟代理模式代码实现:
package com.csdn;/** * 虚拟代理类 * @author Administrator * */ public class Proxy implements Subject { //要代理哪个实现类 private Subject subject; //实现接口中的方法 @Overrdie public void request() { if(subject == null){ subject = new RealSubject(); } subject.request(); } }
注:在需要的时候才初始化主题对象,可以避免被代理对象较多而引起的初始化缓慢问题
6.动态代理模式代码实现示例代码:
package com.csdn;/** * 抽象开店 * @author Administrator * */public interface Shop { //开门营业 public void openTheDoor(); //卖东西 public void sell(); //关门打烊 public void closeTheDoor();}
package com.csdn;/** * 具体的一家店 * @author Administrator * */public class Boss implements Shop { //店主名字 private String name = ""; //带参构造器 public Boss(String _name) { this.name = _name; } //店门打开方法 @Override public void openTheDoor() { System.out.println(this.name+"的店门打开了.."); } //营业、卖东西方法 @Override public void sell() { System.out.println(this.name+"的店开始出售东西.."); } //关门打烊方法 @Override public void closeTheDoor() { System.out.println(this.name+"的店门关上了.."); }}
package com.csdn;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * 动态代理类 * @author Administrator * */public class DynamicAgent implements InvocationHandler{ //被代理者 Class clazz = null; //被代理的实例 Object obj = null; //要代理谁 public DynamicAgent(Object _obj){ this.obj = _obj; } //调用被代理的方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(this.obj, args); //此处可以加入面向切面的功能,AOP(面向切面的编程)的提现处 //如在门被打开时的提醒功能 if(method.getName().equalsIgnoreCase("openTheDoor")){ System.out.println("(有人正在打开店门!)"); } return result; }}
package com.csdn;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;/** * 模拟动态代理经营店铺 * @author Administrator * */public class Business { public static void main(String[] args) { //初始化“小明”的店铺 Boss boss = new Boss("小明"); //“小明”的店铺需要动态代理服务 InvocationHandler handler = new DynamicAgent(boss); //获得类的类加载器 ClassLoader cl = boss.getClass().getClassLoader(); //动态产生一个代理者 Shop proxy = (Shop)Proxy.newProxyInstance(cl,new Class[]{Shop.class}, handler); //代理打开小明的店门 proxy.openTheDoor(); //代理帮小明卖东西 proxy.sell(); //代理关上小明的店门 proxy.closeTheDoor(); }}
输出:
小明的店门打开了..(有人正在打开店门!)小明的店开始出售东西..小明的店门关上了..
注:
a:invoke方法是InvocationHandler定义必须实现的,他完成对真实方法的调用,所有被代理的方法都由InvocationHandler接管实际的处理任务
b:对于日志、事物、权限等都可以在系统设计阶段不用去考虑,而在设计后通过AOP(面向切面的编程)的方式切过去
7.通用动态代理模式模板代码:
package com.csdn;/** * 抽象类 * @author Administrator * */public interface Subject { //业务操作 public void doSomething(String str); }
package com.csdn;/** * 具体类 * @author Administrator * */ public class RealSubject implements Subject { //业务操作 @Override public void doSomething(String str){ System.out.println("do something----->" + str); }; }
package com.csdn;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * 动态代理的Handler类 * @author Administrator * */public class MyInvocationHandler implements InvocationHandler { //被代理的对象 private Object target = null; //通过构造函数传递一个对象 public MyInvocationHandler(Object _obj){ this.target = _obj; } //代理方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行被代理的方法 return method.invoke(this.target, args); }}
package com.csdn;import java.lang.reflect.InvocationHandler;/** * 动态代理类 * @author Administrator * * @param <T> */public class DynamicProxy<T> { public static <T> T newProxyInstance(ClassLoader loader,Class<?>[]interfaces,InvocationHandler h){ //寻找JoinPoint连接点,AOP框架使用元数据定义 if(true){ //执行一个前置通知 (new BeforeAdvice()).exec(); } //执行目标并返回结果 return (T)Proxy.newProxyInstance(loader, interfaces, h); }}
package com.csdn;/** * 通知接口 * @author Administrator * */public interface IAdvice { //通知的方法 public void exec();}
package com.csdn;/** * 通知实现类 * @author Administrator * */public class BeforeAdvice implements IAdvice { @Override public void exec() { System.out.println("前置通知"); }}
package com.csdn;import java.lang.reflect.InvocationHandler;/** * 动态代理场景类 * @author Administrator * */public class Client { public static void main(String[] args) { //定义一个主题 Subject subject = new RealSubject(); //定义一个Handler InvocationHandler handler = new MyInvocationHandler(subject); //定义主题的代理 Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler); //代理的行为 proxy.doSomething("Finish"); }}
输出:
前置通知do something----->Finish
注:
a:在动态代理类中newProxyInstance方法有三个参数,其中c.getInterfaces查找该类的所有接口,然后实现接口的所有方法,由new MyInvocationHandler(subject)这个对象接管
扩展:
package com.csdn;import java.lang.reflect.InvocationHandler;/** * 具体业务的动态代理 * @author Administrator * */public class SubjectDynamicProxy extends DynamicProxy{ public static <T> T newProxyInstance(Subject subject){ //获得类加载器 ClassLoader loader = subject.getClass().getClassLoader(); //获得接口数据 Class<?>[] classes = subject.getClass().getInterfaces(); //获得Handler InvocationHandler handler = new MyInvocationHandler(subject); return newProxyInstance(loader, classes, handler); }}
package com.csdn;/** * 动态代理场景类 * @author Administrator * */public class Client { public static void main(String[] args) { //定义一个主题 Subject subject = new RealSubject(); //定义主题的代理 Subject proxy = SubjectDynamicProxy.newProxyInstance(subject); //代理的行为 proxy.doSomething("Finish"); }}
注:
a:动态代理的主要意图就是横切面编程,在不改变我们已有的代码结构的情况下增强或控制对象的行为
- JAVA的23种设计模式---代理模式(二)
- java设计模式--代理模式(二)
- JAVA的23种设计模式---代理模式(一)
- Java设计模式详谈(二):代理
- JAVA的23种设计模式---备忘录模式(二)
- JAVA设计模式--代理模式(动态)(二)
- Java技术常用设计模式(二)--- 代理模式
- 设计模式(二十九)------23种设计模式(21):代理模式
- 设计模式(二)代理模式
- 善用设计模式(二)代理模式
- Java设计模式---代理模式(二)---动态代理
- 设计模式之禅——代理模式(二)代理模式&AOP编程&JDK对代理模式的支持
- java的设计模式之代理模式
- 我的Java设计模式-代理模式
- JAVA开发的23种设计模式之 — 装饰器模式 && 代理器模式
- Java设计模式之----动态代理(二)
- Java的代理模式(二)jDK的动态代理
- JAVA设计模式之【代理模式】二(jdk动态代理)
- 日志的生成
- 谈谈对「工控安全」和「产品经理」的理解
- AOP学习笔记(一)—— 代理
- 线程间通信的方式
- H5游戏研发发展
- JAVA的23种设计模式---代理模式(二)
- 时间类
- 栈(顺序)
- 回溯算法
- xgboost模型部署及注意相关事宜。
- 经纬度计算Sql语句
- 集合类
- prepend、append
- 车牌字符识别(matlab)