设计模式 - 代理模式深入理解

1.定义

代理可以理解为做什么事情在不同的环境之下事先准备工作和工作结束之后需要完成工作都是不一样的。

代理在java中可以分为静态和动态两种方式

2.静态代理

在java世界中代理说白了有两个类都继承一个接口,都要实现接口的方法,但是其中一个类属于另一个类的成员,另外一个类进行接口方法时也需要调用成员继承接口的方法

我们拿学汽车驾驶来举例,最简单的动作就是驾驶,学员也驾驶,教练也要驾驶,但是教练驾驶不是自已,而是教学员,学员在驾驶时他们需要帮他做准备工作,学员驾驶完了需要完成的工作,以下代码是具体的使用静态代理实现:

public interface IDriverService {

void drive();

}

@Data

public class Driver implements IDriverService{

private String name;

@Override

public void drive() {

System.out.println(this.name+"汽车发动,驾驶汽车");

}

}

public class Coach implements IDriverService {

private Driver student;

public void setStudent(Driver student) {

this.student = student;

}

@Override

public void drive() {

before();

student.drive();

end();

}

private void before(){

System.out.println("检查四周环境,告知学员可以开车");

}

private void end(){

System.out.println("到达目的地,停车");

}

}

测试方法:

@Test

public void staticProxy(){

Driver student1=new Driver();

student1.setName("王小人");

Coach coach=new Coach();

coach.setStudent(student1);

coach.drive();

Driver student2=new Driver();

student2.setName("周XXX");

coach.setStudent(student2);

coach.drive();

}

运行日志:

检查四周环境,告知学员可以开车

王小人汽车发动,驾驶汽车

到达目的地,停车

检查四周环境,告知学员可以开车

周XXX汽车发动,驾驶汽车

到达目的地,停车

3.动态代理

从静态代理的例子类中我们可以看出他只适用一类型的学员,如果教练说我除了教人,我还可以教动物园的猴子狮子来学车,用上的方法可能不能实现,但是java中有一种代理机制来实现,下现是准备内容,增加了两个类,一个代理类和动物类

public class Animal implements IDriverService {

private String name;

private String zoomname;

public Animal(String name,String zoomname){

this.name=name;

this.zoomname=zoomname;

}

@Override

public void drive() {

System.out.println("大家小心了,"+this.zoomname+"的"+this.name+"开车了");

}

}

public class CoachDynamicProxy implements InvocationHandler {

private Object target;

public Object setStudent(Object target) {

this.target=target;

Class<?> clazz=target.getClass();

Object o=Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);

System.out.println(o.getClass().getName());

return o;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

before();

Object obj=method.invoke(this.target,args);

end();

return obj;

}

private void before(){

System.out.println("检查四周环境,告知学员可以开车");

}

private void end(){

System.out.println("到达目的地,停车");

}

}

测试方法:

@Test

public void DynamicProxy() throws Exception{

Driver student1=new Driver();

student1.setName("王小人");

CoachDynamicProxy coach=new CoachDynamicProxy();

IDriverService o=(IDriverService)coach.setStudent(student1);

o.drive();

Driver student2=new Driver();

student2.setName("周XXX");

o=(IDriverService)coach.setStudent(student2);

o.drive();

o=(IDriverService)coach.setStudent(new Animal("猴子A","苏州动物园"));

o.drive();

o=(IDriverService)coach.setStudent(new Animal("老虎A","上海动物园"));

o.drive();

}

运行日志:

com.sun.proxy.$Proxy9

检查四周环境,告知学员可以开车

王小人汽车发动,驾驶汽车

到达目的地,停车

com.sun.proxy.$Proxy9

检查四周环境,告知学员可以开车

周XXX汽车发动,驾驶汽车

到达目的地,停车

com.sun.proxy.$Proxy9

检查四周环境,告知学员可以开车

大家小心了,苏州动物园的猴子A开车了

到达目的地,停车

com.sun.proxy.$Proxy9

检查四周环境,告知学员可以开车

大家小心了,上海动物园的老虎A开车了

到达目的地,停车

4.扩展

但是以上动态代理只是继承了IDriverSerivce的方式来,但是我们也可以修改,比如让Animal继承其他接口,这样可以增加灵活性

public interface IJumpService {

void jump();

void eat();

}

public class Animal implements IJumpService {

private String name;

private String zoomname;

public Animal(String name,String zoomname){

this.name=name;

this.zoomname=zoomname;

}

@Override

public void jump() {

System.out.println("大家小心了,"+this.zoomname+"的"+this.name+"要做jump动作了");

}

@Override

public void eat() {

System.out.println("大家小心了,"+this.zoomname+"的"+this.name+"要做开始进食了");

}

}

测试方法:

@Test

public void DynamicProxy() throws Exception{

Driver student1=new Driver();

student1.setName("王小人");

CoachDynamicProxy coach=new CoachDynamicProxy();

IDriverService o=(IDriverService)coach.setStudent(student1);

o.drive();

Driver student2=new Driver();

student2.setName("周XXX");

o=(IDriverService)coach.setStudent(student2);

o.drive();

IJumpService o1=(IJumpService)coach.setStudent(new Animal("猴子A","苏州动物园"));

o1.jump();

o1.eat();

o1=(IJumpService)coach.setStudent(new Animal("老虎A","上海动物园"));

o1.jump();

o1.eat();

}

测试日志:

com.sun.proxy.$Proxy9

检查四周环境,告知学员可以开车

大家小心了,苏州动物园的猴子A要做jump动作了

到达目的地,停车

检查四周环境,告知学员可以开车

大家小心了,苏州动物园的猴子A要做开始进食了

到达目的地,停车

com.sun.proxy.$Proxy9

检查四周环境,告知学员可以开车

大家小心了,上海动物园的老虎A要做jump动作了

到达目的地,停车

检查四周环境,告知学员可以开车

大家小心了,上海动物园的老虎A要做开始进食了

到达目的地,停车

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值