代理模式

代理模式是什么岳服?

代理模式是一種結(jié)構(gòu)性設(shè)計(jì)模式,意思是在使用者和目標(biāo)中出現(xiàn)一個(gè)中間層鸯乃,中間層才能控制目標(biāo),而使用者只能和中間層交互跋涣,類似:租客 - 中介 - 房東。中間層在雙方之中增加自己的業(yè)務(wù)鸟悴。

代理模式能解決什么問題陈辱?

直接訪問對(duì)象時(shí)帶來的問題。
比如你在訪問中途需要增加中間層業(yè)務(wù)的時(shí)候细诸。
比如你要不同業(yè)務(wù)中增加統(tǒng)一的一層業(yè)務(wù)沛贪。

代理模式分類

靜態(tài)代理

靜態(tài)代理是什么?
給目標(biāo)對(duì)象提供一個(gè)代理對(duì)象,并由代理對(duì)象控制對(duì)目標(biāo)對(duì)象的引用利赋。
例子1:電腦桌面的快捷方式水评。電腦對(duì)某個(gè)程序提供一個(gè)快捷方式(代理對(duì)象)涮母,快捷方式連接客戶端和程序匆浙,客戶端通過操作快捷方式就可以操作那個(gè)程序。
例子2:你要租房缤沦,然后通過第三方的租房平臺(tái)租到了一套房塘偎。這里第三方租房平臺(tái)就是代理對(duì)象疗涉,第三方租房平臺(tái)連接著你和房東,房東就是目標(biāo)對(duì)象吟秩。
例子3:你去銀行存錢咱扣,你只需要找尋柜臺(tái)工作人員幫你做存錢的業(yè)務(wù),而不需要自己操作電腦存錢涵防。這里柜臺(tái)工作人員就是代理對(duì)象闹伪,而存錢的業(yè)務(wù)就是目標(biāo)對(duì)象。
代理對(duì)象:起到了中介作用壮池,連接客戶端和目標(biāo)對(duì)象偏瓤。

解決問題

隱藏了真正的功能細(xì)節(jié),一切通過代理得知結(jié)果火窒。防止直接訪問目標(biāo)對(duì)象帶來的不必要的復(fù)雜度硼补。

模式原理

靜態(tài)代理.png

實(shí)例講解
實(shí)例概況

  • 背景:小成希望買一臺(tái)最新的頂配Mac電腦
  • 沖突:國(guó)內(nèi)還沒上,只有美國(guó)才有
  • 解決方案:尋找代購(gòu)進(jìn)行購(gòu)買

代購(gòu)(代理對(duì)象) 代替 我(真實(shí)對(duì)象) 去買Mac(間接訪問的操作)

實(shí)現(xiàn)步驟
1熏矿、創(chuàng)建抽象對(duì)象接口(ISBusiness):聲明你(真實(shí)對(duì)象)需要讓代購(gòu)(代理對(duì)象)幫忙做的事(買Mac)

interface ISBusiness {

    /**
     * 買mac
     */
    fun buyMac(name:String)

    /**
     * 買水果
     */
    fun buyFruit(name:String,fruit: String)
}

2已骇、創(chuàng)建真實(shí)對(duì)象類(SBusiness),即真正做事的人

class SBusiness : ISBusiness {
    override fun buyFruit(name: String,fruit: String) {
        println("幫${name}買了一斤$fruit")
    }

    override fun buyMac(name: String) {
        println("幫${name}去買了一臺(tái)mac")
    }
}

3、創(chuàng)建代理對(duì)象類(Proxy)票编,即”代購(gòu)“褪储,并通過代理類創(chuàng)建真實(shí)對(duì)象實(shí)例并訪問其方法

class SProxy :ISBusiness{
    override fun buyFruit(name: String,fruit: String) {
        //真實(shí)做事情的對(duì)象
        val business = SBusiness()
        business.buyFruit(name,fruit)
        //代理對(duì)象做額外的操作
        fruitWrap()
    }

    override fun buyMac(name:String) {
        //真實(shí)做事情的對(duì)象
        val business = SBusiness()
        business.buyMac(name)
        //代理對(duì)象做額外的操作
        giftWrap()
    }

    private fun giftWrap() {
        println("商品包裝")
    }

    private fun fruitWrap() {
        println("水果打包")
    }
}

4、客戶端調(diào)用

    @Test
    fun test() {
        val sproxy = SProxy()
        sproxy.buyMac("小明")
        sproxy.buyFruit("小明","香蕉")
    }

結(jié)果輸出

幫小明去買了一臺(tái)mac
商品包裝
幫小明買了一斤香蕉
水果打包

優(yōu)缺點(diǎn)
優(yōu)點(diǎn)

  • 由代理類對(duì)目標(biāo)對(duì)象進(jìn)行訪問控制和擴(kuò)展慧域,降低了系統(tǒng)的耦合度鲤竹。
  • 代理對(duì)象作為客戶端和目標(biāo)對(duì)象的中間層,起到了保護(hù)目標(biāo)對(duì)象的作用昔榴。

缺點(diǎn)

  • 重復(fù)性:靜態(tài)代理的原則是一個(gè)代理類對(duì)應(yīng)一個(gè)基礎(chǔ)接口辛藻,如果基礎(chǔ)接口過多,那么就需要?jiǎng)?chuàng)建多個(gè)代理類來分別管理不同的目標(biāo)對(duì)象互订。重復(fù)的模板也會(huì)越來越多吱肌。
  • 脆弱性:基礎(chǔ)接口一旦修改,所以相關(guān)的目標(biāo)對(duì)象都要進(jìn)行改動(dòng)仰禽,代理類也無法避免氮墨。
  • 實(shí)現(xiàn)代理模式需要額外的工作(有些代理模式的實(shí)現(xiàn)非常復(fù)雜)纺蛆,從而增加了系統(tǒng)實(shí)現(xiàn)的復(fù)雜度。如果多個(gè)不同的基礎(chǔ)接口需要提供一個(gè)相關(guān)的功能规揪,比如日志桥氏,那么所有實(shí)現(xiàn)的代理類都需要進(jìn)行修改。

動(dòng)態(tài)代理

動(dòng)態(tài)代理的意義
假設(shè)項(xiàng)目中要給多個(gè)實(shí)現(xiàn)了一個(gè)相同的業(yè)務(wù)接口增加一個(gè)統(tǒng)一的功能猛铅,比如日志字支,這個(gè)時(shí)候你使用靜態(tài)代理其實(shí)可以實(shí)現(xiàn)。但是如果項(xiàng)目中要給多個(gè)不同的業(yè)務(wù)接口實(shí)現(xiàn)類增加一個(gè)日志功能呢奕坟?你一個(gè)靜態(tài)代理是不夠的祥款,靜態(tài)代理的原則是一個(gè)代理類對(duì)應(yīng)著一個(gè)基礎(chǔ)接口。那如果是多個(gè)基礎(chǔ)接口月杉,就需要?jiǎng)?chuàng)建多個(gè)靜態(tài)代理類刃跛。這就暴露了靜態(tài)代理的缺點(diǎn):
一、重復(fù)性苛萎,在程序規(guī)模開始增加時(shí)桨昙,需要代理的方法越來越多,你所需要的代理類就越來越多腌歉,重復(fù)的模板就越來越多了蛙酪。
二、脆弱性翘盖,基礎(chǔ)接口一旦修改桂塞,除了所有的業(yè)務(wù)類需要修改,代理類也必須改動(dòng)馍驯。

怎么解決這個(gè)問題阁危?
動(dòng)態(tài)代理(Dymanic Proxy API)是JDK1.3中引入的特性,核心API是java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler接口汰瘫。它利用反射機(jī)制在運(yùn)行時(shí)生成代理類的字節(jié)碼狂打,為Java平臺(tái)在帶來了運(yùn)行時(shí)動(dòng)態(tài)擴(kuò)展對(duì)象行為的能力。

動(dòng)態(tài)代理和靜態(tài)代理的區(qū)別混弥?
靜態(tài)代理:在編譯期間就已經(jīng)確定目標(biāo)對(duì)象是哪一個(gè)趴乡,運(yùn)行前目標(biāo)對(duì)象已經(jīng)存在。
動(dòng)態(tài)代理:程序運(yùn)行時(shí)才確定目標(biāo)對(duì)象是哪一個(gè)蝗拿,運(yùn)行過程中動(dòng)態(tài)生成代理類晾捏。

為什么要用動(dòng)態(tài)代理?
因?yàn)橐粋€(gè)靜態(tài)代理類只能服務(wù)一種類型的對(duì)象哀托,在目標(biāo)對(duì)象較多的情況下粟瞬,會(huì)出現(xiàn)代理類較多,代碼量較大的問題萤捆。
而使用動(dòng)態(tài)代理動(dòng)態(tài)生成代理者對(duì)象能避免這種情況的發(fā)生裙品。

動(dòng)態(tài)代理核心組件
Proxy:代理類,內(nèi)部通過反射機(jī)制動(dòng)態(tài)生成代理類對(duì)象俗或。
InvocationHandler:這是一個(gè)接口市怎,代理實(shí)例的調(diào)用處理程序。

原理時(shí)序圖

動(dòng)態(tài)代理.png

實(shí)現(xiàn)步驟
1辛慰、聲明目標(biāo)對(duì)象的抽象接口

interface Ibusiness {
    fun business()
}

2区匠、生成目標(biāo)對(duì)象(實(shí)現(xiàn)目標(biāo)對(duì)象的抽象接口,這里由于每個(gè)代理類都繼承了 Proxy 類帅腌,又 Java 的單繼承特性驰弄,所以,只能針對(duì)接口創(chuàng)建代理類速客,不能針對(duì)類創(chuàng)建代理類)

class OneBusiness : Ibusiness {
    override fun business() {
        println("我外出買了mac")
    }
}

3戚篙、聲明調(diào)用處理類

public class BusinessHandler implements InvocationHandler {

    private Ibusiness ibusiness;

    public BusinessHandler(Ibusiness bui) {
        ibusiness = bui;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("外出前先收拾垃圾");
        try {
            method.invoke(ibusiness, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("外出回來了");
        return null;
    }
}

4、生成相關(guān)對(duì)象并通過代理類對(duì)象調(diào)用目標(biāo)對(duì)象方法

//生成相關(guān)對(duì)象
OneBusiness business = new OneBusiness();
BusinessHandler handler = new BusinessHandler(business);
Ibusiness ibusiness = (Ibusiness) Proxy.newProxyInstance(business.getClass().getClassLoader(), business.getClass().getInterfaces(), handler);
//調(diào)用方法
ibusiness.business();

5溺职、最終會(huì)在調(diào)用處理類中執(zhí)行目標(biāo)對(duì)象的對(duì)應(yīng)方法岔擂,并且你可以在此期間增加新的業(yè)務(wù)

public class BusinessHandler implements InvocationHandler {

    private Ibusiness ibusiness;

    public BusinessHandler(Ibusiness bui) {
        ibusiness = bui;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //可以執(zhí)行一些擴(kuò)展的業(yè)務(wù),比如日志浪耘,埋點(diǎn)等
        System.out.println("外出前先收拾垃圾");
        try {
            //調(diào)用目標(biāo)對(duì)象方法
            method.invoke(ibusiness, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("外出回來了");
        return null;
    }
}

結(jié)果輸出

外出前先收拾垃圾 ->這是擴(kuò)展的業(yè)務(wù)
我外出買了mac -> 這是目標(biāo)對(duì)象執(zhí)行的函數(shù)
外出回來了 -> 這也是擴(kuò)展的業(yè)務(wù)

靜態(tài)代理和動(dòng)態(tài)代理
共同點(diǎn):兩種代理模式都是在不改動(dòng)目標(biāo)對(duì)象的前提下乱灵,對(duì)目標(biāo)對(duì)象進(jìn)行訪問和擴(kuò)展,符合開閉原則七冲。
不同點(diǎn):靜態(tài)代理模式在程序規(guī)模稍大時(shí)痛倚,重復(fù)性和脆弱性的缺點(diǎn)出現(xiàn),動(dòng)態(tài)代理實(shí)現(xiàn)了一個(gè)代理處理N個(gè)基礎(chǔ)接口并擴(kuò)展澜躺,本質(zhì)上是代理類和基礎(chǔ)接口的解耦蝉稳,一定程度上規(guī)避了靜態(tài)代理的缺點(diǎn)。從原理上講苗踪,靜態(tài)代理的代理類在編譯期生成颠区,而動(dòng)態(tài)代理的代理類在運(yùn)行時(shí)生成。代理類在coding階段并不存在通铲,代理關(guān)系直到運(yùn)行時(shí)才確定毕莱。
使用動(dòng)態(tài)代理的好處?
它可以無侵入的增加其他的方法颅夺,不會(huì)對(duì)基礎(chǔ)業(yè)務(wù)有任何影響朋截。

應(yīng)用場(chǎng)景
Android的跨進(jìn)程通信中使用了動(dòng)態(tài)代理
比如activity的啟動(dòng)過程中,有動(dòng)態(tài)代理的使用
Retrofit中create()也使用了動(dòng)態(tài)代理吧黄,用途是封裝接口轉(zhuǎn)化成一個(gè)OkHttpCall對(duì)象傳給OkHttp
AOP面向切面編程領(lǐng)域

動(dòng)態(tài)代理源碼分析
這是java.lang.reflect.Proxy的源碼部服,試著理解代理類Class如何生成,這是jdk1.3之后引入的特性

package java.lang.reflect;
* @author      Peter Jones
 * @see         InvocationHandler
 * @since       1.3
 */
public class Proxy implements java.io.Serializable {

公共方法


2.png

分析newProxyInstance方法

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
throws IllegalArgumentException
參數(shù)一:ClassLoader 類加載器拗慨,這里可以傳代理類要實(shí)現(xiàn)的接口的ClassLoader
為什么要指定ClassLoader對(duì)象廓八?
ClassLoader相當(dāng)于類的命名空間奉芦,類的唯一性由它本身和加載它的ClassLoader確定。一個(gè)Class文件如果由兩個(gè)ClassLoader加載剧蹂,結(jié)果是兩個(gè)獨(dú)立的類声功。
參數(shù)二:Class<?>[] 要實(shí)現(xiàn)的接口,因?yàn)橐粋€(gè)類可以實(shí)現(xiàn)多個(gè)接口宠叼,所以這里是個(gè)數(shù)組
參數(shù)三:InvocationHandler 這個(gè)就是接口代理類執(zhí)行方法的回調(diào)
 {
        ...
        //查找或生成指定的代理類
        Class<?> cl = getProxyClass0(loader, intfs);
        ...
        //實(shí)例化代理類先巴,H就是我們實(shí)現(xiàn)的BusinessHandler
        return cons.newInstance(new Object[]{h});
      ...
    }  

分析通過動(dòng)態(tài)代理生成的字節(jié)碼文件
getProxyClass0()獲取代理類字節(jié)碼文件,主要使用了ProxyGenerator.generateProxyClass()生成了代理類冒冬,默認(rèn)在內(nèi)存中伸蚯,如果你想生成文件觀看需要設(shè)置兩個(gè)步驟:
一、設(shè)置System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true") 獲取本地文件, 通過此語(yǔ)句可以立個(gè)flag讓生成字節(jié)碼文件的時(shí)候简烤,輸出本地字節(jié)碼文件,注意這句話一定要在獲取代理類實(shí)例之前剂邮。
二、需要在main函數(shù)中調(diào)用才能生成字節(jié)碼文件乐埠,原因未知抗斤,但是我在其他地方調(diào)用是不能生成字節(jié)碼文件的。
生成的文件在當(dāng)前項(xiàng)目的根目錄丈咐,對(duì)應(yīng)的包名文件夾里:com/sun/proxy/$Proxy().class

3.png

ProxyGenerator
這個(gè)類是生成對(duì)應(yīng)的代理類字節(jié)碼,也就是通過這個(gè)方法

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//這是對(duì)應(yīng)設(shè)置是否生成對(duì)應(yīng)路徑的字節(jié)碼文件瑞眼,默認(rèn)只會(huì)生成在內(nèi)存中
public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        final byte[] var4 = var3.generateClassFile();
        //我們現(xiàn)在控制的就是這個(gè)變量,如果為ture表示字節(jié)碼文件寫入本地
        if (saveGeneratedFiles) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    try {
                        int var1 = var0.lastIndexOf(46);
                        Path var2;
                        if (var1 > 0) {
                            Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                            Files.createDirectories(var3);
                            var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                        } else {
                            var2 = Paths.get(var0 + ".class");
                        }

                        Files.write(var2, var4, new OpenOption[0]);
                        return null;
                    } catch (IOException var4x) {
                        throw new InternalError("I/O exception saving generated file: " + var4x);
                    }
                }
            });
        }
        return var4;
    }

來看下生成的字節(jié)碼文件

package com.sun.proxy;

import com.wzy.dynamic.proxy.dproxy.Ibusiness;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Ibusiness {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;
    
    //關(guān)鍵點(diǎn)
    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void business() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.wzy.dynamic.proxy.dproxy.Ibusiness").getMethod("business");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

關(guān)鍵的構(gòu)造函數(shù)

//這個(gè)handler就是我們最初傳入的那個(gè)InvocationHandler的實(shí)現(xiàn)類
public $Proxy0(InvocationHandler var1) throws  {
    super(var1);
}

接著看父類

//這個(gè)H就是我們自己的InvocationHandler
protected Proxy(InvocationHandler var1) {
    Objects.requireNonNull(var1);
    this.h = var1;
}

Proxy中有一個(gè)這個(gè)靜態(tài)方法就是最終會(huì)回到我們實(shí)現(xiàn)的invoke類中

 private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
        InvocationHandler h = proxy.h;
        return h.invoke(proxy, method, args);
 }

所有相關(guān)的調(diào)用最終也都會(huì)調(diào)用這個(gè)方法棵逊,具體可以看上面的字節(jié)碼類

//$Proxy0.class
public final void business() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

總結(jié)一下伤疙,代理類執(zhí)行的任何一個(gè)方法都會(huì)回調(diào)你的InvocationHandler實(shí)現(xiàn)類。而且通過ProxyGenerator.generateProxyClass()確實(shí)動(dòng)態(tài)生成了字節(jié)碼文件辆影!
那么看完這些咱們也明白了InvocationHandler中invoke(Object proxy, Method method, Object[] args) 這三個(gè)參數(shù)分別是什么?
參數(shù)一:Object 生成的代理類對(duì)象
參數(shù)二:Method 代理類調(diào)用的方法
參數(shù)三:args 調(diào)用方法時(shí)的參數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末徒像,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蛙讥,更是在濱河造成了極大的恐慌锯蛀,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件次慢,死亡現(xiàn)場(chǎng)離奇詭異旁涤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)迫像,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門劈愚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人闻妓,你說我怎么就攤上這事菌羽。” “怎么了由缆?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵注祖,是天一觀的道長(zhǎng)猾蒂。 經(jīng)常有香客問我,道長(zhǎng)是晨,這世上最難降的妖魔是什么婚夫? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮署鸡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘限嫌。我一直安慰自己靴庆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布怒医。 她就那樣靜靜地躺著炉抒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稚叹。 梳的紋絲不亂的頭發(fā)上焰薄,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音扒袖,去河邊找鬼塞茅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛季率,可吹牛的內(nèi)容都是我干的野瘦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼飒泻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鞭光!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起泞遗,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惰许,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后史辙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汹买,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年髓霞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卦睹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡方库,死狀恐怖结序,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纵潦,我是刑警寧澤徐鹤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布垃环,位于F島的核電站,受9級(jí)特大地震影響返敬,放射性物質(zhì)發(fā)生泄漏遂庄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一劲赠、第九天 我趴在偏房一處隱蔽的房頂上張望涛目。 院中可真熱鬧,春花似錦凛澎、人聲如沸霹肝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沫换。三九已至,卻和暖如春最铁,著一層夾襖步出監(jiān)牢的瞬間讯赏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工冷尉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漱挎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓网严,卻偏偏與公主長(zhǎng)得像识樱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子震束,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 定義 代理模式又叫委托模式怜庸,是為某個(gè)對(duì)象提供一個(gè)代理對(duì)象,并且由代理對(duì)象控制對(duì)原對(duì)象的訪問垢村。代理模式通俗來講就是我...
    奔向?qū)W霸的路上閱讀 537評(píng)論 0 0
  • 7.代理模式 7.1.課程目標(biāo) 1嘉栓、掌握代理模式的應(yīng)用場(chǎng)景和實(shí)現(xiàn)原理宏榕。 2、了解靜態(tài)代理和動(dòng)態(tài)代理的區(qū)別侵佃。 3麻昼、了...
    我是阿喵醬閱讀 623評(píng)論 0 0
  • 一、概述 ??代理模式我們接觸的就比較多了馋辈,所謂的代理模式就是抚芦,給某一個(gè)對(duì)象提供一個(gè)代理對(duì)象,并由代理對(duì)象控制對(duì)原...
    騎著烏龜去看海閱讀 907評(píng)論 0 9
  • 什么是代理模式 代理模式是對(duì)象的結(jié)構(gòu)模式。代理模式為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問叉抡。簡(jiǎn)單來說尔崔,在某些情...
    walidake閱讀 3,214評(píng)論 4 27
  • 聲明:原創(chuàng)作品,轉(zhuǎn)載請(qǐng)注明出處http://www.reibang.com/p/e4c1e6b734ad 今天來...
    蛇發(fā)女妖閱讀 1,696評(píng)論 3 8