設計模式學習筆記——觀察者(Observer)模式
@(設計模式)[設計模式, 觀察者模式, Observer]
基本介紹
觀察者模式也稱爲發佈-訂閱模式。
在觀察者訂閱被觀察者發佈的內容時,所訂閱的內容發生變化,觀察者會接到相應通知。觀察者可以進行相應處理。
觀察者案例
類圖
實現代碼
Observer接口
package com.pc.observer.example;
/**
* 觀察者接口
* Created by Switch on 2017/3/30.
*/
public interface Observer {
/**
* 更新
*
* @param generator 數值生成器
*/
void update(NumberGenerator generator);
}
DigitObserver類
package com.pc.observer.example;
/**
* 數字觀察者對象
* Created by Switch on 2017/3/30.
*/
public class DigitObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:" + generator.getNumber());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
GraphObserver類
package com.pc.observer.example;
/**
* 圖形觀察者類
* Created by Switch on 2017/3/30.
*/
public class GraphObserver implements Observer {
@Override
public void update(NumberGenerator generator) {
System.out.print("GraphObserver:");
for (int i = 0; i < generator.getNumber(); i++) {
System.out.print("*");
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
NumberGenerator抽象類
package com.pc.observer.example;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 數值生成器抽象類
* Created by Switch on 2017/3/30.
*/
public abstract class NumberGenerator {
/**
* 觀察者列表
*/
private List<Observer> observers = new ArrayList<>();
/**
* 添加觀察者
*
* @param observer 觀察者對象
*/
public void addObserver(Observer observer) {
observers.add(observer);
}
/**
* 刪除指定觀察者
*
* @param observer 觀察者對象
*/
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
/**
* 向觀察者列表中的所有觀察者發送通知
*/
public void notifyObservers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer observer = it.next();
observer.update(this);
}
}
/**
* 獲取數值
*
* @return 數值
*/
public abstract int getNumber();
/**
* 生成數值
*/
public abstract void execute();
}
RandomNumberGenerator類
package com.pc.observer.example;
import java.util.Random;
/**
* 隨機數值生成器類
* Created by Switch on 2017/3/30.
*/
public class RandomNumberGenerator extends NumberGenerator {
/**
* 隨機數生成器
*/
private Random random = new Random();
/**
* 當前數值
*/
private int number;
@Override
public int getNumber() {
return this.number;
}
@Override
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
this.notifyObservers();
}
}
}
測試類
package com.pc.observer.example.test;
import com.pc.observer.example.*;
import org.junit.Test;
/**
* DigitObserver Tester.
*
* @author Switch
* @version 1.0
*/
public class ObserverTest {
/**
* 測試觀察者模式
*/
@Test
public void testObserver() {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}
運行結果
DigitObserver:15
GraphObserver:***************
DigitObserver:43
GraphObserver:*******************************************
DigitObserver:17
GraphObserver:*****************
DigitObserver:21
GraphObserver:*********************
DigitObserver:12
GraphObserver:************
DigitObserver:15
GraphObserver:***************
DigitObserver:11
GraphObserver:***********
DigitObserver:34
GraphObserver:**********************************
DigitObserver:0
GraphObserver:
DigitObserver:37
GraphObserver:*************************************
DigitObserver:12
GraphObserver:************
DigitObserver:38
GraphObserver:**************************************
DigitObserver:22
GraphObserver:**********************
DigitObserver:30
GraphObserver:******************************
DigitObserver:1
GraphObserver:*
DigitObserver:28
GraphObserver:****************************
DigitObserver:44
GraphObserver:********************************************
DigitObserver:45
GraphObserver:*********************************************
DigitObserver:23
GraphObserver:***********************
DigitObserver:45
GraphObserver:*********************************************
觀察者模式中的角色
Subject(觀察對象)
Subject
角色表示觀察對象。Subject
角色定義了註冊觀察者和刪除觀察者的方法。此外,它還聲明瞭“獲取現在的狀態”的方法。在案例中,由NumberGenerator
類扮演此角色。
ConcreteSubject(具體的觀察對象)
ConcreteSubject
角色表示具體的被觀察對象。當自身狀態發生變化後,它會通知所有已經註冊的Observer
角色。在案例中,由RandomNumberGenerator
類扮演此角色。
Observer(觀察者)
Observer
角色負責接收來自Subject
角色的狀態變化的通知。爲此,它聲明瞭update
方法。在案例中,由Observer
接口扮演此角色。
ConcreteObserver(具體的觀察者)
ConcreteObserver
角色表示具體的Observer
。當它的update
方法被調用後,會去獲取要觀察的對象的最新狀態。在案例中,由DigitObserver
類和GraphObserver
類扮演此角色。
類圖
GitHub:DesignPatternStudy
——————參考《圖解設計模式》