設計模式:代理(Proxy)模式

設計模式:代理(Proxy)模式

1、前言設計模式

   代理模式或許咱們都據說過,至少知道代理(Proxy)這個東西的,不然看這篇博客也沒任何意義的。什麼叫作代理,代理是代替服務器去接受請求者的請求的中間人。咱們也據說過代理服務器這個東西,它的做用就是幫助客戶端去請求客戶端想要的資源,爲何要經過這個代理呢,那是由於客戶端直接去訪問服務器會被拒絕(防火牆屏蔽),而代理服務器則能夠直接訪問服務器的,所以客戶端經過代理服務器,將請求的內容交給代理服務器,代理服務器對這些內容進行重組換成本身的標識(IP),而且將請求的結果返回給用戶,這樣作的弊端就是訪問的速度大打折扣,可是有總比沒有強。那麼咱們的代理模式也是這個樣子的,若是代理可以處理的東西(好比用戶已經訪問過的,服務器返回過來的沒有過時的緩存),不用請求服務器了,直接返回給用戶,而只有代理服務器不能處理的東西纔會再次交給服務器(本人)去處理,固然這只是代理的一種策略就是爲了可以加快訪問速度,這樣代理服務器就代替咱們去訪問服務器了。緩存

   代理代理,究竟是代替誰去處理,你們可能有疑慮,由於用戶有請求,代理服務器代替用戶去請求和處理,這樣說是代替用戶的;但是代理有了本身的權限(緩存)以後看起來又像是代替服務器去處理同樣,只有本身作不到的時候纔會去麻煩這個被代理人(服務器),而且返回用戶想要的數據,那麼究竟是代替誰去處理呢?!服務器

   讓咱們想一下平常生活,咱們去找一我的辦一件事,可是這我的可能身份很高,咱們不能直接去見面,可是這樣的人身邊都是有代理(助理)的,所以咱們找到了這個助理,告訴本身的問題,若是這我的說,這麼簡單的問題呀,還用麻煩咱們的老闆?!因而直接告訴了我答案和解決辦法。那麼我(客戶)就美滋滋的走了,若是助理以爲問題很大,本身一我的不能解決,就會去向老闆(服務器)請示,最終獲得結果而且告訴我(客戶端),這樣來講代理一直是爲老闆(服務器)代理的,而客戶有事情的話去找助理,助理無論本身處理仍是向老闆請示都是一種應該作的事情,不能說代理是爲咱們(客戶)代理的,應該說代理是替老闆代理的,所以代理代理,是替服務器代理,而不是替客戶端代理,固然相信你們也據說過反向代理,這個東西就是本身組建了服務器集羣,而後使用反向代理機制加快別人訪問本身服務器的速度,這樣本身的集羣就是被代理(老闆)的了。我想這應該是一個誤區,大多數人可能都搞不清的地方。函數

2、代碼this

  本人去處理全部事情是很是麻煩的,特別是初始化的時候都很是的耗時,所以使用代理,不到必須本身出馬的時候一直按兵不動,讓代理去完成這些工做,這就是代理模式。spa

 Printable接口代理的同源性:設計

1 package zyr.dp.proxy;
2 
3 public interface Printable {
4 
5     public abstract void setPrinterName(String name);
6     public abstract String getPrinterName();
7     public abstract void print(String word);
8     
9 }

  Printer類:本人(至關於真正的服務器)代理

 1 package zyr.dp.proxy;
 2 
 3 public class Printer implements Printable {
 4 
 5     String name;
 6     public Printer(String name) {
 7         this.name=name;
 8         heavyWork();
 9         System.out.println("生成打印機實例成功...");
10     }
11 
12     //作一點重活
13     private void heavyWork() { 14         System.out.println("本人:"+name); 15         try { 16             Thread.sleep(5000); 17         } catch (InterruptedException e) { 18  e.printStackTrace(); 19  } 20  } 21 
22     public void setPrinterName(String name) {
23         this.name=name;
24     }
25     public String getPrinterName() {
26         return name;
27     }
28 
29     public void print(String word) {
30         System.out.println("打印機"+name+"正在打印...");
31         System.out.println(word);
32         System.out.println("打印完成!");
33     }
34 
35 }

  ProxyPrinter代理類:code

 1 package zyr.dp.proxy;
 2 
 3 public class ProxyPrinter implements Printable {
 4 
 5     String name;
 6     Printer printer=null;
 7     
 8     //代理能作的事情本身去作
 9     public synchronized void setPrinterName(String name) {
10         if(printer!=null){
11             printer.setPrinterName(name);
12         }
13         this.name=name;
14     }
15 
16     //代理能作的事情本身去作
17     public String getPrinterName() {
18         return name;
19     }
20 
21     //代理作不了的事情交給真正能作的(打印機)去作
22     public  void print(String word) {
23         check();
24         printer.print(word);
25     }
26 
27     private synchronized void check() {
28         if(printer==null){
29             printer=new Printer(name);
30         }
31     }
32 
33 }

 Main類:對象

 1 package zyr.dp.proxy;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6 
 7         Printable proxy=new ProxyPrinter();
 8         proxy.setPrinterName("zyr");
 9         System.out.println("此時代理的名字爲:"+proxy.getPrinterName());
10         System.out.println("==遇到了代理處理不了的工做,通知服務器==");
11         proxy.print("hello,world!");
12         System.out.println("====================");
13         proxy.setPrinterName("lsx");
14         System.out.println("此時代理的名字爲:"+proxy.getPrinterName());
15         proxy.print("hello,my country!");
16     }
17 
18 }

 運行結果:

  能夠看到服務器的啓動實在是太耗時了(睡眠5秒鐘來表示),那麼使用代理服務器能夠輕鬆地處理一些事務(設置名字,得到名字),直到代理服務器無能爲力的時候(print打印內容),代理服務器就會通知服務器(本人)讓服務器去處理,從本例能夠看到,代理是清楚的直到被代理的對象的,由於使用了委託機制,將Printer對象組合進來),可是Printer是不知道代理的,它只是被啓動了而已,這說明了什麼?!本人(Printer)能夠不作任何改動,就能夠增長不少的代理去啓動本人,這樣很是利於可擴展性,其實這裏也使用了懶加載模式,能夠看到只有到不得不使用的時候才生成被代理的實例,那麼可不能夠直接在代理模式之中使用懶加載機制呢,答案是不利於可擴展性,沒有這種分而治之的思想好,另外就是啓動Printer類自己就是一種開銷。同時咱們看到了代理和被代理人都實現了一樣的接口,這樣的好處是很大的,在Main中能夠隨意切換,同時可以定義相同的必須的接口。這種透明性是很是有益的,在不少模式之中都有着體現。

3、總結

  代理模式是一種經常使用的模式,只在必要的時候生成實例,也分爲不少種類,主要是按照使用去分類的,好比本例的虛擬代理,以及其餘的遠程代理,訪問控制代理等,咱們主要要理解代理的實現本質,代理的意義,以及實際的用處。代理模式與裝飾器模式比較相似,都是持有了同類或父類的引用(委託機制),而且在函數之中調用了同類的方法來加工與同類同名的本類的相應方法,可是也有區別,代理模式是爲了減輕被代理人的工做,在不得已的時候再去打擾被代理人,而裝飾器模式是爲了產生新的功能,裝飾原有的屬性。

  程序代碼

相關文章
相關標籤/搜索