【design pattern】代理模式
2024-08-27 11:36:34
1. 设计模式分类
设计模式分为三大类:
创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式;
结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式;
行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式;
2. 代理模式
代理是基本的设计模式之一,提供额外的或不同的操作,代理通常充当中间人的角色,如果用“租房子”来打比方,代理则是中介,首先要明确的是:不论是静态代理还是动
态代理,被代理对象都要有一个实现的接口
2.1 静态代理
静态代理的本质是:用户调用目标对象的方法是通过代理对象调用的,其中代理对象中实现并组合了目标对象实现的接口,因此可以在代理对象中调用目标对象的方法。
1. 目标对象实现的接口
package cn.huawei.ProxyPattern;
public interface TargetInterface {
void method1();
}
2. 目标对象
package cn.huawei.ProxyPattern;
public class Target implements TargetInterface {
@Override
public void method1() {
System.out.println("STEP3: 睡觉");
}
}
3. 静态代理对象
package cn.huawei.ProxyPattern;
public class StaticProxy implements TargetInterface{
private TargetInterface proxied;
@Override
public void method1() {
System.out.println("STEP1: 洗脸");
System.out.println("STEP2: 刷牙");
proxied.method1();
}
public StaticProxy(TargetInterface proxied) {
this.proxied = proxied;
}
}
4.Main函数
package cn.huawei.ProxyPattern;
public class Main {
public static void fun1(TargetInterface iface){
iface.method1();
}
public static void main(String[] args) {
System.out.println("代理之前:");
fun1(new Target());
System.out.println("代理之后:");
fun1(new StaticProxy(new Target()));
}
}
5.运行结果
代理之前:
STEP3: 睡觉
==========
代理之后:
STEP1: 洗脸
STEP2: 刷牙
STEP3: 睡觉
2.2 动态代理
动态代理的本质和静态代理是不同的,不同点如下:
1. 静态代理需要用户写代理对象StaticTarget,而动态代理是JVM在内存中生成代理对象
2. 动态代理的代理对象是通过反射机制调用目标对象的方法,而静态代理是通过在代理对象中组合目标对象实现的接口来实现调用目标对象方法的功能
3. 动态代理的代理对象和目标对象实现了相同的接口
【参考资料】:Java中的反射机制
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class Main {
public static void main(String[] args) {
FBB fbb = new FBB(); /*
* 参数讲解:
* 1. 被代理对象的类加载器
* 2. 被代理对象实现的接口的字节码数组 // 也可以是 new Class[] { MX.class }
* 3. InvocationHandler
* 4. 返回值要和接口的字节码数组中的接口类型一致
*/
MX proxy = (MX) Proxy.newProxyInstance(MX.class.getClassLoader(), fbb.getClass().getInterfaces(), new InvocationHandler() {
/*
* InvocationHandler可以理解为一组规范,代理对象proxy调用目标对象几次方法,该方法就执行几次
* invoke:执行代理对象的方法
* proxy:代理对象
* method:目标对象方法的字节码Method对象,来自FBB中的方法
* args:被代理对象中方法的参数,来自FBB方法中的参数
* @return 返回代理方法的结果
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("sing".equals(method.getName())) { //针对唱歌项目,如果加钱可以唱歌曲2
System.out.println("加钱 歌曲2"); //增强方法
Object invoke = method.invoke(fbb, args);
return invoke; //返回sing()结果
} else {
return method.invoke(fbb, args);
}
}
});
System.out.println(proxy.sing());
System.out.println(proxy.dance());
}
} interface MX { //明星接口,默认明星都会唱歌和跳舞
String sing();
String dance();
} class FBB implements MX { //目标对象(被代理对象)
@Override
public String sing() { //FBB默认只会唱歌曲1
return "fbb sing 歌曲1";
} @Override
public String dance() {//FBB默认只会跳舞蹈1
return "fbb dance 舞蹈1 ";
}
}
执行结果
=======
加钱 歌曲2
fbb sing 歌曲1
fbb dance 舞蹈1
最新文章
- Cesium简介以及离线部署运行
- OpenLDAP安装
- Sql--列操作
- OpenStack 企业私有云的若干需求(9): 云管理平台 CMP
- (原创)mybaits学习三,springMVC和mybatis融合
- UITextField使用的相关方法
- 推荐《C Primer Plus(第五版)中文版》【worldsing笔记】
- PHP 5.6.6 上运行 ecshop 2.7.3 不兼容问题整合
- Java中的那些名词术语(不断更新中)
- Activity的Launch mode详解,A B C D的singleTask模式
- Win10系列:C#应用控件基础19
- ES6中的proxy
- 鱼缸的启示:Scale-out和Scale-up架构
- pip install psutil出错-You are using pip version 10.0.1, however version 18.0 is available.
- WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(核心)
- JDK中线程组ThreadGroup
- P4385 [COCI2009]Dvapravca
- zookeeper 节点启动时的更新机制
- google中guava类库:AsyncEventBus
- docker-compose示例与命令介绍
热门文章
- P4575 [CQOI2013]图的逆变换
- Python测试工具——nose
- python包管理工具他们之间的关系
- RHEL5.6环境下Oracle10g单主机安装步骤记录
- Linux命令(009) -- tar
- 208 Implement Trie (Prefix Tree) 字典树(前缀树)
- 解决ASP.NET Core通过docker-compose up启动应用无法配置https的解决办法
- VMware Workstation安装CentOS 7和开发环境
- python 使用 Pyscript 调试 报错
- dede自定义表单放首页出错的解决办法