对静态代理的理解

假如有一个使用账号密码登录功能,我们写这样一个类:

public class Login {

    public void print() {
        System.out.println("专注于账号密码登录中...");
    }
}

现在想在登录之前和之后分别想打点上报,但是打点上报却不属于登录的操作,我们不想把上报的代码写在登录模块中,于是我们可以这样写

public class LoginProxy {

    private Login login;

    public LoginProxy(Login login) {
        this.login = login;
    }

    public void print() {
        System.out.println("在登录之前上报...");
        login.print();
        System.out.println("在登录之后上报...");
    }
}

使用方法

    public static void main(String[] args) {
        Login login = new Login();
        LoginProxy loginProxy = new LoginProxy(login);
        loginProxy.print();
    }

这样在不丝毫影响登录模块的情况下实现登录前后的上报功能,这其实就是静态代理的实现,Login是被代理对象,LoginProxy是代理对象。
现在增加需求,要实现微信登录,于是增加一个登录类

public class WechatLogin {
    public void print() {
        System.out.println("专注于微信登录中...");
    }
}

代理类

public class WechatLoginProxy {
    private WechatLogin wechatLogin;

    public WechatLoginProxy(WechatLogin wechatLogin) {
        this.wechatLogin = wechatLogin;
    }

    public void print() {
        System.out.println("在登录之前上报...");
        wechatLogin.print();
        System.out.println("在登录之后上报...");
    }
}

这时候又增加需求,要实现QQ登录,于是新建QQLogin、QQLoginProxy......
在使用时太麻烦了,不符合设计原则,来改造一番。
新增接口:

public interface LoginInterface {
    public void print();
}

改造Login:

public class Login implements LoginInterface{

    @Override
    public void print() {
        System.out.println("专注于账号密码登录中...");
    }
}

改造WechatLogin:

public class WechatLogin implements LoginInterface{
    @Override
    public void print() {
        System.out.println("专注于微信登录中...");
    }
}

接着改造LoginProxy:

public class LoginProxy implements LoginInterface{

    private LoginInterface login;

    public LoginProxy(LoginInterface login) {
        this.login = login;
    }

    @Override
    public void print() {
        System.out.println("在登录之前上报...");
        login.print();
        System.out.println("在登录之后上报...");
    }
}

WechatLoginProxy:

public class WechatLoginProxy {
    private WechatLogin wechatLogin;

    public WechatLoginProxy(WechatLogin wechatLogin) {
        this.wechatLogin = wechatLogin;
    }

    public void print() {
        System.out.println("在登录之前上报...");
        wechatLogin.print();
        System.out.println("在登录之后上报...");
    }
}

使用时,想怎么登录直接传对应构造参数就行了

    public static void main(String[] args) {
        //账号密码登录
        LoginProxy loginProxy = new LoginProxy(new Login());
        loginProxy.print();
        //微信登录
        LoginProxy wechatProxy = new LoginProxy(new WechatLogin());
        wechatProxy.print();
    }

打印结果:

在登录之前上报...
专注于账号密码登录中...
在登录之后上报...
在登录之前上报...
专注于微信登录中...
在登录之后上报...

到此,一个标准的静态代理就出现了,之前查了一些静态代理资料,都有一句话:代理对象和被代理对象必须实现同一个接口。个人理解这样说的太绝对,其实不实现也可以实现静态代理的功能和运用原理,实现接口只是为了遵循面向接口编程的设计原则而已,和静态代理没有关系。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,220评论 6 13
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,159评论 1 32
  • 情绪的魔咒,失控-恢复-再次失控,这好像是一个固定的谜题,无解。 当我看到它的时候,它也望着我。 越想掌控就越失控...
    白色的世界_409e阅读 111评论 0 0
  • 作者:张新国 【好员工的基本要求】: 热情胜于才干,态度决定一切 敬业实干发挥最大价值,主动 把工作当人生乐趣,成...
    面包不打烊阅读 531评论 0 2
  • 夏天过去,天黑的就很早。每天下班时,街灯就开始亮了。 我没有见过其他颜色的街灯,大部分是昏黄的...
    南宫柳阅读 604评论 3 2