1. 
          

          1. 新聞動(dòng)態(tài)

            設計模式系列| 觀(guān)察者模式

            常見(jiàn)問(wèn)題 發(fā)布者:ou3377 2021-12-25 10:01 訪(fǎng)問(wèn)量:222

            這篇讓我們來(lái)認識一下觀(guān)察者模式


            1、概述

            觀(guān)察者模式是一種行為設計模式, 允許你定義一種訂閱機制, 可在對象事件發(fā)生時(shí)通知多個(gè) “觀(guān)察” 該對象的其他對象。

            2、適用場(chǎng)景

            1)當一個(gè)對象狀態(tài)的改變需要改變其他對象, 或實(shí)際對象是事先未知的或動(dòng)態(tài)變化時(shí), 可使用觀(guān)察者模式。

            2) 當應用中的一些對象必須觀(guān)察其他對象時(shí),可使用該模式。但僅能在有限時(shí)間內或特定情況下使用。訂閱者可隨時(shí)加入或離開(kāi)該列表。

            3、實(shí)例

            有以下場(chǎng)景:

            有一個(gè)小區,需要進(jìn)行核酸檢測。
            假設每個(gè)人通過(guò)關(guān)注公眾號獲取核酸檢測結果。

            發(fā)布者接口:

            /**
             * 發(fā)布接口
             */

            public interface IPublisher {

                /**
                 * 發(fā)布事件
                 * @param event
                 */

                void publish(IEvent event);
            }

            訂閱者接口:

            /**
             * 通用訂閱接口
             */

            public interface ISubscriber {

                /**
                 * 查看結果
                 */

                void look();
            }

            事件接口:

            /**
             * 通用事件接口
             */

            public interface IEvent {

                /**
                 * 打印事件信息
                 */

                void print();

            }

            消息發(fā)送者

            /**
             * 消息發(fā)送者
             */

            public class Publisher implements IPublisher{

                private IEvent event;

                private List<ISubscriber> subscribers;

                public Publisher(IEvent event, List<ISubscriber> subscribers) {
                    this.event = event;
                    this.subscribers = subscribers;
                }

                /**
                 * 發(fā)布消息
                 * @param event
                 */

                @Override
                public void publish(IEvent event){
                    event.print();
                }

                public IEvent getEvent() {
                    return event;
                }

                public void setEvent(IEvent event) {
                    this.event = event;
                }

                public List<ISubscriber> getSubscribers() {
                    return subscribers;
                }

                public void setSubscribers(List<ISubscriber> subscribers) {
                    this.subscribers = subscribers;
                }

            }

            事件:

            /**
             * 檢測事件
             */

            public class CheckEvent implements IEvent{

                private String name;

                private String result;

                private ISubscriber subscriber;

                public ISubscriber getSubscriber() {
                    return subscriber;
                }

                public void setSubscriber(ISubscriber subscriber) {
                    this.subscriber = subscriber;
                }

                public CheckEvent(String name) {
                    this.name = name;
                }

                @Override
                public void print() {
                    subscriber.look();
                    System.out.println("事件名稱(chēng):" + name);
                    System.out.println("事件結果:" + result);
                }


                public String getName() {
                    return name;
                }

                public void setName(String name) {
                    this.name = name;
                }

                public String getResult() {
                    return result;
                }

                public void setResult(String result) {
                    this.result = result;
                }
            }

            訂閱者:

            /**
             * 訂閱者
             */

            public class User implements ISubscriber{

                private String name;

                public User(String name) {
                    this.name = name;
                }

                public String getName() {
                    return name;
                }

                public void setName(String name) {
                    this.name = name;
                }

                @Override
                public void look() {
                    System.out.println("檢測姓名:" + name);
                }
            }

            客戶(hù)端:

            /**
             * 測試類(lèi)
             */

            public class TestDemo {

                public static void main(String[] args) {
                    //定義兩種結果
                    String[] doc = {"陰性""陽(yáng)性"};
                    //初始化檢測事件
                    CheckEvent check = new CheckEvent("核酸檢測");
                    //初始化消息發(fā)布者
                    Publisher publisher = new Publisher(check,new ArrayList<>());
                    //實(shí)例化接受檢測的用戶(hù)
                    List<ISubscriber> users = new ArrayList<>();
                    for (int i = 0; i < 10; i++) {
                        //初始化用戶(hù)
                        User user = new User("狼王" + i);
                        users.add(user);
                    }
                    //用戶(hù)訂閱事件
                    publisher.setSubscribers(users);
                    int index;
                    //發(fā)布檢測結果
                    for (int i = 0; i < 10; i++) {
                        System.out.println("---------------");
                        //隨機檢測結果
                        index = (int) (Math.random() * doc.length);
                        check.setSubscriber(users.get(i));
                        check.setResult(doc[index]);
                        //發(fā)布
                        publisher.publish(check);
                    }

                }
            }

            結果:

            ---------------
            檢測姓名:狼王0
            事件名稱(chēng):核酸檢測
            事件結果:陰性
            ---------------
            檢測姓名:狼王1
            事件名稱(chēng):核酸檢測
            事件結果:陰性
            ---------------
            檢測姓名:狼王2
            事件名稱(chēng):核酸檢測
            事件結果:陽(yáng)性
            ---------------
            檢測姓名:狼王3
            事件名稱(chēng):核酸檢測
            事件結果:陰性
            ---------------
            檢測姓名:狼王4
            事件名稱(chēng):核酸檢測
            事件結果:陽(yáng)性
            ---------------
            檢測姓名:狼王5
            事件名稱(chēng):核酸檢測
            事件結果:陽(yáng)性
            ---------------
            檢測姓名:狼王6
            事件名稱(chēng):核酸檢測
            事件結果:陽(yáng)性
            ---------------
            檢測姓名:狼王7
            事件名稱(chēng):核酸檢測
            事件結果:陰性
            ---------------
            檢測姓名:狼王8
            事件名稱(chēng):核酸檢測
            事件結果:陰性
            ---------------
            檢測姓名:狼王9
            事件名稱(chēng):核酸檢測
            事件結果:陰性

            4、分析

            代碼依賴(lài)關(guān)系如下圖所示:

            圖片

            分別定義了三個(gè)接口:事件接口,消息發(fā)布者接口,消息訂閱者接口每個(gè)接口有其對應的實(shí)現。

            這樣設計利于后續的擴展,在不同的事件和不同的訂閱者以及消息發(fā)布者,都可以進(jìn)行擴展而不影響其他。

            5、總結

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

            1)開(kāi)閉原則

            2)業(yè)務(wù)代碼解耦,具體消息訂閱者和發(fā)布者沒(méi)有直接關(guān)聯(lián)。

            缺點(diǎn):

            1)多個(gè)消費者存在的時(shí)候,可能會(huì )無(wú)法控制順序和時(shí)間較長(cháng)。



            關(guān)鍵字: 觀(guān)察者模式 設計模式

            文章連接: http://www.gostscript.com/cjwt/860.html

            版權聲明:文章由 晨展科技 整理收集,來(lái)源于互聯(lián)網(wǎng)或者用戶(hù)投稿,如有侵權,請聯(lián)系我們,我們會(huì )立即刪除。如轉載請保留

            双腿国产亚洲精品无码不卡|国产91精品无码麻豆|97久久久久久久极品|无码人妻少妇久久中文字幕
                1.