zoukankan      html  css  js  c++  java
  • 设计模式:行为型->观察者模式

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

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

    和发布订阅的区别

  • 相关阅读:
    C Looooops(扩展欧几里得)题解
    POJ1061 青蛙的约会(扩展欧几里得)题解
    UVA 11426 GCD
    Trailing Zeroes (III) (二分)题解
    BZOJ 1977 次小生成树
    BZOJ 4557 侦查守卫
    codevs 1088 神经网络
    codevs 1135 选择客栈
    BZOJ 3527 力
    BZOJ 1610 连线游戏
  • 原文地址:https://www.cnblogs.com/take-it-easy/p/14626627.html
Copyright © 2011-2022 走看看