假如有一個使用賬號密碼登錄功能,我們寫這樣一個類:
public class Login {
public void print() {
System.out.println("專注于賬號密碼登錄中...");
}
}
現(xiàn)在想在登錄之前和之后分別想打點上報,但是打點上報卻不屬于登錄的操作,我們不想把上報的代碼寫在登錄模塊中,于是我們可以這樣寫
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();
}
這樣在不絲毫影響登錄模塊的情況下實現(xiàn)登錄前后的上報功能,這其實就是靜態(tài)代理的實現(xiàn),Login是被代理對象,LoginProxy是代理對象。
現(xiàn)在增加需求,要實現(xiàn)微信登錄,于是增加一個登錄類
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("在登錄之后上報...");
}
}
這時候又增加需求,要實現(xiàn)QQ登錄,于是新建QQLogin、QQLoginProxy......
在使用時太麻煩了,不符合設(shè)計原則,來改造一番。
新增接口:
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("在登錄之后上報...");
}
}
使用時,想怎么登錄直接傳對應(yīng)構(gòu)造參數(shù)就行了
public static void main(String[] args) {
//賬號密碼登錄
LoginProxy loginProxy = new LoginProxy(new Login());
loginProxy.print();
//微信登錄
LoginProxy wechatProxy = new LoginProxy(new WechatLogin());
wechatProxy.print();
}
打印結(jié)果:
在登錄之前上報...
專注于賬號密碼登錄中...
在登錄之后上報...
在登錄之前上報...
專注于微信登錄中...
在登錄之后上報...
到此,一個標(biāo)準(zhǔn)的靜態(tài)代理就出現(xiàn)了,之前查了一些靜態(tài)代理資料,都有一句話:代理對象和被代理對象必須實現(xiàn)同一個接口。個人理解這樣說的太絕對,其實不實現(xiàn)也可以實現(xiàn)靜態(tài)代理的功能和運用原理,實現(xiàn)接口只是為了遵循面向接口編程的設(shè)計原則而已,和靜態(tài)代理沒有關(guān)系。