設(shè)計(jì)模式-責(zé)任鏈模式

責(zé)任鏈模式的介紹

? 責(zé)任鏈模式(Iterator Pattren),是行為型設(shè)計(jì)模式之一。什么是“鏈”雌贱?我們將多個(gè)節(jié)點(diǎn)首尾相連所構(gòu)成的模型稱為鏈蜓萄,比如生活中常見(jiàn)的鎖鏈,就是由一個(gè)個(gè)圓角長(zhǎng)方形的鐵環(huán)串起來(lái)的結(jié)構(gòu)鞠眉。對(duì)于鏈?zhǔn)浇Y(jié)構(gòu)薯鼠,每個(gè)節(jié)點(diǎn)都可以被拆開(kāi)再連接择诈,因此,鏈?zhǔn)浇Y(jié)構(gòu)也具有很好的靈活性出皇。將這樣一種結(jié)構(gòu)應(yīng)用于編程領(lǐng)域羞芍,將每個(gè)節(jié)點(diǎn)看作是一個(gè)對(duì)象,每個(gè)對(duì)象擁有不同的處理邏輯郊艘,將一個(gè)請(qǐng)求從鏈?zhǔn)降氖锥税l(fā)出荷科,沿著鏈的路徑一次傳遞給每一個(gè)節(jié)點(diǎn)對(duì)象,直至有對(duì)象處理這個(gè)請(qǐng)求為止纱注,我們將這樣的一種模式稱為責(zé)任鏈模式畏浆。

責(zé)任鏈模式的定義

? 使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系奈附。將這些對(duì)象連成一條鏈全度,并沿著這條鏈傳遞該請(qǐng)求,直到有對(duì)象處理它為止斥滤。

責(zé)任鏈模式的使用場(chǎng)景

  • 多個(gè)對(duì)象可以處理同一請(qǐng)求将鸵,但具體由哪個(gè)對(duì)象處理則在運(yùn)行時(shí)動(dòng)態(tài)決定。
  • 在請(qǐng)求處理者不明確的情況下向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求佑颇。
  • 需要?jiǎng)討B(tài)指定一組對(duì)象處理請(qǐng)求顶掉。

責(zé)任鏈模式的UML類圖

責(zé)任鏈模式類圖.png

根據(jù)類圖我們可以得出如下一個(gè)責(zé)任鏈模式簡(jiǎn)化版通用模式代碼。

//抽象處理類
public abstract class Handler {
    protected Handler successor; //下一個(gè)節(jié)點(diǎn)的處理者
    /**
     * 請(qǐng)求處理
     * @param conditon 請(qǐng)求條件
     */
    public abstract void handlerRequest(String conditon);
}

//具體的處理者1
public class ConcreteHandler1 extends Handler {

    @Override
    public void handlerRequest(String conditon) {
        if (conditon.equals("ConcreteHandler1")) {
            System.out.println("ConcreteHandler1 handler");
        } else {
            successor.handlerRequest(conditon);
        }
    }
}


//具體處理者2
public class ConcreteHandler2 extends Handler {

    @Override
    public void handlerRequest(String conditon) {
        if (conditon.equals("ConcreteHandler2")) {
            System.out.println("ConcreteHandler2 handler");
        } else {
            successor.handlerRequest(conditon);
        }
    }
}

//客戶類 
public class Client {
    @Test
    public void test() {
        //構(gòu)造一個(gè)ConcreteHandler1對(duì)象
        ConcreteHandler1 handler1 = new ConcreteHandler1();

        //構(gòu)造一個(gè)ConcreteHandler2對(duì)象
        ConcreteHandler2 handler2 = new ConcreteHandler2();

        //設(shè)置handler1的下一個(gè)節(jié)點(diǎn)
        handler1.successor = handler2;

        //設(shè)置handler2的下一個(gè)節(jié)點(diǎn)
        handler2.successor = handler1;

        //處理請(qǐng)求
        handler1.handlerRequest("ConcreteHandler2");
    }
}

角色介紹

  • Handler :抽象處理者角色挑胸,聲明一個(gè)請(qǐng)求處理的方法痒筒,并在其中保持一個(gè)對(duì)下一個(gè)處理節(jié)Handler 對(duì)象的引用。
  • ConcreteHandler :具體的處理者對(duì)請(qǐng)求進(jìn)行處理 茬贵,如果不能處理則將該請(qǐng)求轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn)上的處理對(duì)象簿透。

上面我們說(shuō)這個(gè)一個(gè)簡(jiǎn)化版的通用模板代碼,為什么這個(gè)說(shuō)呢解藻?因?yàn)閷?duì)于請(qǐng)求來(lái)說(shuō)老充,其形式是固定的,就是一個(gè)字符串螟左,而判斷一個(gè)節(jié)點(diǎn)上的對(duì)象是否能夠處理該請(qǐng)求的標(biāo)志啡浊,則是該字符串是否與之匹配。然而 在大多數(shù)情況下胶背,責(zé)任鏈中的請(qǐng)求和對(duì)應(yīng)的處理規(guī)則是不盡相同的巷嚣,在這種情況下可以將請(qǐng)求進(jìn)行封裝,同時(shí)對(duì)請(qǐng)求的處理規(guī)則也進(jìn)行封裝作為一個(gè)獨(dú)立的對(duì)象钳吟,類圖如下所示:


責(zé)任鏈模式封裝類圖.png

首先我們看下AbstractHandler 抽象處理者廷粒,其聲明了處理者對(duì)象處理請(qǐng)求的方法和獲取處理級(jí)別的方法,并對(duì)具體的處理轉(zhuǎn)發(fā)邏輯進(jìn)行了實(shí)現(xiàn)砸抛。

public abstract class AbstractHandler {
    
    protected AbstractHandler nextHandler;
    
    public final void handleRequest(AbstractRequest request){
        //判斷當(dāng)前處理者對(duì)象的處理級(jí)別是否與請(qǐng)求者的處理級(jí)別一致
        if (getHandleLevel()==request.getHandleLevel()){
            handle(request);
        }else {
            //否則將請(qǐng)求對(duì)象轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn)上的請(qǐng)求對(duì)象
            if (nextHandler!=null){
                nextHandler.handleRequest(request);
            }else {
                //當(dāng)所有處理者對(duì)象均不能處理該請(qǐng)求輸出
                System.out.println("All of haandler can't handle the request");
            }
        }
    }
    
    /**
     * 獲取處理者對(duì)象的處理級(jí)別
     * @return 處理級(jí)別
     */
    protected abstract int getHandleLevel();

    /**
     * 每個(gè)處理者對(duì)象的具體處理方式
     * @param request 請(qǐng)求者對(duì)象
     */
    protected abstract void handle(AbstractRequest request);
}

在這種情況下我們的責(zé)任轉(zhuǎn)發(fā)邏輯由抽象處理類控制评雌,而對(duì)于抽象請(qǐng)求者树枫,其內(nèi)部也聲明了一個(gè)獲取請(qǐng)求級(jí)別的方法,其與抽象處理者中返回的處理級(jí)別保持對(duì)應(yīng)景东,什么級(jí)別的處理邏輯就對(duì)應(yīng)什么樣的請(qǐng)求級(jí)別砂轻。

//抽象請(qǐng)求類
public abstract class AbstractRequest {
    //處理 對(duì)象
    private Object obj;

    public AbstractRequest(Object obj) {
        this.obj = obj;
    }

    /**
     * 獲取處理的內(nèi)容對(duì)象
     * @return 具體的處理對(duì)象
     */
    public Object getContent(){
        return obj;
    }

    /**
     * 獲取請(qǐng)求級(jí)別
     * @return 請(qǐng)求級(jí)別
     */
    public abstract int getHandleLevel();
}

下面我們分別實(shí)現(xiàn)3個(gè)請(qǐng)求者和3 個(gè)處理者對(duì)象 ,邏輯很簡(jiǎn)單斤吐。

public class Request1 extends AbstractRequest {
    public Request1(Object obj) {
        super(obj);
    }

    @Override
    public int getHandleLevel() {
        return 1;
    }
}

public class Request2 extends AbstractRequest {
    public Request2(Object obj) {
        super(obj);
    }

    @Override
    public int getHandleLevel() {
        return 2;
    }
}

public class Request3 extends AbstractRequest {
    public Request3(Object obj) {
        super(obj);
    }

    @Override
    public int getHandleLevel() {
        return 3;
    }
}

處理者

public class Handler1 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 1;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handle1 handle request:"+request.getHandleLevel());
    }
}

public class Handler2 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 2;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handle2 handle request:"+request.getHandleLevel());
    }
}

public class Handler3 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 2;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handle3 handle request:"+request.getHandleLevel());
    }
}

下面是客戶類

public class Client {
    @Test
    public void main(){
        //構(gòu)造三個(gè)處理者對(duì)象
        Handler1 handler1 = new Handler1();
        Handler2 handler2 = new Handler2();
        Handler3 handler3 = new Handler3();

        //設(shè)置當(dāng)前處理者對(duì)象的下一個(gè)節(jié)點(diǎn)
        handler1.nextHandler = handler2;
        handler2.nextHandler = handler3;

        //構(gòu)造三個(gè)請(qǐng)求者對(duì)象
        Request1 request1 = new Request1("Request1");
        Request2 request2 = new Request2("Request2");
        Request3 request3 = new Request3("Request3");

        //總是從鏈?zhǔn)降氖锥税l(fā)起請(qǐng)求
        handler1.handleRequest(request1);
        handler2.handleRequest(request2);
        handler1.handleRequest(request3);
    }
}
結(jié)果:
Handle1 handle request:1
Handle2 handle request:2
Handle3 handle request:3

責(zé)任鏈模式的簡(jiǎn)單實(shí)現(xiàn)

舉個(gè)例子:公司安排小明出差搔涝,出差回來(lái)后花費(fèi)了近5萬(wàn)元,于是小明第二天上班找組長(zhǎng)申請(qǐng)報(bào)銷費(fèi)用和措,組長(zhǎng)一看是一筆不小的數(shù)目庄呈,他沒(méi)有權(quán)限審批,于是組長(zhǎng)拿著票據(jù)去找部門主管派阱,主管一看要報(bào)這么多錢诬留,自己權(quán)限只能批5千以下的費(fèi)用,這完全超出了自己的范圍贫母,于是主管又去找經(jīng)理文兑,經(jīng)理一看二話不說(shuō)直接拿著票據(jù)去了老板的辦公室,因?yàn)樗荒芘蝗f(wàn)以下的費(fèi)用腺劣,上面的情景就是一個(gè)責(zé)任鏈模式的小例子绿贞,每一個(gè)人,準(zhǔn)確的說(shuō)是每一類人代表這條鏈上的一個(gè)節(jié)點(diǎn)橘原,小明是請(qǐng)求的發(fā)起者籍铁,而老板則是出于鏈條頂端的類,小明在鏈條底端發(fā)起一個(gè)申請(qǐng)報(bào)賬的請(qǐng)求趾断,首先由組長(zhǎng)處理該請(qǐng)求拒名,組長(zhǎng)對(duì)比后發(fā)現(xiàn)自己權(quán)限不夠于是將該請(qǐng)求轉(zhuǎn)發(fā)給位于鏈中的下一個(gè)節(jié)點(diǎn)的主管,主管對(duì)比后也發(fā)現(xiàn)自己的權(quán)限不夠又將該請(qǐng)求轉(zhuǎn)發(fā)給經(jīng)理芋酌,而經(jīng)理也基于同樣的原因?qū)⒄?qǐng)求轉(zhuǎn)發(fā)給老板靡狞,這樣層層轉(zhuǎn)達(dá)直至請(qǐng)求被處理,從中大家可以看到一個(gè)顯而易見(jiàn)的事隔嫡,就是至始至終小明只與組長(zhǎng)產(chǎn)生的關(guān)聯(lián),后面具體由誰(shuí)處理的票據(jù)甘穿,小明并不關(guān)心腮恩,唯一在乎的是報(bào)賬的結(jié)果,責(zé)任鏈模式在這里很好地將請(qǐng)求的發(fā)起者與處理者解耦温兼。我們?cè)诖a 中模擬這個(gè)過(guò)程秸滴,首先還是先聲明一個(gè)抽象的領(lǐng)導(dǎo)類。

//抽象領(lǐng)導(dǎo)者
public abstract class Leader {
    //上一級(jí)領(lǐng)導(dǎo)處理者
    protected Leader nexthandler;

    public void handlerRequest(int money){
        if (money<=limit()) {
            handle(money);
        }else {
            if (nexthandler != null) {
                nexthandler.handle(money);
            }
        }
    }

    /**
     * 自身能審批的額度
     * @return 額度
     */
    public abstract int limit();

    /**
     * 處理報(bào)賬行為
     * @param money 具體金額
     */
    public abstract void handle(int money);
}

在這個(gè)抽象的領(lǐng)導(dǎo)類中只做了兩件事募判,一是定義了兩個(gè)抽象接口方法來(lái)確定一個(gè)領(lǐng)導(dǎo)者應(yīng)有的行為和屬性荡含,而是聲明了一個(gè)處理報(bào)賬請(qǐng)求的方法來(lái)確定當(dāng)前領(lǐng)導(dǎo)是否有能力處理報(bào)賬請(qǐng)求咒唆,如果沒(méi)有這個(gè)權(quán)限,則將該請(qǐng)求轉(zhuǎn)發(fā)給上一級(jí)的領(lǐng)導(dǎo)處理释液,接下來(lái)是各個(gè)領(lǐng)導(dǎo)類的實(shí)現(xiàn)全释。

public class GroupLeader extends Leader {
    @Override
    public int limit() {
        return 1000;
    }

    @Override
    public void handle(int money) {
        System.out.println("組長(zhǎng)審批報(bào)銷"+money +"元");
    }
}

public class Director extends Leader {
    @Override
    public int limit() {
        return 5000;
    }

    @Override
    public void handle(int money) {
        System.out.println("主管審批報(bào)銷"+money +"元");
    }
}

public class Manager extends Leader {
    @Override
    public int limit() {
        return 10000;
    }

    @Override
    public void handle(int money) {
        System.out.println("經(jīng)理審批報(bào)銷"+money +"元");
    }
}

public class Boss extends Leader {
    @Override
    public int limit() {
        return Integer.MAX_VALUE;
    }

    @Override
    public void handle(int money) {
        System.out.println("老板審批報(bào)銷"+money +"元");
    }
}

最后小明從組長(zhǎng)開(kāi)始請(qǐng)求申請(qǐng)報(bào)帳。

    @Test
    public void main() {
        //構(gòu)造各個(gè)領(lǐng)導(dǎo)
        GroupLeader groupLeader = new GroupLeader();
        Director director = new Director();
        Manager manager = new Manager();
        Boss boss = new Boss();
        //設(shè)置上一級(jí)領(lǐng)導(dǎo)處理者
        groupLeader.nexthandler = director;
        director.nexthandler = manager;
        manager.nexthandler = boss;
        //發(fā)起請(qǐng)求
        groupLeader.handlerRequest(50000);
    }
結(jié)果
老板審批報(bào)銷50000元

這里大家可能會(huì)想误债,可不可以直接越過(guò)組長(zhǎng)找組長(zhǎng)報(bào)賬呢浸船?答案是肯定的,這也是責(zé)任鏈模式的靈活之處寝蹈,請(qǐng)求的發(fā)起可以從責(zé)任鏈的任何一個(gè)節(jié)點(diǎn)開(kāi)始李命,同時(shí)也可以改變責(zé)任鏈內(nèi)部的傳遞規(guī)則,如果主管不在箫老,我們完全可以跨過(guò)主管從組長(zhǎng)直接將請(qǐng)求轉(zhuǎn)送給經(jīng)理封字。

對(duì)于責(zé)任鏈中的一個(gè)處理者對(duì)象,其中只有兩個(gè)行為耍鬓,一是請(qǐng)求處理阔籽,而是將請(qǐng)求轉(zhuǎn)送給下一個(gè)節(jié)點(diǎn),不允許某個(gè)處理者對(duì)象在處理了請(qǐng)求后又將請(qǐng)求轉(zhuǎn)發(fā)給上一個(gè)節(jié)點(diǎn)的情況界斜。對(duì)于一條責(zé)任鏈來(lái)說(shuō)仿耽,一個(gè)請(qǐng)求最終只有兩種情況,一是被某個(gè)處理對(duì)象所處理各薇,另一個(gè)是所有對(duì)象均未對(duì)其處理项贺,對(duì)于前一個(gè)情況我們稱該責(zé)任鏈為純的責(zé)任鏈,對(duì)于后一種情況我們稱為不純的責(zé)任鏈峭判,在實(shí)際應(yīng)用中开缎,我們所見(jiàn)到的責(zé)任鏈模式大多為不純的責(zé)任鏈。

責(zé)任鏈模式的實(shí)戰(zhàn)

責(zé)任鏈模式與其說(shuō)實(shí)在Android 中的應(yīng)用倒不如說(shuō)是在Java 中的應(yīng)用林螃,畢竟上層應(yīng)用開(kāi)發(fā)大多都是基于Java 的奕删,而我們的設(shè)計(jì)模式也是針對(duì)Java 而言,Android 中我們可以借鑒責(zé)任鏈模式的思想來(lái)優(yōu)化BroadcastReceiver 使之成為一個(gè)全局的責(zé)任處理者疗认,具體方法很簡(jiǎn)單完残,我們知道Broadcast 可以分為兩種,一種是Normal Broadcast 普通廣播横漏,另一種是Order Broadcast 有序廣播谨设,普通廣播是異步的,發(fā)出時(shí)可以被所有的接收者收到缎浇;而有序廣播則是根據(jù)優(yōu)先級(jí)一次傳播的扎拣,直到有接收者將其終止或所有接收者都不終止它,有序廣播的這一特性與我們的責(zé)任鏈模式很想近,通過(guò)它可以實(shí)現(xiàn)一種全局的責(zé)任鏈?zhǔn)录幚矶叮@里我們創(chuàng)建3個(gè) BroadcastReceiver誉券。

public class FirstReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //獲取Intent中附加的限制值
        int limit = intent.getIntExtra("limit", -1001);
        //如果限制值等于1000則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver
        if (limit!=1000) {
            Bundle bundle = new Bundle();
            bundle.putString("new","Message from FirstReceiver");
            setResultExtras(bundle);
        }else {
            String msg = intent.getStringExtra("msg");
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
    }
}

在發(fā)送廣播的時(shí)候我們?cè)?code>Intent 中附加兩個(gè)值刊愚,一個(gè)int類型的值用于存儲(chǔ)權(quán)限值踊跟,另一個(gè)String類型的則存儲(chǔ)消息,一個(gè)接收者能否處理本次廣播的唯一條件則是看廣播中所附加的權(quán)限值是否與自身相等如上面FirstReceiver 的處理權(quán)限值是1000百拓;則只有當(dāng)limit =1000時(shí)才會(huì)處理本次廣播琴锭,否則在廣播的Intent中在附加一條信息傳遞出去給下一個(gè)接收者。

public class FirstReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //獲取Intent中附加的限制值
        int limit = intent.getIntExtra("limit", -1001);
        //如果限制值等于1000則處理衙传,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver
        if (limit!=1000) {
            Bundle bundle = new Bundle();
            bundle.putString("new","Message from FirstReceiver");
            setResultExtras(bundle);
        }else {
            String msg = intent.getStringExtra("msg");
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
    }
}

public class SecondReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //獲取Intent中附加的限制值
        int limit = intent.getIntExtra("limit", -1001);
        //如果限制值等于1000則處理决帖,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver
        if (limit!=100) {
            Bundle bundle = new Bundle();
            bundle.putString("new","Message from SecondReceiver");
            setResultExtras(bundle);
        }else {
            String msg = intent.getStringExtra("msg");
            Bundle bundle = getResultExtras(true);
            String str = bundle.getString("new");
            Toast.makeText(context,msg+"<<<>>>" +str, Toast.LENGTH_SHORT).show();
            abortBroadcast();
        }
    }
}

public class ThridReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //獲取Intent中附加的限制值
        int limit = intent.getIntExtra("limit", -1001);
        //如果限制值等于1000則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver
        if (limit!=10) {
            Bundle bundle = new Bundle();
            bundle.putString("new","Message from ThridReceiver");
            setResultExtras(bundle);
        }else {
            String msg = intent.getStringExtra("msg");
            Bundle bundle = getResultExtras(true);
            String str = bundle.getString("new");
            Toast.makeText(context,msg+"<<<>>>" +str, Toast.LENGTH_SHORT).show();
            abortBroadcast();
        }
    }
}

最后我們還要在清單文件聲明3個(gè)Receiver,并設(shè)定對(duì)應(yīng)的權(quán)限值蓖捶。

        <receiver android:name=".FirstReceiver" android:exported="false">
            <intent-filter android:priority="1000">
                <action android:name="ORDER_BROADCAST" />
            </intent-filter>
        </receiver>
        <receiver android:name=".SecondReceiver" android:exported="false">
            <intent-filter android:priority="100">
                <action android:name="ORDER_BROADCAST" />
            </intent-filter>
        </receiver>
        <receiver android:name=".ThridReceiver" android:exported="false">
            <intent-filter android:priority="10">
                <action android:name="ORDER_BROADCAST" />
            </intent-filter>
        </receiver>

完成后地回,我們?cè)谝粋€(gè)Activity中發(fā)送一個(gè)廣播

        Intent intent = new Intent();
        intent.setAction("ORDER_BROADCAST");
        intent.putExtra("limit",1000);
        intent.putExtra("msg","Message from MainActivity");
        sendOrderedBroadcast(intent,null);

這里將limit 設(shè)置為100 ,也就是說(shuō)只有SecondReceiver才會(huì)處理它俊鱼。

總結(jié)

  • 優(yōu)點(diǎn):可以對(duì)請(qǐng)求者和處理者關(guān)系解耦刻像,提高代碼的靈活性。
  • 缺點(diǎn):對(duì)鏈中請(qǐng)求處理者的遍歷并闲,如果處理者太多细睡,那么遍歷必定會(huì)影響性能,特別是在一些遞歸調(diào)用中帝火。

Demo

設(shè)計(jì)模式Demo

參考

《Android源碼設(shè)計(jì)模式》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溜徙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子犀填,更是在濱河造成了極大的恐慌蠢壹,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件九巡,死亡現(xiàn)場(chǎng)離奇詭異图贸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)冕广,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門洲守,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)臊泰,“玉大人端朵,你說(shuō)我怎么就攤上這事稿蹲∑俳梗” “怎么了饥伊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵辅愿,是天一觀的道長(zhǎng)竿报。 經(jīng)常有香客問(wèn)我,道長(zhǎng)溉委,這世上最難降的妖魔是什么鹃唯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮瓣喊,結(jié)果婚禮上坡慌,老公的妹妹穿的比我還像新娘。我一直安慰自己藻三,他們只是感情好洪橘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著棵帽,像睡著了一般熄求。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逗概,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天弟晚,我揣著相機(jī)與錄音,去河邊找鬼逾苫。 笑死卿城,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铅搓。 我是一名探鬼主播瑟押,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼星掰!你這毒婦竟也來(lái)了多望?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蹋偏,失蹤者是張志新(化名)和其女友劉穎便斥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體威始,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枢纠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黎棠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晋渺。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脓斩,靈堂內(nèi)的尸體忽然破棺而出木西,到底是詐尸還是另有隱情,我是刑警寧澤随静,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布八千,位于F島的核電站吗讶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏恋捆。R本人自食惡果不足惜照皆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沸停。 院中可真熱鬧膜毁,春花似錦、人聲如沸愤钾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)能颁。三九已至杂瘸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間劲装,已是汗流浹背胧沫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留占业,地道東北人绒怨。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像谦疾,于是被迫代替她去往敵國(guó)和親南蹂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是責(zé)任鏈模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 純與不純的責(zé)任鏈模式 優(yōu)點(diǎn)和缺點(diǎn) ...
    w1992wishes閱讀 1,260評(píng)論 4 14
  • 定義 責(zé)任鏈模式是一種對(duì)象的行為模式念恍。在責(zé)任鏈模式中六剥,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來(lái)形成一條鏈。請(qǐng)求...
    步積閱讀 2,062評(píng)論 1 5
  • 今天來(lái)說(shuō)說(shuō)程序員小猿和產(chǎn)品就關(guān)于需求發(fā)生的故事峰伙。前不久疗疟,小猿收到了產(chǎn)品的需求。 產(chǎn)品經(jīng)理:小猿瞳氓,為了迎合大眾屌絲用...
    Jet啟思閱讀 6,382評(píng)論 0 14
  • 前言 Android的設(shè)計(jì)模式系列文章介紹策彤,歡迎關(guān)注,持續(xù)更新中: Android的設(shè)計(jì)模式-設(shè)計(jì)模式的六大原則一...
    四月葡萄閱讀 9,493評(píng)論 5 20
  • 游戲:游樂(lè)匣摘,玩耍店诗;娛樂(lè)活動(dòng)。伴我良久音榜,分分合合庞瘸,合合分分。最終赠叼,在手機(jī)里批了一塊地給游戲擦囊,好讓它安身立命违霞。我與游戲...
    窗外_6ac6閱讀 195評(píng)論 2 1