欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式中的觀察者模式

 更新時(shí)間:2023年02月16日 15:27:31   作者:非凡的小笨魚(yú)  
觀察者模式定義對(duì)象之間的一種一對(duì)多的依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),其相關(guān)的依賴對(duì)象都可以得到通知并被自動(dòng)更新。主要用于多個(gè)不同的對(duì)象對(duì)一個(gè)對(duì)象的某個(gè)方法會(huì)做出不同的反應(yīng)

一.介紹

觀察者模式(Observer Pattern)屬于行為型模式。定義了對(duì)象之間的一對(duì)多依賴,讓多個(gè)觀察者同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象,類似于廣播機(jī)制,只需要分發(fā)廣播,感興趣的對(duì)象自動(dòng)接收該廣播。我們平常所說(shuō)的Observer、Listener、Hook、Callback都和這個(gè)模式有關(guān)

二.場(chǎng)景約束

小孩(Baby)哭的時(shí)候會(huì)通知到爸爸(Dad)和媽媽(Mum),爸爸媽媽會(huì)對(duì)此采取不同的行為

三.UML類圖

版本一

版本二

新增事件類將觀察者與主題解耦,觀察者可以根據(jù)不同的事件執(zhí)行不同的操作,也可以直接對(duì)事件源進(jìn)行操作

四.示意代碼(版本一)

業(yè)務(wù)代碼

//抽象觀察者
public interface Observer {
    void action();
}
//抽象主題
abstract class Subject{
    protected List<Observer> observers = new ArrayList<>();
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    public abstract void notifyObserver();
}
//具體主題-被觀察者
class Baby extends Subject{
    @Override
    public void notifyObserver() {
        System.out.println("baby cry");
        observers.forEach(Observer::action);
    }
}
//具體觀察者
class Dad implements Observer {
    @Override
    public void action() {
        System.out.println("dad feed baby");
    }
}
//具體觀察者
class Mum implements Observer {
    @Override
    public void action() {
        System.out.println("mum hug baby");
    }
}

客戶端

public class Client {
    public static void main(String[] args) {
        Baby baby = new Baby();
        baby.addObserver(new Mum());
        baby.addObserver(new Dad());
        baby.notifyObserver();
    }
}

五.示意代碼(版本二)

//抽象觀察者
public interface Observer {
    void action(Event event);
}
//抽象主題
abstract class Subject {
    protected List<Observer> observers = new ArrayList<>();
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    public abstract void notifyObserver();
}
//具體主題-被觀察者
class Baby extends Subject {
    @Override
    public void notifyObserver() {
        System.out.println("baby cry");
        CryEvent cryEvent = new CryEvent(new Date().getTime(), this);
        observers.forEach(observer -> observer.action(cryEvent));
    }
}
//抽象事件
abstract class Event {
    public abstract Object getSource();
}
//具體事件
class CryEvent extends Event {
    public long when;
    Baby source;
    public CryEvent(long when, Baby source) {
        this.when = when;
        this.source = source;
    }
    @Override
    public Baby getSource() {
        return source;
    }
}
//具體觀察者
class Dad implements Observer {
    @Override
    public void action(Event event) {
        System.out.println("dad feed baby");
        if(event.getSource() instanceof Baby){
            System.out.println("dad對(duì)事件源進(jìn)行處理");
        }
    }
}
//具體觀察者
class Mum implements Observer {
    @Override
    public void action(Event event) {
        System.out.println("mum hug baby");
        if(event.getSource() instanceof Baby){
            System.out.println("mum對(duì)事件源進(jìn)行處理");
        }
    }
}

客戶端

public class Client {
    public static void main(String[] args) {
       Baby baby = new Baby();
       baby.addObserver(new Dad());
       baby.addObserver(new Mum());
       baby.notifyObserver();
    }
}

六.觀察者模式與發(fā)布訂閱模式

發(fā)布訂閱模式

  • 發(fā)布者不會(huì)直接通知訂閱者
  • 發(fā)布者與訂閱者完全解耦

觀察者模式

  • 主題要自己通知(notify)觀察者
  • 主題與觀察者松耦合

七.優(yōu)點(diǎn)

  • 符合依賴倒置原則(觀察者與主題都依賴于抽象)
  • 降低耦合(主題與觀察者之間的耦合關(guān)系)

八.在JDK中的典型應(yīng)用

在java.awt包下有很多觀察者模式的身影,先來(lái)看下簡(jiǎn)單的UML類圖

主題角色:java提供的組件類(以Button為例) 觀察者角色:java提供的事件監(jiān)聽(tīng)(各種Listener) 事件角色:鼠標(biāo)事件、鍵盤事件等等

再來(lái)看看一個(gè)小demo 在窗口中添加一個(gè)按鈕,給按鈕添加上鼠標(biāo)與鍵盤的相關(guān)事件,當(dāng)點(diǎn)擊按鈕或者按下鍵盤的時(shí)候在控制臺(tái)打印相應(yīng)的語(yǔ)句

public class MainFrame extends JFrame {
    public MainFrame() throws HeadlessException {
        //定義一個(gè)具體主題
        Button button = new Button("click");
        //給主題添加觀察者(鼠標(biāo)監(jiān)聽(tīng))
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //MouseEvent就是具體事件
                System.out.println("按鈕被點(diǎn)擊");
            }
        });
        //給主題添加觀察者(鍵盤監(jiān)聽(tīng))
        button.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                //KeyEvent就是具體事件
                System.out.println("按下" + e.getKeyChar());
            }
        });
        add(button);
        setSize(100,100);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
    public static void main(String[] args) {
        new MainFrame();
    }
}

這里的KeyAdapter與MouseAdapter使用的是適配器模式

到此這篇關(guān)于Java設(shè)計(jì)模式中的觀察者模式的文章就介紹到這了,更多相關(guān)Java觀察者模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的Spring框架下的AOP編程模式示例

    Java的Spring框架下的AOP編程模式示例

    這篇文章主要介紹了Java的Spring框架下的AOP編程模式示例,文中分別講到了基于XML和基于@AspectJ的自定義方式,需要的朋友可以參考下
    2015-12-12
  • Springboot如何集成jodconverter做文檔轉(zhuǎn)換

    Springboot如何集成jodconverter做文檔轉(zhuǎn)換

    這篇文章主要介紹了Springboot如何集成jodconverter做文檔轉(zhuǎn)換問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java接收text/event-stream格式數(shù)據(jù)的詳細(xì)代碼

    Java接收text/event-stream格式數(shù)據(jù)的詳細(xì)代碼

    這篇文章主要介紹了java接收text/event-stream格式數(shù)據(jù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 關(guān)于thymeleaf判斷對(duì)象是否為空的相關(guān)邏輯處理

    關(guān)于thymeleaf判斷對(duì)象是否為空的相關(guān)邏輯處理

    這篇文章主要介紹了關(guān)于thymeleaf判斷對(duì)象是否為空的相關(guān)邏輯處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Spring如何通過(guò)注解引入外部資源(PropertySource?Value)

    Spring如何通過(guò)注解引入外部資源(PropertySource?Value)

    這篇文章主要為大家介紹了Spring通過(guò)注解@PropertySource和@Value引入外部資源的方法實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Jmeter邏輯控制器事務(wù)控制器使用方法解析

    Jmeter邏輯控制器事務(wù)控制器使用方法解析

    這篇文章主要介紹了Jmeter邏輯控制器事務(wù)控制器使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java中@InitBinder注解的使用原理詳解

    Java中@InitBinder注解的使用原理詳解

    這篇文章主要介紹了Java中@InitBinder注解的使用原理詳解,在Java中,@InitBinder 注解是用于標(biāo)記一個(gè)方法,該方法將在控制器(Controller)處理請(qǐng)求之前被調(diào)用,用于進(jìn)行一些數(shù)據(jù)綁定和預(yù)處理的操作,需要的朋友可以參考下
    2023-10-10
  • MyBatis多對(duì)多映射初識(shí)教程

    MyBatis多對(duì)多映射初識(shí)教程

    這篇文章重點(diǎn)給大家介紹mybatis多對(duì)多映射,多對(duì)多映射的例子也很常見(jiàn),本文通過(guò)代碼實(shí)例相結(jié)合的方式給大家介紹mybatis多對(duì)多映射,需要的朋友參考下吧
    2016-08-08
  • Java線程通信詳解

    Java線程通信詳解

    本篇文章主要介紹了Java線程通信問(wèn)題,線程通信用來(lái)保證線程協(xié)調(diào)運(yùn)行,有需要的朋友可以了解一下。
    2016-10-10
  • Java對(duì)象的內(nèi)存布局詳細(xì)介紹

    Java對(duì)象的內(nèi)存布局詳細(xì)介紹

    這篇文章主要介紹了Java對(duì)象的內(nèi)存布局,我們知道在Java中基本數(shù)據(jù)類型的大小,例如int類型占4個(gè)字節(jié)、long類型占8個(gè)字節(jié),那么Integer對(duì)象和Long對(duì)象會(huì)占用多少內(nèi)存呢?本文介紹一下Java對(duì)象在堆中的內(nèi)存結(jié)構(gòu)以及對(duì)象大小的計(jì)算
    2023-02-02

最新評(píng)論