《Head First 设计模式》:代理模式
生活随笔
收集整理的這篇文章主要介紹了
《Head First 设计模式》:代理模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正文
一、定義
代理模式為另一個對象提供一個替身或占位符以控制對這個對象的訪問。
要點:
- 代理模式為一個對象創建了代理對象,讓代理對象控制對該對象的訪問。被代理的對象可以是遠程的對象、創建開銷大的對象或者需要安全控制的對象。
- 代理類型:遠程代理、虛擬代理、保護代理等。
- 遠程代理:控制訪問遠程對象。
- 虛擬代理:控制訪問創建開銷大的資源。
- 保護代理:基于權限控制對資源的訪問。
二、實現步驟
1、創建主題接口
/*** 主題接口*/ public interface Subject {/*** 請求主題執行某種動作*/void request(); }2、創建真實主題(被代理類),并繼承主題接口
真實主題是真正做事的主題對象。
/*** 真正做事的真實主題(被代理類)*/ public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject do something...");} }3、創建主題代理(代理類),并繼承主題接口
主題代理持有真正做事的真實主題,并控制對真實主題的訪問。
/*** 主題代理(代理類)*/ public class SubjectProxy implements Subject {/*** 持有真實主題*/RealSubject realSubject;@Overridepublic void request() {System.out.println("SubjectProxy receives and controls request, and entrust request to RealSubject...");// 代理并控制對真實主題的訪問,比如權限控制、訪問資源控制等if (realSubject == null) {realSubject = new RealSubject();}// ...// 將請求委托給真實主題realSubject.request();} }4、使用主題代理訪問主題
public class Test {public static void main(String[] args) {// 代理SubjectProxy proxy = new SubjectProxy();// 通過代理請求主題proxy.request();} }三、舉個栗子
1、背景
我們打算建立一個應用程序,用來展示你最喜歡的 CD 封面。CD 封面的圖我們可以從一些網站的在線服務中獲取。
唯一的問題是,限于連接帶寬和網絡負載,下載可能需要一些時間,所以在等待圖像加載時,應該顯示一些東西。我們也不希望在等待圖像時,整個應用程序被掛起。一旦圖像被加載完成,剛才顯示的東西應該消失,然后圖像顯示出來。
2、實現
使用虛擬代理管理圖片的加載、顯示。
(1)創建圖片接口
/*** 圖片接口*/ public interface Image {/*** 繪圖*/void paint(); }(2)創建真正做事的圖片類
/*** 真正進行圖片操作的真實圖片類*/ public class RealImage implements Image {String url;String description;public RealImage(String url, String description) {this.url = url;this.description = description;load(url);}@Overridepublic void paint() {System.out.println("Image is painted");}/*** 模擬加載圖片*/private void load(String url) {try {System.out.println("Loading image from: " + url);for (int i = 0; i < 10; i++) {System.out.print("===");Thread.sleep(200);}System.out.println("===>100%");System.out.println("Loading image is finished!");} catch (InterruptedException e) {e.printStackTrace();}} }(3)創建圖片代理
/*** 圖片代理*/ public class ImageProxy implements Image {RealImage realImage;String imageUrl;/*** 是否已加載圖片*/boolean hasLoaded = false;public ImageProxy(String imageUrl) {this.imageUrl = imageUrl;}@Overridepublic void paint() {if (realImage != null) {// 有圖片,則直接繪圖realImage.paint();} else {// 沒有圖片,則先顯示加載中的信息,再去加載并繪制圖片System.out.println("Loading CD cover, please wait...");loadAndPaint();}}/*** 加載并繪制圖片*/private void loadAndPaint() {if (hasLoaded) {return;}hasLoaded = true;// 加載圖片是一個比較耗時的操作,為了避免程序阻塞,采用異步處理new Thread(new Runnable() {@Overridepublic void run() {realImage = new RealImage(imageUrl, "CD Cover");// 加載完后,再進行繪圖realImage.paint();}}).start();} }(4)使用圖片代理進行繪圖
public class Test {public static void main(String[] args) throws InterruptedException {// 圖片代理ImageProxy imageProxy = new ImageProxy("https://www.jingqueyimu.com/images/xxx.jpg");// 使用圖片代理進行繪圖System.out.println("首次繪圖:");imageProxy.paint();Thread.sleep(3000);System.out.println("再次繪圖:");imageProxy.paint();} }四、Java 動態代理
1、創建主題接口
/*** 主題接口*/ public interface Subject {/*** 請求主題執行某種動作*/void request(); }2、創建真實主題(被代理類),并繼承主題接口
/*** 真正做事的真實主題*/ public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject do something...");} }3、使用 Java 動態代理,代理真實主題
public class Test {public static void main(String[] args) {// 真實主題(被代理類)Subject realSubject = new RealSubject();// 調用處理器InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 代理實例的方法被調用時,最終會執行該方法System.out.println("InvocationHandler start to invoke...");// do something...// 調用真實主題(被代理類)的方法method.invoke(realSubject, args);// do something...return null;}};// 使用 Proxy 創建代理Subject subjectProxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);// 通過代理發起請求subjectProxy.request();} }總結
以上是生活随笔為你收集整理的《Head First 设计模式》:代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu 下安装 StarUML
- 下一篇: html静态测试网页,Html静态网页测