一、何为代理

在我们生活中有这样一种场景,当你要去租房时,现在的社会很难直接找到房东本人,找到了房东租房时的很多细节可能把握不定,那么中介应运而生,这也是下面谈静态代理举的例子,房东只有一个需求,那就是赶快帮我把房子出租出去,客户也只有一个需求,尽快找到我满意的房子

二、代理模式的好处

可以使真实角色的任务更加纯粹,不需要去关注一些细节的业务
公共部分交给了代理,实现了业务的分工
公共业务发生扩展的时候,方便集中管理

三、角色分析

1、抽象角色:一般使用接口或抽象类
2、真实角色:被代理的角色
3、代理角色:代理真实角色,代理真实角色后,我们会做一些附属操作
4、客户角色:访问代理对象的人

QQ截图20200922175826.jpg

四、代码实现

1、抽象角色,这里用接口创建一个租房的方法,真实对象实现这个方法(也就是房东)

package cn.kexing.Proxy;
//租房
public interface Rent {
    void rent();
}

2、真实角色(房东)

package cn.kexing.Proxy;
//房东
public class Host implements Rent{
    //调用抽象角色,出租房子
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}

3、代理角色,代理房东,帮他完成租房功能,另外代理角色还可以执行额外的操作,必须中介带客户看房,签合同,当然 代理不是白代理的,还要抽点手续费

package cn.kexing.Proxy;

//代理对象 代理房东去出租房子,代理对象可做其他工作

/**
 *
 */
public class StaticProxy {
    private Host host;

    public StaticProxy() {
    }

    public StaticProxy(Host host) {
        this.host = host;
    }

    public void rent(){
        host.rent();
        //中介的额外操作
        watch();
        result();
        fee();
    }

    public void watch(){
        System.out.println("中介带客户去看房!");
    }

    public void result(){
        System.out.println("中介带客户签合同!");
    }

    public void fee(){
        System.out.println("中介收取一定的手续费!");
    }
}

4、客户

package cn.kexing.Proxy;

//客户,需要租房子
public class Client {
    public static void main(String[] args) {
        Host host = new Host();
        StaticProxy proxy = new StaticProxy(host);
        proxy.rent();
    }
}

QQ截图20200922182150.jpg

五、再理解静态代理

上面我们说过:公共部分交给了代理,实现了业务的分工 这句话怎么理解,这里有一个场景,当你的上级给你说让你在所有业务代码里增加一条输出日志功能,却又不能更改原有代码,这时就可以用代理实现公共部分功能

1、业务接口

package cn.kexing.Proxy2;
//业务接口
public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}

2、业务实现

package cn.kexing.Proxy2;

/**
 * 业务接口实现类
 */
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 select() {
        System.out.println("查询一个用户");
    }
}

3、代理业务,增加日志

package cn.kexing.Proxy2;

/**
 * 若想要修改业务的方法,但又不能修改原有的代码
 * 那么创建一个代理类来实现
 */
public class UserServiceProxy {
    private UserServiceImpl userService;

    public UserServiceProxy() {
    }

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    public void add(){
        log("add");
        userService.add();
    }

    public void delete(){
        log("delete");
        userService.delete();
    }

    public void update(){
        log("update");
        userService.update();
    }

    public void select(){
        log("select");
        userService.select();
    }

    public void log(String method){
        System.out.println("【debug】 实现了"+method+"方法");
    }
}

4、客户使用

package cn.kexing.Proxy2;

public class Client {
    public static void main(String[] args) {
        UserServiceImpl service = new UserServiceImpl();
        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(service);

        proxy.add();
        proxy.delete();
        proxy.update();
        proxy.select();
    }
}

QQ截图20200922182745.jpg

静态代理

  • 优点:代码结构简单,较容易实现
  • 缺点:无法适配所有代理场景,如果有新的需求,需要修改代理类,不符合软件工程的开闭原则

开闭原则:在编写程序的过程中,软件的所有对象应该是对扩展是开放的,而对修改是关闭的

所以,为了提高类的可扩展性和可维护性,满足开闭原则,Java 提供了动态代理机制。
下篇文章来续动态代理

最后修改:2021 年 11 月 15 日 05 : 20 PM
如果觉得我的文章对你有用,请随意赞赏