設計模式:行爲型->觀察者模式

參考這篇文章,很生動:https://zhuanlan.zhihu.com/p/158537313

有點像發佈訂閱,有不同之處,但是要實現的功能很像

 

舉了一個遊戲的例子

Hero類走格子,有怪物類,寶物類,走到格子時需要判斷是否進入這些格子並且產生效果。

 

傳統想法之一(拉取):怪物類隔100ms判斷一次,但這樣一直空轉

傳統想法之二(推送):把幾個類都寫到Hero類中了,每次Hero類移動時做判斷

 

觀察者模式:

 

 觀察者:實現Observer接口(怪物類,寶物類),主要功能就是update

 被觀察者:繼承Subject抽象類(Hero),有一個ObserverList,當需要更新時,notify觀察者

 

邏輯:被觀察者移動--notify觀察者--觀察者更新

 

代碼:

觀察者

//觀察者 接口
public interface Observer {
    public void update();
}


//怪物
public class Monster implements Observer {

    @Override
    public void update() {
        if(inRange()){
            System.out.println("怪物 對主角攻擊!");
        }
    }

    private boolean inRange(){
        //判斷主角是否在自己的影響範圍內,這裏忽略細節,直接返回true
        return true;
    }
}


//寶物 邏輯一樣
public class Treasure implements Observer {

    @Override
    public void update() {
        if(inRange()){
            System.out.println("寶物 爲主角加血!");
        }
    }

    private boolean inRange(){
        //判斷主角是否在自己的影響範圍內,這裏忽略細節,直接返回true
        return true;
    }
}

 

被觀察者:

//被觀察者
abstract public class Subject {

    private List<Observer> observerList = new ArrayList<Observer>();

    public void attachObserver(Observer observer) {
        observerList.add(observer);
    }//增加觀察者

    public void detachObserver(Observer observer){
        observerList.remove(observer);
    }//刪除觀察者

    public void notifyObservers(){
        for (Observer observer: observerList){
            observer.update();
        }
    }
}


//實際被觀察者,繼承Subject類
public class Hero extends Subject{
    void move(){
        System.out.println("主角向前移動");
        notifyObservers();
    }
}

 

main函數中代碼

public static void main(String[] args) {
        //初始化對象
        Hero hero = new Hero();
        Monster monster = new Monster();
        Trap trap = new Trap();
        Treasure treasure = new Treasure();
        //註冊觀察者
        hero.attachObserver(monster);
        hero.attachObserver(trap);
        hero.attachObserver(treasure);
        //移動事件
        hero.move();
    }
}

 

 如果在被觀察者之間有循環依賴的話,被觀察者會觸發它們之間進行循環調用,導致系統崩潰。在使用觀察者模式是要特別注意這一點。

 

和發佈訂閱的區別

 

 

 

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