设计模式:行为型->观察者模式

参考这篇文章,很生动: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();
    }
}

 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。

和发布订阅的区别

原文地址:https://www.cnblogs.com/take-it-easy/p/14626627.html