Android 責(zé)任鏈模式

源碼地址

介紹

它是一種行為型設(shè)計(jì)模式之一。它的每一個(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é)任鏈模式。

使用場(chǎng)景

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

示例一

說明:此為簡(jiǎn)化版代碼,分為抽象處理者,具體的處理者。代碼如下:

  1. 抽象處理者

    public abstract class Handler {
        protected Handler successor;    //下一節(jié)點(diǎn)的處理者
    
        /**
         * 請(qǐng)求處理
         * @param condition 請(qǐng)求條件
         */
        public abstract void handleRequest(String condition);
    }
    
  2. 具體的處理者1

    public class ConcreteHandler1 extends Handler {
        @Override
        public void handleRequest(String condition) {
            if (condition.equals("ConcreteHandler1")) {
                System.out.println("ConcreteHandler1 handled");
            } else {
                successor.handleRequest(condition);
            }
        }
    }
    
  3. 具體的處理者2

    public class ConcreteHandler2 extends Handler {
        @Override
        public void handleRequest(String condition) {
            if (condition.equals("ConcreteHandler2")) {
                System.out.println("ConcreteHandler2 handled");
            } else {
                successor.handleRequest(condition);
            }
        }
    }
    
  4. 客戶類

    public class Client {
        public static void main(String[] args) {
            //構(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.handleRequest("ConcreteHandler2");
        }
    }
    

示例二

說明:抽象處理者,抽象請(qǐng)求者,請(qǐng)求者,處理者。代碼如下:

  1. 抽象處理者

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

    public abstract class AbstractRequest {
        private Object obj; //處理對(duì)象
    
        public AbstractRequest(Object obj) {
            this.obj = obj;
        }
    
        public Object getContent() {
            return obj;
        }
    
        /**
         * 獲取請(qǐng)求級(jí)別
         * @return  請(qǐng)求級(jí)別
         */
        public abstract int getRequestLevel();
    }
    
  3. 請(qǐng)求者

    public class Request1 extends AbstractRequest {
        public Request1(Object obj) {
            super(obj);
        }
    
        @Override
        public int getRequestLevel() {
            return 1;
        }
    }
    
    public class Request2 extends AbstractRequest {
        public Request2(Object obj) {
            super(obj);
        }
    
        @Override
        public int getRequestLevel() {
            return 2;
        }
    }
    
    public class Request3 extends AbstractRequest {
        public Request3(Object obj) {
            super(obj);
        }
    
        @Override
        public int getRequestLevel() {
            return 3;
        }
    }
    
  4. 處理者

    public class Handler1 extends AbstractHandler {
        @Override
        protected int getHandleLevel() {
            return 1;
        }
    
        @Override
        protected void handle(AbstractRequest request) {
            System.out.println("Handler1 handle request:" + request.getRequestLevel());
        }
    }
    
    public class Handler2 extends AbstractHandler {
        @Override
        protected int getHandleLevel() {
            return 2;
        }
    
        @Override
        protected void handle(AbstractRequest request) {
            System.out.println("Handler2 handle request:" + request.getRequestLevel());
        }
    }
    
    public class Handler3 extends AbstractHandler {
        @Override
        protected int getHandleLevel() {
            return 3;
        }
    
        @Override
        protected void handle(AbstractRequest request) {
            System.out.println("Handler3 handle request:" + request.getRequestLevel());
        }
    }
    
  5. 客戶類

    public class Client {
        public static void main(String[] args) {
            //構(gòu)造3個(gè)處理者對(duì)象
            AbstractHandler handler1 = new Handler1();
            AbstractHandler handler2 = new Handler2();
            AbstractHandler handler3 = new Handler3();
    
            //設(shè)置當(dāng)前處理者對(duì)象下一個(gè)節(jié)點(diǎn)的處理者對(duì)象
            handler1.nextHandler = handler2;
            handler2.nextHandler = handler3;
    
            //構(gòu)造3個(gè)請(qǐng)求者對(duì)象
            AbstractRequest request1 = new Request1("Request1");
            AbstractRequest request2 = new Request2("Request2");
            AbstractRequest request3 = new Request3("Request3");
    
            //總是從鏈?zhǔn)降氖锥税l(fā)起請(qǐng)求
            handler1.handleRequest(request1);
            handler1.handleRequest(request2);
            handler1.handleRequest(request3);
        }
    }
    

示例三

說明:小明出差學(xué)些新技術(shù),其中花費(fèi)了5w元,于是小明去找組長報(bào)銷費(fèi)用。。。代碼如下:

  1. 抽象領(lǐng)導(dǎo)者

    public abstract class Leader {
        //上一級(jí)領(lǐng)導(dǎo)處理者
        protected Leader nextHandler;
    
        /**
         * 處理報(bào)賬請(qǐng)求
         * @param money 能批復(fù)的報(bào)賬額度
         */
        public final void handleRequest(int money) {
            if (money <= limit()) {
                handle(money);
            } else {
                if (nextHandler != null) {
                    nextHandler.handleRequest(money);
                }
            }
        }
    
        /**
         * 自身能夠批復(fù)的額度權(quán)限
         * @return  額度
         */
        protected abstract int limit();
    
        /**
         * 處理報(bào)賬行為
         * @param money 具體金額
         */
        protected abstract void handle(int money);
    }
    
  2. 具體的領(lǐng)導(dǎo)者

    public class GroupLeader extends Leader {
    
        @Override
        protected int limit() {
            return 1000;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("組長批復(fù)報(bào)銷" + money + "元");
        }
    }
    
    public class Director extends Leader {
    
        @Override
        protected int limit() {
            return 5000;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("主管批復(fù)報(bào)銷" + money + "元");
        }
    }
    
    public class Manager extends Leader {
    
        @Override
        protected int limit() {
            return 10000;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("經(jīng)理批復(fù)報(bào)銷" + money + "元");
        }
    }
    
    public class Boss extends Leader {
    
        @Override
        protected int limit() {
            return Integer.MAX_VALUE;
        }
    
        @Override
        protected void handle(int money) {
            System.out.println("老板批復(fù)報(bào)銷" + money + "元");
        }
    }
    
  3. 客戶類小明

    public class XiaoMing {
        public static void main(String[] args) {
            //構(gòu)造各個(gè)領(lǐng)導(dǎo)對(duì)象
            GroupLeader groupLeader = new GroupLeader();
            Director director = new Director();
            Manager manager = new Manager();
            Boss boss = new Boss();
    
            //設(shè)置上一級(jí)領(lǐng)導(dǎo)處理者對(duì)象
            groupLeader.nextHandler = director;
            director.nextHandler = manager;
            manager.nextHandler = boss;
    
            //發(fā)起報(bào)賬申請(qǐng)
            groupLeader.handleRequest(50000);
        }
    }
    

    小明先找組長報(bào)賬,然后組長找到主管,主管找到經(jīng)理,經(jīng)理最后找到老板解決。

    當(dāng)然也可以直接跳過某個(gè)人。

對(duì)于責(zé)任鏈中的一個(gè)處理者對(duì)象,其只有兩種行為,一是處理請(qǐng)求,二是將請(qǐng)求轉(zhuǎn)送給下一個(gè)節(jié)點(diǎn),不允許某個(gè)處理者對(duì)象在處理了請(qǐng)求后又將請(qǐng)求轉(zhuǎn)送給上一個(gè)節(jié)點(diǎn)的情況。

對(duì)于一條責(zé)任鏈來說,一個(gè)請(qǐng)求最終只有兩種情況,一個(gè)唄某個(gè)處理對(duì)象所處理,另一個(gè)是所有對(duì)象均未對(duì)其處理,對(duì)于前一種情況我們稱該責(zé)任鏈為純的責(zé)任鏈,對(duì)于后一種情況我們稱為不純的責(zé)任鏈,在實(shí)際應(yīng)用中,我們所見到的責(zé)任鏈模式大多為不純的責(zé)任鏈。

Android 源碼中的實(shí)現(xiàn)

事件的分發(fā)處理。

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

說明:有序廣播的處理。源碼地址

  1. 廣播接收者

    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) {
                //獲取Intent中附加的字符串消息并Toast
                String msg = intent.getStringExtra("msg");
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    
                //終止廣播
                abortBroadcast();
            } else {
                //添加信息發(fā)送給下一個(gè)Receiver
                Bundle bundle = new Bundle();
                bundle.putString("new", "Message from FirstReceiver");
                setResultExtras(bundle);
            }
        }
    }
    
    public class SecondReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //獲取Intent中附加的限制值
            int limit = intent.getIntExtra("limit", -1001);
            //如果限制值等于100,則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver
            if (limit == 100) {
                //獲取Intent中附加的字符串消息并Toast
                String msg = intent.getStringExtra("msg");
    
                //獲取上一個(gè)Receiver增加的消息
                Bundle bundle = getResultExtras(true);
                String str = bundle.getString("new");
                Toast.makeText(context, msg + "-----" + str, Toast.LENGTH_SHORT).show();
    
                //終止廣播
                abortBroadcast();
            } else {
                //添加信息發(fā)送給下一個(gè)Receiver
                Bundle bundle = new Bundle();
                bundle.putString("new", "Message from SecondReceiver");
                setResultExtras(bundle);
            }
        }
    }
    
    public class ThirdReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //獲取Intent中附加的限制值
            int limit = intent.getIntExtra("limit", -1001);
            //如果限制值等于10,則處理,否則繼續(xù)轉(zhuǎn)發(fā)給下一個(gè)Receiver
            if (limit == 10) {
                //獲取Intent中附加的字符串消息并Toast
                String msg = intent.getStringExtra("msg");
    
                //獲取上一個(gè)Receiver增加的消息
                Bundle bundle = getResultExtras(true);
                String str = bundle.getString("new");
                Toast.makeText(context, msg + "-----" + str, Toast.LENGTH_SHORT).show();
    
                //終止廣播
                abortBroadcast();
            } else {
                //添加信息發(fā)送給下一個(gè)Receiver
                Bundle bundle = new Bundle();
                bundle.putString("new", "Message from ThirdReceiver");
                setResultExtras(bundle);
            }
        }
    }
    
  2. 部分清單文件數(shù)據(jù)

    <receiver android:name="com.yan.iterator.FirstReceiver">
        <intent-filter android:priority="1000">
            <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/>
        </intent-filter>
    </receiver>
    <receiver android:name="com.yan.iterator.SecondReceiver">
        <intent-filter android:priority="100">
            <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/>
        </intent-filter>
    </receiver>
    <receiver android:name="com.yan.iterator.ThirdReceiver">
        <intent-filter android:priority="10">
            <action android:name="com.yan.iterator.action.ORDER_BROADCAST"/>
        </intent-filter>
    </receiver>
    
  3. MainActivity

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction("com.yan.iterator.action.ORDER_BROADCAST");
                    intent.putExtra("limit", 100);
                    intent.putExtra("msg", "Message from MainActivity");
                    sendOrderedBroadcast(intent, null);
                }
            });
        }
    }
    

總結(jié)

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

    可以對(duì)請(qǐng)求者和處理者關(guān)系解耦,提高代碼的靈活性。

  • 缺點(diǎn)

    對(duì)鏈中請(qǐng)求處理者的遍歷,如果處理者太多,那么遍歷必定會(huì)影響性能,特別是在一些遞歸調(diào)用中,要慎重。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容