设计模式(二):代理模式之静态代理(Static Proxy)

静态代理在使用时,需要定义接口或者父类,目标对象与代理对象一起实现相同的接口或者是继承相同父类

代理对象通过调用代理对象的方法来调用目标对象的方法;可以在不修改目标对象的前提下,对目标对象的功能进行扩展。

静态代理

静态代理原理

在代理类里,定义一个目标对象(被代理对象)的属性;在调用代理对象时,将目标对象做为代理对象构造方法里的参数传入,代理对象重写目标对象的方法,在重写的方法里包装被代理对象的方法。

这样就可以在代理对象的方法里调用目标对象的方法,可以在代理方法里做一些扩展。在调用时,只需通过代理对象调用自身的方法即可。

构成元素:

  • 接口 或 父类
  • 接口的实现类 或 继承父类的子类
  • 实现同样接口的代理类 或 同样继承父类的代理类

静态代理缺点

一个明显的缺点要为每一个接口类生成一个代理类,也就是一个接口类必然要对应一个代理类。这样必然会生成很多的代理类,并且这些代理类的代码有很多重复的部分。

解决这一问题,最好的办法就是通过一个代理类 完成全部的代理功能,此时就要使用动态代理。

实现接口方式

结构图

静态代理结构图

接口:

1
2
3
4
5
6
/**
* 接口
*/
public interface UserDao {
void save();
}

目标对象类(接口实现类):

1
2
3
4
5
6
7
8
9
10
/**
* 目标对象
*/
public class UserDaoImpl implements UserDao {

@Override
public void save() {
System.out.println("正在保存");
}
}

代理对象类(与目标对象实现同一个接口):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 代理实现
*/
public class UserDaoProxyImpl implements UserDao {

private UserDaoImpl userDaoImpl;

public UserDaoProxyImpl(UserDaoImpl userDaoImpl) {
this.userDaoImpl = userDaoImpl;
}

/**
* 重写被代理的目标对象的方法
*/
@Override
public void save() {
System.out.println("代理增强: 开始保存。。。。");
userDaoImpl.save();
System.out.println("代理增强: 保存结束。。。。");
}

}

客户端调用代理类:

1
2
3
4
5
6
7
8
9
public class Client {

public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
//被代理的目标对象作为代理对象的构造参数传入
userDao = new UserDaoProxyImpl(userDao);
userDao.save();
}
}

执行结果:

1
2
3
代理增强:  开始保存。。。。
正在保存
代理增强: 保存结束。。。。

继承父类方式

父类

1
2
3
4
5
6
public class BaseMapper {

public void save() {
System.out.println("正在保存。。。。");
}
}

目标对象类(被代理对象类继承父类)

1
2
3
4
5
6
7
8
9
10
/**
* 目标对象
*/
public class BatchMapper extends BaseMapper {

public void batchSave() {
System.out.println("批量保存。。。。");
}

}

代理对象类(继承相同的父类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 代理对象
*/
public class MapperProxy extends BaseMapper {

private BatchMapper batchMapper;

public MapperProxy(BatchMapper batchMapper) {
this.batchMapper = batchMapper;
}

public void save() {
System.out.println("代理增强: 开始保存。。。。");
batchMapper.save();
System.out.println("代理增强: 保存结束。。。。");
}

public void batchSave() {
System.out.println("代理增强: 批量保存。。。。");
batchMapper.batchSave();
System.out.println("代理增强: 保存结束。。。。");
}
}

客户端调用

1
2
3
4
5
6
7
8
9
public class Client {
public static void main(String[] args) {
BatchMapper batchMapper = new BatchMapper();
MapperProxy mapperProxy = new MapperProxy(batchMapper);
mapperProxy.save();
System.out.println("------------------------------------");
mapperProxy.batchSave();
}
}
  1. 执行结果
    1
    2
    3
    4
    5
    6
    7
    代理增强:  开始保存。。。。
    正在保存。。。。
    代理增强: 保存结束。。。。
    ------------------------------------
    代理增强: 批量保存。。。。
    批量保存。。。。
    代理增强: 保存结束。。。。

设计模式(二):代理模式之静态代理(Static Proxy)

http://blog.gxitsky.com/2018/03/14/DesignPatterns-02-Proxy-Static/

作者

光星

发布于

2018-03-14

更新于

2022-06-17

许可协议

评论