91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中觀察者模式與委托的實例對比分析

發布時間:2022-05-12 15:37:49 來源:億速云 閱讀:183 作者:iii 欄目:開發技術

這篇文章主要介紹“Java中觀察者模式與委托的實例對比分析”,在日常操作中,相信很多人在Java中觀察者模式與委托的實例對比分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中觀察者模式與委托的實例對比分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    代碼背景

    一個班級,有兩類學生,A類:不學習,玩,但是玩的東西不一樣,有的是做游戲,有的是看電視

    B類:放哨的學生,專門看老師的動向,如果老師進班了就立即通知大家。

    如此就形成了一個需求,放哨的學生要通知所有玩的學生:老師來了,而不同的學生有不同的反應,有的馬上把電視關閉,有的停止玩游戲。

    觀察者模式

    介紹

    觀察者模式:定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。
    這個主題對象在狀態發生變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。

    主要解決:一個對象狀態改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協作。

    何時使用:一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。

    如何解決:使用面向對象技術,可以將這種依賴關系弱化。

    關鍵代碼:在抽象類里有一個 ArrayList 存放觀察者們。

    實現

    Java中觀察者模式與委托的實例對比分析

    觀察者(學生)
    /**
     * 抽象的觀察者
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/10 - 15:32
     */
    public interface Observer {
        public abstract void updateState();
    }
    /**
     * 具體的觀察者
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/10 - 15:39
     */
    public class ConcreteObserver implements Observer{
        //觀察者的姓名
        private String name;
        //觀察者的狀態
        private String observerState;
        //明確具體的通知者
        private ConcreteSubject subject;
       //get set方法省略
        public ConcreteObserver(String name, ConcreteSubject subject) {
            this.name = name;
            this.subject = subject;
        }
        @Override
        public void updateState() {
            observerState=subject.getSubjectState();
            System.out.println(name+"在打游戲");
            String str=String.format("觀察者%s的:新狀態是%s", name,observerState);
            System.out.println(str);
        }
    }
    /**
     * 具體的觀察者
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/10 - 15:39
     */
    public class ConcreteObserver2 implements Observer{
        //觀察者的姓名
        private String name;
        //觀察者的狀態
        private String observerState;
        //明確具體的通知者
        private ConcreteSubject subject;
       //get set方法省略
        public ConcreteObserver2(String name, ConcreteSubject subject) {
            this.name = name;
            this.subject = subject;
        }
        @Override
        public void updateState() {
            observerState=subject.getSubjectState();
            System.out.println(name+"在看電視");
            String str=String.format("觀察者%s:新狀態是%s", name,observerState);
            System.out.println(str);
        }
    }
    通知者(老師)
    /**
     * 抽象的通知者
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/10 - 15:30
     */
    public abstract class Subject {
        //管理觀察者的集合
        private List<Observer> observers=new ArrayList<>();
        //增加觀察者
        public void add(Observer observer){
            observers.add(observer);
        }
        //減少觀察者
        public void detach(Observer observer){
            observers.remove(observer);
        }
        /**
         * 通知所有的觀察者
         */
        public void notifyMsg(){
            for (Observer observer : observers) {
                observer.updateState();
            }
        }
    }
    /**
     * 具體的通知者
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/10 - 15:38
     */
    public class ConcreteSubject extends Subject {
        //通知者的狀態
        private String subjectState;
        //get set方法
        public String getSubjectState() {
            return subjectState;
        }
        public void setSubjectState(String subjectState) {
            this.subjectState = subjectState;
        }
    }
    Main方法
    /**
     * 控制臺Main方法
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/10 - 15:48
     */
    public class MainTest {
        public static void main(String[] args) {
            //創建一個主題/通知者
            ConcreteSubject subject=new ConcreteSubject();
            //new出觀察者(學生)
            ConcreteObserver studentZhang = new ConcreteObserver("小張", subject);
            ConcreteObserver studentLiu = new ConcreteObserver("小劉", subject);
            ConcreteObserver studentWang = new ConcreteObserver("小王", subject);
            //將觀察者添加到通知隊列里
            subject.add(studentZhang);
            subject.add(studentLiu);
            subject.add(studentWang);
            //通知者(老師)狀態修改,通知每個學生
            subject.setSubjectState("老師回來了,我要好好學習");
            subject.notifyMsg();
            System.out.println("-----------");
        }
    }

    Java中觀察者模式與委托的實例對比分析

     委托 介紹

    委托可以看做是函數的抽象,是函數的“類”。委托的實例將代表一個具體的函數
    一個委托可以搭載多個方法,所有的方法被依次喚起。可以使委托對象所搭載的方法并不需要屬于同一類。
    委托事件模型可以由三個組件定義:事件、事件源和事件偵聽器。

    委托的實現簡單來講就是用反射來實現的。

    實現

    Java中觀察者模式與委托的實例對比分析

    觀察者
    /**
     * 監聽器/觀察者 玩游戲
     * 事件監聽器
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:17
     */
    public class PlayingGameListener {
        public PlayingGameListener(){
            System.out.println("我正在玩游戲 開始時間"+new Date());
        }
        public void stopPlayingGame(Date date){
            System.out.println("老師來了,快回到座位上,結束時間"+date);
        }
    }
    /**
     * 監聽器/觀察者 看電視
     * 事件監聽器
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:17
     */
    public class WatchingTVListener {
        public WatchingTVListener(){
            System.out.println("我正在看電視 "+new Date());
        }
        public void stopWatchingTV(Date date){
            System.out.println("老師來了,快關閉電視 。 結束時間"+date);
        }
    }
    通知者
    /**
     * 通知者的抽象類
     * 事件源
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:15
     */
    public abstract class Notifier {
        //每個通知者都有一個需要通知的隊列(通知:對象、方法、參數)
        private EventHandler eventHandler=new EventHandler();
        public EventHandler getEventHandler() {
            return eventHandler;
        }
        public void setEventHandler(EventHandler eventHandler) {
            this.eventHandler = eventHandler;
        }
        //增加需要幫忙放哨的學生
        public abstract void addListener(Object object,String methodName,Object...args);
        //告訴所有要幫忙放哨的學生:老師來了
        public abstract void notifyX();
    }
    /**
     * 通知者的子類,放哨人
     * 事件源
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:15
     */
    public class GoodNotifier extends Notifier {
        @Override
        public void addListener(Object object, String methodName, Object...args) {
            System.out.println("有新的同學委托盡職盡責的放哨人!");
            this.getEventHandler().addEvent(object, methodName, args);
        }
        @Override
        public void notifyX() {
            System.out.println("盡職盡責的放哨人告訴所有需要幫忙的同學:老師來了");
            try{
                //優化:異步通知
                this.getEventHandler().notifyX();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
     事件
    /**
     * 抽象出的事件類,也可以稱為方法類
     * 事件
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:03
     */
    public class Event {
        //要執行方法的對象
        private Object object;
        //要執行的方法名稱
        private String methodName;
        //要執行方法的參數
        private Object[] params;
        //要執行方法的參數類型
        private Class[] paramTypes;
        //若干setter getter
        public Object getObject() {
            return object;
        }
        public String getMethodName() {
            return methodName;
        }
        public void setMethodName(String methodName) {
            this.methodName = methodName;
        }
        public Object[] getParams() {
            return params;
        }
        public void setParams(Object[] params) {
            this.params = params;
        }
        public Class[] getParamTypes() {
            return paramTypes;
        }
        public void setParamTypes(Class[] paramTypes) {
            this.paramTypes = paramTypes;
        }
        public Event(){
        }
        public Event(Object object,String methodName,Object...args){
            this.object=object;
            this.methodName=methodName;
            this.params=args;
            contractParamTypes(this.params);
        }
        //根據參數數組生成參數類型數組
        private void contractParamTypes(Object[] params){
            this.paramTypes=new Class[params.length];
            for(int i=0;i<params.length;i++){
                this.paramTypes[i]=params[i].getClass();
            }
        }
        //執行該 對象的該方法
        public void invoke() throws Exception{
            //通過class,method,paramTypes 確定執行哪個類的哪個方法
            Method method=object.getClass().getMethod(this.getMethodName(), this.getParamTypes());
            if(null==method){
                return;
            }
            //方法執行
            method.invoke(this.getObject(), this.getParams());
        }
    }
    事件處理
    /**
     * 管理哪些事件需要執行
     * 管理事件
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:03
     */
    public class EventHandler {
        //是用一個List
        private List<Event> objects;
        //添加某個對象要執行的事件,及需要的參數
        public void addEvent(Object object,String methodName,Object...args){
            objects.add(new Event(object,methodName,args));
        }
        public EventHandler(){
            objects=new ArrayList<Event>();
        }
        //通知所有的對象執行指定的事件
        public void notifyX() throws Exception{
            for(Event e : objects){
                e.invoke();
            }
        }
    }

    Main方法

    /**
     * 啟動類
     *
     * @author Promsing(張有博)
     * @version 1.0.0
     * @since 2022/5/8 - 11:19
     */
    public class EventMain {
        public static void main(String[] args) {
            //創建一個盡職盡責的放哨者
            Notifier goodNotifier = new GoodNotifier();
            //創建一個玩游戲的同學,開始玩游戲
            PlayingGameListener playingGameListener = new PlayingGameListener();
            //創建一個看電視的同學,開始看電視
            WatchingTVListener watchingTVListener = new WatchingTVListener();
            //玩游戲的同學告訴放哨的同學,老師來了告訴一下
            goodNotifier.addListener(playingGameListener, "stopPlayingGame", new Date());
            //看電視的同學告訴放哨的同學,老師來了告訴一下
            goodNotifier.addListener(watchingTVListener, "stopWatchingTV", new Date());
            try {
                //一點時間后
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //老師出現,放哨的人通知所有要幫忙的同學:老師來了
            goodNotifier.notifyX();
        }
    }

    Java中觀察者模式與委托的實例對比分析

     總結

    1.先有觀察者模式后有委托事件技術
    2.觀察者模式只能通知繼承 Observer類 的子類,也可以將Observer改成接口

    for (Observer observer : observers) {
            observer.updateState();
    }

    3.委托可以通知任何類的任何方法。反射、everone

     Method method=object.getClass().getMethod(this.getMethodName(), this.getParamTypes());
    if(null==method){
            return;
    }
     method.invoke(this.getObject(), this.getParams());

    4.委托與觀察者比多了一個事件執行者,解除觀察者與通知者的耦合,可以做到通知任何對象的任何方法。讓A類學生和B類學生完全解耦,即A類完全不知道B類的學生,卻可以通知B類的學生

    6.建立一套觸發機制,可以使用異步通知

    7.觀察者/委托挺像MQ里邊的訂閱發布。生產者、隊列、消費者。

    到此,關于“Java中觀察者模式與委托的實例對比分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    洪洞县| 循化| 崇礼县| 汉阴县| 镇赉县| 常山县| 思南县| 彭山县| 托里县| 中阳县| 厦门市| 体育| 宾阳县| 大田县| 遂平县| 汉阴县| 胶州市| 大城县| 新干县| 镇沅| 河北区| 东乌珠穆沁旗| 布拖县| 怀仁县| 青河县| 吴堡县| 丹凤县| 敦化市| 盐池县| 门头沟区| 丁青县| 三门县| 湘潭市| 沙河市| 广平县| 普兰店市| 安岳县| 微博| 共和县| 奇台县| 娄底市|