静态代理是一种结构型设计模式,它在编译时就已经确定了代理类和真实类的关系,即代理类是在编译期间就确定的,代理类和真实类的关系在程序运行前就已经确定。静态代理通常通过手动编写代理类来实现,在代理类中调用真实对象的方法,并可以在调用前后进行一些额外的操作。
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色之后,我们一般会做一些附属操作
- 客户:访问代理对象的人
静态代理模式的好处:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公共业务交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理对象,代码量会翻倍,开发效率会变低(可以使用动态代理解决)
举例:
现在去租房子一般都是去找中介,因为中介手中有大量的房源,中介就是一个代理角色,实际出租房子的房东就是一个真实角色。
代码步骤
1.接口
//租房接口
public interface Rent {
public void rent();
}
2.真实角色
//房东
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子");
}
}
3.代理角色
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Proxy implements Rent{
private Host host;
/**
* 代理租房
*/
@Override
public void rent() {
host.rent();
seeHouse();
fare();
hetong();
}
/**
* 看房子
*/
public void seeHouse()
{
System.out.println("中介带你看房子");
}
/**
* 收中介费
*/
public void fare()
{
System.out.println("收中介费");
}
/**
* 签合同
*/
public void hetong()
{
System.out.println("签合同");
}
}
4.客户端访问代理角色
public class Client {
public static void main(String[] args) {
// Host host = new Host();
// host.rent();
//房东要出租房子
Host host = new Host();
//代理:中介帮房东租房子,但是代理角色会有一些附属操作
Proxy proxy = new Proxy(host);
//租房者不用寻找房东,只需要找中介
proxy.rent();
}
}
代理模式的好处就是可以在不改变原有代码的前提下添加功能。
举例:在原有的增删改查的基础上添加一个日志功能,但是不改变原有代码,这时,我们就可以使用代理模式来完成。
原有功能:
public interface UserService {
void add();
void delete();
void update();
void query();
}
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个用户");
}
@Override
public void delete() {
System.out.println("修改了一个用户");
}
@Override
public void update() {
System.out.println("删除了一个用户");
}
@Override
public void query() {
System.out.println("查询了一个用户");
}
}
使用代理模式无侵入的添加一个Log功能
//在不改变原有代码的基础上添加日志功能
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserServiceProxy implements UserService{
private UserServiceImpl userService;
@Override
public void add() {
log("add");
userService.add();
}
@Override
public void delete() {
log("delete");
userService.delete();
}
@Override
public void update() {
log("update");
userService.update();
}
@Override
public void query() {
log("query");
userService.query();
}
//日志方法
public void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}