1、前言設計模式
代理是代替服務器去接受請求者的請求的中間人。咱們也據說過代理服務器,它的做用的幫助客戶端去請求客戶端想要的資源,爲何要經過代理呢,那是由於客戶端直接訪問服務器會被拒絕(防火牆屏蔽),而代理服務器則能夠直接訪問服務器,客戶端經過代理服務器,將請求的結果交給代理服務器,代理服務器對這些內容進行重組換成本身的標識(IP),而且將請求的結果返回給用戶,這樣作的弊端就是訪問的速度大打折扣,可是總比沒有強。緩存
咱們的代理模式就是這麼幹的,若是代理可以處理的東西(好比用戶已經訪問過的,服務器返回過來的沒有過時的緩存),不用請求服務器了,直接返回給用戶,而只有代理服務器不能處理的東西纔會再次交給服務器去處理,固然這只是代理的一種策略,爲了可以加快訪問速度,這樣代理服務器就代替咱們去訪問服務器了。服務器
2、代碼實例ide
本人去處理全部事情是很是麻煩的,特別是初始化的時候都很是的耗時,所以使用代理,不到必須本身出馬的時候一直按兵不動,讓代理去完成這些工做,這就是代理模式。函數
Printable接口:代理的同源性:this
package designMode.proxy; public interface Printable { public abstract void setPrinterName(String name); public abstract String getPirnterName(); public abstract void print(String word); }
Printer類:本人(至關於真正的服務器)spa
package designMode.proxy; public class Printer implements Printable{ String name; public Printer(String name) { this.name = name; heavyWork(); System.out.println("生成打印機實例成功..."); } private void heavyWork(){ System.out.println("本人:"+name); try { Thread.sleep(5000); }catch (InterruptedException e){ e.printStackTrace(); } } @Override public void setPrinterName(String name) { this.name=name; } @Override public String getPirnterName() { return name; } @Override public void print(String word){ System.out.println("打印機"+name+"正在打印..."); System.out.println(word); System.out.println("打印完成!"); } }
ProxyPrinter代理類:.net
package designMode.proxy; public class ProxyPrinter implements Printable { String name; Printer printer = null; //代理能作的事情本身去作 @Override public void setPrinterName(String name) { if(printer!=null){ printer.setPrinterName(name); } this.name = name; } //代理能作的事情本身去作 @Override public String getPirnterName() { return name; } //代理作不了的事情交給真正能作的(打印機)去作 @Override public void print(String word) { check(); printer.print(word); } private synchronized void check(){ if(printer==null){ printer = new Printer(name); } } }
Main類:設計
package designMode.proxy; public class Main { public static void main(String[] args) { Printable proxy = new ProxyPrinter(); proxy.setPrinterName("江疏影"); System.out.println("此時代理的名字爲:"+proxy.getPirnterName()); System.out.println("==遇到了代理處理不了的工做,通知服務器=="); proxy.print("hello,world!"); System.out.println("======================"); proxy.setPrinterName("倪妮"); System.out.println("此時代理的名字爲:"+proxy.getPirnterName()); proxy.print("hello,my country!"); } }
啓動服務器很耗時(這裏用睡眠5秒錶示),那麼使用代理服務器能夠輕鬆處理一些事務(設置名字,獲取名字),知道代理服務器無能爲力的時候(print打印內容),代理服務器就會通知服務器去處理,從本例來看,由於使用了委託機制,將printer對象組合進來,可是printer是不知道代理的,它只是被啓動了而已,這說明了什麼?本人(printer)能夠不作任何改動,就能夠增長不少的代理去啓動本人,這樣很是有利於擴展,其實這裏也使用了懶加載機制,看到只有到不得不使用的時候才生成被代理的實例,那麼可不能夠直接在代理模式中使用懶加載機制呢,答案是不利於擴展性,沒有這種分而治之的思想好,這樣的好處是很大的,在main中能夠隨意切換,同時可以定義相同的必須的接口。這種透明性是很是有益的,在不少模式中都有體現。代理
3、總結
代理模式是一種常見的模式,只在必須的時候生成實例,也分爲不少種類,主要按照使用去分類的,好比本例的虛擬代理,以及其它的遠程代理,訪問控制代理等,咱們主要理解代理的實現本質,代理的意義,以及手機用途。代理模式與裝飾器模式比較相似,都是持有了同類或父類的引用(委託機制),而且在函數之中調用了同類的方法來加工與同類同名的本類的響應方法,可是也有區別,代理模式是爲了減輕被代理人的工做,在不得已的時候再去打擾被代理人,而裝飾器模式是爲了產生新的功能,裝飾原有的屬性。