代理模式(Proxy)--静态代理
1,代理模式的概念
代理模式:为其他对象提供一种代理,以控制对这个对象的访问(代理对对象起到中介的作用,可去掉功能服务或者添加额外的服务)
2,代理模式的分类
(1)远程代理:类似于客户机服务器模式
为不同地址空间的对象提供局域网代表对象
举例说明:通过远程代理监控各个店铺
(2)虚拟代理:根据需要将资源消耗很大的对象进行延迟,真正需要的时候进行创建
举例说明:当对一个网页进行记载的时候,会先使用一张默认的图片代替要加载的图片,将文字等其他信息和默认的图片一起加载出来,在慢慢加载指定的图片。
(3)保护代理:控制对一个对象的访问权限
举例说明:在浏览某个网站的时候,未登录状态,只能浏览网站,只有在登陆后才可以发帖。
(4)智能引用代理:提供对目标对象的额外的服务
举例说明:火车票代购处,不仅提供了销售火车票的功能,还提供了电话预约的功能。
3,智能引用代理---静态代理:
模拟场景:车行驶的路上,代理添加新功能:记录行驶的时间
(1)在不使用代理的情况下:
S1:编写行驶接口类Moveable
package com.songyan.proxy; public interface Moveable {
void move();
}
S2:编写小汽车类实现Moveable接口
并实现Moveable中定义的行驶方法(move())
在行驶方法中获取运行开始时,运行结束时的时间,做差获取运行的时间,由于程序运行太快,使用Thread的sleep()休眠1秒
package com.songyan.proxy; import java.util.Random; public class Car implements Moveable {
public void move() {
long startTime=System.currentTimeMillis();
System.out.println("汽车行驶的开始时间:"+startTime); //实现开车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("汽车行驶中");
} catch (InterruptedException e) {
e.printStackTrace();
} long endTime=System.currentTimeMillis();
System.out.println("骑车行驶的终止时间:"+endTime);
System.out.println("汽车行驶时间共计:"+(endTime-startTime)+"毫秒~"); } }
S3:编写测试类,是小汽车行驶
package com.songyan.proxy; public class Client {
public static void main(String[] args) {
Car car= new Car();
car.move();
} }
S4:运行结果
(2)代理实现记录汽车行驶的时间---继承
S1:新建Car2继承Car
S2:重写move方法
S3:将car中的记录时间的部分抽取出来,只留下汽车行驶的部分
package com.songyan.proxy;
/**
*
* @author sy
*通过继承Car2实现对Car的代理
*/
public class Car2 extends Car{
@Override
public void move() {
long startTime=System.currentTimeMillis();
System.out.println("开始行驶~~~~"); super.move(); long endTime=System.currentTimeMillis();
System.out.println("行驶结束~~~~~~~~~~");
System.out.println("汽车行驶时间:"+(endTime-startTime)+"毫秒~");
} }
package com.songyan.proxy; import java.util.Random; public class Car implements Moveable {
public void move() {
System.out.println("移动~~~~~~~~~~~~");
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
S4:编写测试类测试
package com.songyan.proxy; public class Client {
public static void main(String[] args) {
/*Car car=new Car();
car.move();*/
Moveable car2=new Car2();
car2.move();
}
}
输出结果
(3)代理实现记录汽车行驶的时间---聚合
S1:编写Car3实现Moveable接口
S2:声明一个Car类型的变量
S3:并通过构造函数进行初始化
S4:重写move方法,调用car的move()在写逻辑代码。
package com.songyan.proxy;
/**
*
* @author sy
* 通过聚合的方式实现代理
*/
public class Car3 implements Moveable{
private Car car;
/**
* 聚合:一个类当中
*/
public void move() {
//计时开始
long startTime=System.currentTimeMillis();
System.out.println("开始行驶~~~~"); //调用car的move方法
car.move(); //计时结束
long endTime=System.currentTimeMillis();
System.out.println("行驶结束~~~~~~~~~~");
System.out.println("汽车行驶时间:"+(endTime-startTime)+"毫秒~");
} /**
* 通过构造函数将car传进来
* @param car
*/
Car3(Car car)
{
super();
this.car=car;
} }
思考:以上是两种实现代理的方式,哪一种更好呢?
功能拓展:上面的代理中知识拓展了记录行驶时间的功能,如果需要实现功能叠加,两种方式有该如何实现?
(1)继承的方式
先记录日志在记录行驶时间:需要编写Car3继承Car.
先记录行驶时间,在记录日志:又需要编写Car4继承Car
不难看出继承的方式代码的可重用性不高
(2)聚合的方式(可以很好的解决上述问题)
S1:编写实现记录时间的代理类
package com.songyan.proxy;
/**
* 记录时间的代理类
* @author sy
*
*/
public class CarTimeProxy implements Moveable
{
private Moveable m;
public void move() {
System.out.println("时间记录开始~~");
m.move();
System.out.println("时间记录结束~~"); }
public CarTimeProxy(Moveable m)
{
this.m=m;
}
}
S2:编写记录日志的代理类
package com.songyan.proxy;
/**
* 就日志的代理类
* @author sy
*
*/
public class CarLogProxy implements Moveable{
private Moveable m;
public void move() {
System.out.println("log开始~~~~");
m.move();
System.out.println("log结束~~~~~~");
}
public CarLogProxy(Moveable m)
{
this.m=m;
} }
S3:编写测试类(1)先记录日志在记录时间
package com.songyan.proxy;
/**
* 代理组合测试类
* @author sy
* 要求代理:先记录日志,在记录时间
*/
public class CarTest {
public static void main(String[] args) {
Moveable m=new Car();
Moveable time=new CarTimeProxy(m);
Moveable log=new CarLogProxy(time);
log.move();
}
}
运行结果:
S4:编写测试类2(先记录时间在记录日志)
不行需要重新写代理类
只需要在调用的时候调整顺序即可
package com.songyan.proxy;
/**
* 代理组合测试类
* @author sy
* 要求代理:先记录时间,在记录日志
*/
public class CarTest {
public static void main(String[] args) {
Moveable m=new Car();
Moveable log=new CarLogProxy(m);
Moveable time=new CarTimeProxy(log);
time.move();
}
}
输出结果:
由上可以看出:聚合要比继承更好用。
思考:我们上面实现的都是对Car的代理,如果我们下需要对火车,自行车实现相同的代理,我们又该如何实现呢?
这里就需要用到动态代理技术了:具体请点击此处查看另一篇博客。
代理模式(Proxy)--静态代理的更多相关文章
- Spring框架_代理模式(静态代理,动态代理,cglib代理)
共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下: ...
- java 代理模式(静态代理、动态代理、Cglib代理) 转载
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- Java三种代理模式:静态代理、动态代理和cglib代理
一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...
- java代理模式之静态代理
作为一个初级开发者,可能不会接触到代理模式,但是在很多框架的使用中都不知不觉使用了代理模式,比如servlet的过滤器链,spring的AOP,以及spring mvc的拦截器等.所以了解代理模式对于 ...
- 代理模式之静态代理,JDK动态代理和cglib动态代理
代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...
- java 编程基础 Class对象 反射:代理模式和静态代理
生活中的代理 类(对象)代理模式 代理模式是面向对象编程中比较常见的设计模式. 1. 用户只关心接口功能,而不在乎谁提供了功能.上图中接口是 Subject 2. 接口真正实现者是上图的 RealSu ...
- 【Java】代理模式,静态代理和动态代理(基于JDK或CGLib)
当我们需要在一个方法之前或之后添加一段逻辑时,自然会想到使用代理类.代理类帮我们代理了实际类的调用,然后可以在实际调用之前和之后添加一些逻辑,从而不浸入实际类. 拓展:由于代理类能在实际类调用之前和之 ...
- 结构型模式 -- 代理模式(静态代理&动态代理)
静态代理: 真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用.代理角色去执行方法,对于某些"真正"需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他 ...
- Java的三种代理模式:静态代理/JDK动态代理/Cglib动态代理
1.静态代理:需要定义接口或者父类,目标对象与代理对象均实现同一接口或继承同一父类. 2.JDK动态代理:需要目标对象实现一个接口,通过动态反射的机制,生成代理对象,实现同一个接口 3.Cglib动态 ...
- 《Proxy系列专题》:代理模式(静态、JDK、CGLib)
<Proxy系列专题>:代理模式(静态.JDK.CGLib)使用 现象:在如今互联网时代,项目的复杂度不断的提升,有些场景下需要一定的设计优化来支撑业务的扩展,如为了不改动原始类,但需要对 ...
随机推荐
- Android开发实例总结
写一个修改密码的界面 1画界面总结: 需要弄清楚什么地方用相对布局,什么地方使用线性布局 希望这过后自己花时间去弄清楚他们内嵌的的所有组件以及组件的属性包括用法. 2逻辑总结: 逻辑描述总是那么几步的 ...
- Android记事本05
昨天: intentFilter 今天: URL和logcat 问题: ADK更新后无法打开布局文件.xml
- GDI+绘制可滚动的窗口
在winform中绘制图形,可以使用gdi+来完成. 当绘制的图形大于目前窗口大小时,就需要滚动条来帮忙显示. 设置属性:Form.AutoScrollMinSize为要显示内容的大小. privat ...
- Angular & RxJS & Typescript
Angular & RxJS & Typescript https://www.wmnetwork.cc/d/?mid=75627 杭州经开区国际创博中心 https://www.w ...
- weex 开发 (已放弃了)
关于weex 开发 本菜已放弃使用了,当初选择使用weex 是为了同时支持h5 和 android / ios 三端:想法很不错,深入之后 突然发现,开发起来并没有很轻松,因为weex 中有些方法, ...
- 【bzoj2793】[Poi2012]Vouchers 暴力
题目描述 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个.正整数中有m个数被标成了幸运数,问有哪些人取到了幸运数. 输入 第一行一个 ...
- 洛谷 P3573 [POI2014]RAJ-Rally 解题报告
P3573 [POI2014]RAJ-Rally 题意: 给定一个\(N\)个点\(M\)条边的有向无环图,每条边长度都是\(1\). 请找到一个点,使得删掉这个点后剩余的图中的最长路径最短. 输入输 ...
- linux fg bg ctrl + z jobs & 等命令
fg.bg.jobs.&.ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的一.& 最经常被用到这个用在一个命令的最后,可以把这个命令放到 ...
- B-number(hdu 3652)
题意:找出1~n范围内含有13并且能被13整除的数字的个数 /* 数位DP dp[i][j][0]表示i位数模13为j当前没有包含13并且最高位不为1的方案数: dp[i][j][0]表示i位数模13 ...
- bananahill(NOIP模拟赛Round 8)
题目描述 香蕉川由座香蕉山组成,第i座山有它的高度.小Z准备从左到右爬这里的恰好座香蕉山,但他不希望山的高度起伏太大,太过颠簸,会让本就体育不好的他过于劳累.所以他定义了爬山的劳累度是所有爬的相邻的两 ...