Java设计模式-Proxy代理模式
問題分析:
什么是代理模式呢?其實我們在生活中并不少見。對于程序員來說最常接觸的莫過于代理上網了,連接大力服務器地址,就可以訪問網絡。
還有每天吃飯趕進度是常事,叫公司的同事幫忙帶飯也是一種代理;如果你辭職老板不給你發工資,那么你還得請個律師幫你打官司,這也是一種代理。總之生活中無處不在。
代理的定義:
為其他對象提供一種代理以控制對這個對象的訪問。簡單點就是在不直接操作訪問對象的的情況下,找一個代理訪問該對象,就是自己不想搞,這個其他人幫你搞。
基本UML圖:
具體問題UML類圖:
抽象主題類Subject.java
package com.hust.staticProxy1;public abstract class Subject {public abstract void visit();//普通業務方法 } 實現抽象主題的真正主題類RealSubject.java
package com.hust.staticProxy1;public class RealSubject extends Subject {public void visit() {System.out.println("Real Subject!");}} 代理類ProxySubject.java
package com.hust.staticProxy1; //代理類 public class ProxySubject extends Subject {private RealSubject mRealSubject;//把被代理對象作為成員變量public ProxySubject(RealSubject mRealSubject){this.mRealSubject=mRealSubject;}public void visit() {mRealSubject.visit();//調用被代理對象的邏輯方法}} Client.java
package com.hust.staticProxy1;public class Client {/*** @param args*/public static void main(String[] args) {//實例化一個被代理對象RealSubject mRealSubject=new RealSubject();//用被代理對象構造一個代理對象ProxySubject mProxySubject=new ProxySubject(mRealSubject);//調用代理對象的相關方法mProxySubject.visit();}} 代理模式的簡單實現:
設定一個故事情節,小明上班遇到一個被老板拖欠工資甚至克扣工資的情況,這種情況下小明還是通過法律來解決問題,一旦小明選擇走法律途徑解決該糾紛,那么不可避免的需要請個律師作為自己的訴訟代理人,我們將訴訟流程抽象在一個接口中。
訴訟接口類
package com.hust.staticProxy2;public interface LawSuit {//提交申請void submit();//進行舉證void burden();//開始辯護void defend();//訴訟完成void finish(); } 具體訴訟人,就是被代理對象小明,就是他想做的事
package com.hust.staticProxy2;public class XiaoMing implements LawSuit {//被代理類,實現訴訟接口public void submit() {// 老板欠小明工資,小明只好申請仲裁System.out.println("老板欠小明工資,小明只好申請仲裁");}public void burden() {//小明證據充足,不怕告不贏System.out.println("這是合同書和過去一年的銀行卡工資流水");}public void defend() {// 鐵證如山,辯護也沒什么好說的System.out.println("證據確鑿!不需要早說些什么了!");}public void finish() {// 結果也肯定的System.out.println("訴訟成功,判決老板即日起七天內結算工資");}} 代理律師類:就是代理對象,小明讓這個代理類完成訴訟流程
package com.hust.staticProxy2; //律師代理類 public class Lawyer implements LawSuit{private LawSuit mLawSuit;public Lawyer(LawSuit mLawSuit){this.mLawSuit=mLawSuit;}public void submit() {// 調用被代理類的方法mLawSuit.submit();}public void burden() {// 調用被代理類的方法mLawSuit.burden();}public void defend() {// 調用被代理類的方法mLawSuit.defend();}public void finish() {// 調用被代理類的方法mLawSuit.finish();}} 客戶端類
package com.hust.staticProxy2;public class ClientTest {/*** @param args*/public static void main(String[] args) {//構造被代理對象小明LawSuit xiaoming=new XiaoMing();//小明委托代理對象律師Lawyer mLawyer=new Lawyer(xiaoming);//代理對象律師幫助小明提出訴訟申請mLawyer.submit();//代理對象律師進行舉證mLawyer.burden();//代理對象律師代替小明進行辯護mLawyer.defend();//代理對象律師完成訴訟mLawyer.finish();}} 輸出:
老板欠小明工資,小明只好申請仲裁 這是合同書和過去一年的銀行卡工資流水 證據確鑿!不需要早說些什么了! 訴訟成功,判決老板即日起七天內結算工資
代理模式的意義:
代理模式到底好處在哪里呢??
那先要說一下代理模式中的三種角色了。
抽象角色:聲明真實對象和代理對象的共同接口。
代理角色: 代理對象角色內部含有對真實對象的引用, 從而可以操作 真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象,可以在執行真實對象操作時,附加其他的操作,相當于對真實對象進行封裝。
真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。
代理模式的一個好處就是對外部提供統一的接口方法,而代理類在接口中實現對真實類的附加操作行為,從而可以在不影響外部調用情況下,進行系統擴展。也就是說,我要修改真實角色的操作的時候,盡量不要修改他,而是在外部在“包”一層進行附加行為,即代理類。例如:接口A有一個接口方法operator(),真實角色:RealA實現接口A,則必須實現接口方法operator()。客戶端Client調用接口A的接方法operator()。現在新需求來了,需要修改RealA中的operator()的操作行為。怎么辦呢?如果修改RealA就會影響原有系統的穩定性,還要重新測試。這是就需要代理類實現附加行為操作。創建代理ProxyA實現接口A,并將真實對象RealA注入進來。ProxyA實現接口方法operator(),另外還可以增加附加行為,然后調用真實對象的operator()。從而達到了“對修改關閉,對擴展開放”,保證了系統的穩定性。我們看客戶端Client調用仍是接口A的接口方法operator(),只不過實例變為了ProxyA類了而已。也就是說代理模式實現了ocp原則。
什么時候使用代理模式
當我們需要使用的對象很復雜或者需要很長時間去構造,這時就可以使用代理模式(Proxy)。例如:如果構建一個對象很耗費時間和計算機資源,代理模式(Proxy)允許我們控制這種情況,直到我們需要使用實際的對象。一個代理(Proxy)通常包含和將要使用的對象同樣的方法,一旦開始使用這個對象,這些方法將通過代理(Proxy)傳遞給實際的對象。 一些可以使用代理模式(Proxy)的情況:
1,一個對象,比如一幅很大的圖像,需要載入的時間很長。
? ?2,一個需要很長時間才可以完成的計算結果,并且需要在它計算過程中顯示中間結果
3,一個存在于遠程計算機上的對象,需要通過網絡載入這個遠程對象則需要很長時間,特別是在網絡傳輸高峰期。
4,一個對象只有有限的訪問權限,代理模式(Proxy)可以驗證用戶的權限
代理模式(Proxy)也可以被用來區別一個對象實例的請求和實際的訪問,例如:在程序初始化過程中可能建立多個對象,但并不都是馬上使用,代理模式(Proxy)可以載入需要的真正的對象。這是一個需要載入和顯示一幅很大的圖像的程序,當程序啟動時,就必須確定要顯示的圖像,但是實際的圖像只能在完全載入后才可以顯示!這時我們就可以使用代理模式(Proxy)。
總結
以上是生活随笔為你收集整理的Java设计模式-Proxy代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【错误记录】-eclipse 导入类 提
- 下一篇: 【错误记录】eclipse,androi