一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - Java設(shè)計(jì)模式開發(fā)中使用觀察者模式的實(shí)例教程

Java設(shè)計(jì)模式開發(fā)中使用觀察者模式的實(shí)例教程

2020-04-19 13:45匆忙擁擠repeat JAVA教程

這篇文章主要介紹了Java設(shè)計(jì)模式開發(fā)中使用觀察者模式的實(shí)例教程,松耦合和邏輯清晰的消息監(jiān)聽是觀察者模式的大特色,需要的朋友可以參考下

觀察者模式是軟件設(shè)計(jì)模式中的一種,使用也比較普遍,尤其是在GUI編程中。關(guān)于設(shè)計(jì)模式的文章,網(wǎng)絡(luò)上寫的都比較多,而且很多文章寫的也不錯(cuò),雖然說有一種重復(fù)早輪子的嫌疑,但此輪子非彼輪子,側(cè)重點(diǎn)不同,思路也不同,講述方式也不近相同。
關(guān)鍵要素

主題:

主題是觀察者觀察的對(duì)象,一個(gè)主題必須具備下面三個(gè)特征。

  • 持有監(jiān)聽的觀察者的引用
  • 支持增加和刪除觀察者
  • 主題狀態(tài)改變,通知觀察者

觀察者:

當(dāng)主題發(fā)生變化,收到通知進(jìn)行具體的處理是觀察者必須具備的特征。

為什么要用這種模式

這里舉一個(gè)例子來說明,牛奶送奶站就是主題,訂奶客戶為監(jiān)聽者,客戶從送奶站訂閱牛奶后,會(huì)每天收到牛奶。如果客戶不想訂閱了,可以取消,以后就不會(huì)收到牛奶。

松耦合

觀察者增加或刪除無需修改主題的代碼,只需調(diào)用主題對(duì)應(yīng)的增加或者刪除的方法即可。
主題只負(fù)責(zé)通知觀察者,但無需了解觀察者如何處理通知。舉個(gè)例子,送奶站只負(fù)責(zé)送遞牛奶,不關(guān)心客戶是喝掉還是洗臉。
觀察者只需等待主題通知,無需觀察主題相關(guān)的細(xì)節(jié)。還是那個(gè)例子,客戶只需關(guān)心送奶站送到牛奶,不關(guān)心牛奶由哪個(gè)快遞人員,使用何種交通工具送達(dá)。

Java實(shí)現(xiàn)觀察者模式
1. Java自帶的實(shí)現(xiàn)

類圖

Java設(shè)計(jì)模式開發(fā)中使用觀察者模式的實(shí)例教程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
 * 觀察目標(biāo) 繼承自 java.util.Observable
 * @author stone
 *
 */
public class UpdateObservable extends Observable {
   
  private int data;
   
  public UpdateObservable(Observer observer) {
    addObserver(observer);
    /*
     * add other observer
     */
  }
   
  public int getData() {
    return data;
  }
   
  public void setData(int data) {
    if (data != this.data) {
      this.data = data;
      setChanged(); //標(biāo)記 改變, 只有標(biāo)記后才能通知到
      notifyObservers(); //通知
    }
     
  }
 
  @Override
  public synchronized void addObserver(Observer o) {
    super.addObserver(o);
  }
 
  @Override
  public synchronized void deleteObserver(Observer o) {
    super.deleteObserver(o);
  }
 
  @Override
  public void notifyObservers() {
    super.notifyObservers();
  }
 
  @Override
  public void notifyObservers(Object arg) {
    super.notifyObservers(arg);
  }
 
  @Override
  public synchronized void deleteObservers() {
    super.deleteObservers();
  }
 
  @Override
  protected synchronized void setChanged() {
    super.setChanged();
  }
 
  @Override
  protected synchronized void clearChanged() {
    super.clearChanged();
  }
 
  @Override
  public synchronized boolean hasChanged() {
    return super.hasChanged();
  }
 
  @Override
  public synchronized int countObservers() {
    return super.countObservers();
  }
   
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * 觀察者 實(shí)現(xiàn) java.util.Observer接口
 * @author stone
 *
 */
public class UpdateObserver implements Observer {
 
  @Override
  public void update(Observable o, Object arg) {
    System.out.println("接收到數(shù)據(jù)變化的通知:");
    if (o instanceof UpdateObservable) {
      UpdateObservable uo = (UpdateObservable) o;
      System.out.print("數(shù)據(jù)變更為:" + uo.getData());
    }
  }
 
}

2. 自定義的觀察模型
類圖

Java設(shè)計(jì)模式開發(fā)中使用觀察者模式的實(shí)例教程

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * 抽象觀察者  Observer
 * 觀察 更新    
 * @author stone
 *
 */
public interface IWatcher {
  /*
   * 通知接口:
   * 1. 簡單通知
   * 2. 觀察者需要目標(biāo)的變化的數(shù)據(jù),那么可以將目標(biāo)用作參數(shù), 見Java的Observer和Observable
   */
// void update(IWatched watched);
   
  void update();
   
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * 抽象目標(biāo) Subject
 * 提供注冊(cè)和刪除觀察者對(duì)象的接口, 及通知觀察者進(jìn)行觀察的接口
 * 及目標(biāo) 自身被觀察的業(yè)務(wù)的接口
 * @author stone
 *
 */
public interface IWatchedSubject {
   
  public void add(IWatcher watch);
 
  public void remove(IWatcher watch);
   
  public void notifyWhatchers();
   
  public void update();//被觀察業(yè)務(wù)變化的接口
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 具體觀察者    Concrete Observer
 *
 * @author stone
 *
 */
public class UpdateWatcher implements IWatcher {
 
  @Override
  public void update() {
    System.out.println(this + "觀察到:目標(biāo)已經(jīng)更新了");
  }
 
}

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * 具體目標(biāo)角色  Concrete Subject
 * @author stone
 *
 */
public class UpdateWatchedSubject implements IWatchedSubject {
  private List<IWatcher> list;
   
  public UpdateWatchedSubject() {
    this.list = new ArrayList<IWatcher>();
  }
   
  @Override
  public void add(IWatcher watch) {
    this.list.add(watch);
  }
 
  @Override
  public void remove(IWatcher watch) {
    this.list.remove(watch);
  }
 
  @Override
  public void notifyWhatchers() {
    for (IWatcher watcher : list) {
      watcher.update();
    }
  }
   
  @Override
  public void update() {
    System.out.println("目標(biāo)更新中....");
    notifyWhatchers();
  }
 
}

 

監(jiān)聽器是觀察者的一種實(shí)現(xiàn):
類圖

Java設(shè)計(jì)模式開發(fā)中使用觀察者模式的實(shí)例教程

?
1
2
3
4
5
6
7
8
/**
 * 監(jiān)聽 用戶在注冊(cè)后
 * @author stone
 *
 */
public interface IRegisterListener {
  void onRegistered();
}
?
1
2
3
4
5
6
7
8
/**
 * 監(jiān)聽 當(dāng)用戶登錄后
 * @author stone
 *
 */
public interface ILoginListener {
  void onLogined();
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * 監(jiān)聽器 是觀察者模式的一種實(shí)現(xiàn)
 * 一些需要監(jiān)聽的業(yè)務(wù)接口上添加 監(jiān)聽器,調(diào)用監(jiān)聽器的相應(yīng)方法,實(shí)現(xiàn)監(jiān)聽
 */
public class User {
   
  public void register(IRegisterListener register) {
    /*
     * do ... register
     */
    System.out.println("正在注冊(cè)中...");
    //注冊(cè)后
    register.onRegistered();
  }
 
  public void login(ILoginListener login) {
    /*
     * do ... login
     */
    System.out.println("正在登錄中...");
    //登錄后
    login.onLogined();
  }
 
}

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
 * 觀察者(Observer)模式 行為型模式
 *  觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)觀察某一個(gè)目標(biāo)對(duì)象。
 *  這個(gè)目標(biāo)對(duì)象在狀態(tài)上發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,讓它們能夠自動(dòng)更新自己
 * 目標(biāo)對(duì)象中需要有添加、移除、通知 觀察者的接口
 
 * @author stone
 */
public class Test {
   
  public static void main(String[] args) {
    /*
     * 使用Java自帶的Observer接口和Observable類
     */
    UpdateObservable observable = new UpdateObservable(new UpdateObserver());
    observable.setData(99);
    System.out.println("");
    System.out.println("");
    /*
     * 自定義的觀察者模型
     */
    IWatchedSubject watched = new UpdateWatchedSubject();
    watched.add(new UpdateWatcher());
    watched.add(new UpdateWatcher());
    watched.update();
    System.out.println("");
     
    /*
     * 子模式-監(jiān)聽器
     */
     
    User user = new User();
    user.register(new IRegisterListener() {
       
      @Override
      public void onRegistered() {
        System.out.println("監(jiān)聽到注冊(cè)后。。。");
      }
    });
    user.login(new ILoginListener() {
       
      @Override
      public void onLogined() {
        System.out.println("監(jiān)聽到登錄后。。。");
      }
    });
     
  }
}

 

打印

?
1
2
3
4
5
6
7
8
9
10
11
接收到數(shù)據(jù)變化的通知:
數(shù)據(jù)變更為:99
 
目標(biāo)更新中....
observer.UpdateWatcher@457471e0觀察到:目標(biāo)已經(jīng)更新了
observer.UpdateWatcher@5fe04cbf觀察到:目標(biāo)已經(jīng)更新了
 
正在注冊(cè)中...
監(jiān)聽到注冊(cè)后。。。
正在登錄中...
監(jiān)聽到登錄后。。。

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 无码骚夜夜精品 | 欧美巨吊| 亚洲免费精品 | 视频高h | 国产综合成色在线视频 | 幻女free性俄罗斯第一次摘花 | 国产一级毛片国语版 | 亚洲视频中文 | juliaann大战黑人 | ipx 在线播放| 惩罚狠h调教灌满 | 色噜噜国产精品视频一区二区 | 欧美伊人久久久久久久久影院 | 国模丰满美女冰漪34d | 91你懂的 | 亚洲一级特黄 | 亚洲国产成人久久综合一区77 | 日韩a级片视频 | 蜜桃影像传媒推广 | 美女逼逼喷水 | 午夜宅男宅女看在线观看 | 99视频在线观看视频 | 欧美综合色网 | 亚洲欧美在线免费观看 | 农村老少伦小说 | 亚洲v成人天堂影视 | 国产亚洲玖玖玖在线观看 | 34看网片午夜理 | 欧美激情影音先锋 | 亚洲国产精品综合一区在线 | 精品日产1区2卡三卡麻豆 | 精品免费视在线视频观看 | 亚洲国产精品嫩草影院久久 | free极度另类性欧美 | 日韩在线视频免费不卡一区 | 波多野结衣作品在线观看 | 日韩欧美亚洲国产高清在线 | 操乳 | avtt在线观看 | 日本在线视频免费观看 | 青青青青青国产费线在线观看 |