Java設(shè)計模式之觀察者模式
什么是觀察者模式
- 先講什么是行為性模型,行為型模式關(guān)注的是系統(tǒng)中對象之間的相互交互,解決系統(tǒng)在運(yùn)行時對象 之間的相互通信和協(xié)作,進(jìn)一步明確對象的職責(zé)。
- 觀察者模式,是一種行為性模型,又叫發(fā)布-訂閱模式,他定義對象之間一種一對多的依賴關(guān)系,使得當(dāng)一個對象改變狀態(tài),則所有依賴于它的對象都會得到通知并自動更新。
觀察者模式職責(zé)
觀察者模式主要用于1對N的通知。當(dāng)一個對象的狀態(tài)變化時,他需要及時告知一系列對象,令他們做出相應(yīng)。 實(shí)現(xiàn)有兩種方式:
- 推:每次都會把通知以廣播的方式發(fā)送給所有觀察者,所有的觀察者只能被動接收。
- 拉:觀察者只要知道有情況即可,至于什么時候獲取內(nèi)容,獲取什么內(nèi)容,都可以自主決定。
應(yīng)用實(shí)例
現(xiàn)實(shí)中有一個金額變化以后,會有短信提示和支付寶提示的例子,短信和支付寶就是金額變化的觀察者。
傳統(tǒng)模式
金額數(shù)據(jù)類
public class MoneyData {
private BigDecimal amount;
private SMS sms;
MoneyData(BigDecimal value){
amount = value;
sms = new SMS();
}
public void increase(BigDecimal value){
amount = amount.add(value);
sms.sendMsg("通知:余額+"+value+",現(xiàn)余額為:"+amount);
}
public void decrease(BigDecimal value){
amount = amount.subtract(value);
sms.sendMsg("通知:余額-"+value+",現(xiàn)余額為:"+amount);
}
}
短信類
public class SMS {
public void sendMsg(String str){
System.out.println("短信"+str);
}
}
客戶端類
public class Client {
public static void main(String[] args) {
MoneyData moneyData = new MoneyData(new BigDecimal("5.20"));
moneyData.increase(new BigDecimal("13.14"));
moneyData.decrease(new BigDecimal("13.14"));
}
}
/**
* 短信通知:余額+13.14,現(xiàn)余額為:18.34
* 短信通知:余額-13.14,現(xiàn)余額為:5.20
*/
傳統(tǒng)模式擴(kuò)展性十分差,如果新增一個支付寶觀察者,需要修改金額數(shù)據(jù)類,增加一個成員變量。
違反了ocp原則(開閉原則)。可以通過觀察者模式修改,讓觀察者放入一個List列表中
觀察者模式
Subject抽象類
public abstract class Subject {
protected List<Observer> observers = new LinkedList<>();
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
if(observers.contains(o)){
observers.remove(o);
}
}
public abstract void notifyObservers(String changeValue);
}
Subject 的具體實(shí)現(xiàn)類
public class MoneyData extends Subject{
private BigDecimal amount;
MoneyData(BigDecimal value){
this.amount = value;
}
public void increase(BigDecimal value){
amount = amount.add(value);
notifyObservers("+"+value);
}
public void decrease(BigDecimal value){
amount = amount.subtract(value);
notifyObservers("-"+value);
}
@Override
public void notifyObservers(String changeValue) {
for (Observer observer : observers) {
observer.sendMsg("通知:余額"+changeValue+",現(xiàn)余額為"+amount);
}
}
}
Observer(觀察者)接口
public class SMS implements Observer{
@Override
public void sendMsg(String msg) {
System.out.println("短信"+msg);
}
}
Observer(觀察者)的兩個具體實(shí)現(xiàn)類
public class SMS implements Observer{
@Override
public void sendMsg(String msg) {
System.out.println("短信"+msg);
}
}
public class Alipay implements Observer{
@Override
public void sendMsg(String msg) {
System.out.println("支付寶"+msg);
}
}
客戶端類
public class Client {
public static void main(String[] args) {
MoneyData moneyData = new MoneyData(new BigDecimal("13.14"));
moneyData.registerObserver(new SMS());
moneyData.increase(new BigDecimal("52.00"));
moneyData.decrease(new BigDecimal("52.00"));
moneyData.registerObserver(new Alipay());
moneyData.increase(new BigDecimal("5.20"));
moneyData.decrease(new BigDecimal("5.20"));
}
}
/**
* 短信通知:余額+52.00,現(xiàn)余額為65.14
* 短信通知:余額-52.00,現(xiàn)余額為13.14
* 短信通知:余額+5.20,現(xiàn)余額為18.34
* 支付寶通知:余額+5.20,現(xiàn)余額為18.34
* 短信通知:余額-5.20,現(xiàn)余額為13.14
* 支付寶通知:余額-5.20,現(xiàn)余額為13.14
*/
應(yīng)用場景
- 對象間存在一對多關(guān)系,一個對象的狀態(tài)發(fā)生改變會影響其他對象。
- 當(dāng)一個抽象模型有兩個方面,其中一個方面依賴于另一方面時,可將這二者封裝在獨(dú)立的對象中以使它們可以各自獨(dú)立地改變和復(fù)用。
到此這篇關(guān)于Java設(shè)計模式之觀察者模式的文章就介紹到這了,更多相關(guān)Java觀察者模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JVisualVM之Java性能監(jiān)控與調(diào)優(yōu)利器詳解
本文將詳細(xì)介紹JVisualVM的使用方法,并結(jié)合實(shí)際案例展示如何利用它進(jìn)行性能調(diào)優(yōu),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05
SpringBoot整合Mybatis?LocalDateTime?映射失效的解決
這篇文章主要介紹了SpringBoot整合Mybatis?LocalDateTime?映射失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
Java數(shù)據(jù)結(jié)構(gòu)之對象比較詳解
這篇文章主要為大家詳細(xì)介紹了Java中對象的比較、集合框架中PriorityQueue的比較方式以及PriorityQueue的模擬實(shí)現(xiàn),感興趣的可以了解一下2022-07-07
Java?EasyExcel實(shí)現(xiàn)合并相同內(nèi)容單元格與動態(tài)標(biāo)題功能
這篇文章主要為大家詳細(xì)介紹了Java?EasyExcel如何實(shí)現(xiàn)合并相同內(nèi)容單元格與動態(tài)標(biāo)題功能,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下2023-12-12

