設計模式學習筆記——觀察者(Observer)模式

設計模式學習筆記——觀察者(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

——————參考《圖解設計模式》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章