漫画:设计模式中的 “观察者模式”

2020 年 7 月 10 日 CSDN

作者 | 程序员小灰

来源 | 程序员小灰

—————  第二天  —————

————————————

场景1:游戏操作界面
在一个小游戏中,包含一个简单的操作界面,界面上有两个按钮:道具和魔法。
如果点击“道具”按钮,游戏里的主角会使用道具;如果点击“魔法”按钮,游戏里的主角会使用魔法。
如何让主角实时接收到点击按钮的事件,并做出相应的行动呢?
场景2:游戏迷宫
同样在这个小游戏里,有一个迷宫,迷宫里有怪物、陷阱和宝物。
一旦主角移动到怪物的有效范围,怪物会袭击主角;主角移动到陷阱的有效范围,陷阱会困住主角;主角移动到宝物的有效范围,宝物会为主角加血。
如何让主角移动的事件被怪物、陷阱、道具感知到,并做出正确的反应?

   
   
     
public  class  Hero {
     //怪物
    Monster monster;
     //陷阱
    Trap trap;
     //宝物
    Treasure treasure;

     public void move(){
        System. out.println( "主角向前移动");
         //主角移动时,分别通知怪物、陷阱和宝物对象
        monster.update();
        trap.update();
        treasure.update();
    }
}

在上面的UML图中,主要有两组实体对象,一组是观察者,一组是被观察者。所有的观察者,都实现了Observer接口;所有的被观察者,都继承自Subject抽象类。
Subject类的成员OberverList,存储着已注册的观察者,当事件发生时,会通知列表中的所有观察者。需要注意的是,OberverList所依赖的是抽象的Observer接口,这样就避免了观察者与被观察者的紧耦合。
   
   
     
//观察者
public  interface  Observer {
     public void update();
}

//被观察者
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();
        }
    }
}
  
  
    
    
    
      

//怪物
public   class Monster implements Observer  {

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

     private boolean inRange() {
         //判断主角是否在自己的影响范围内,这里忽略细节,直接返回true
         return   true ;
    }
}

//陷阱
public   class Trap 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 ;
    }
}
上面代码中,每一个具体观察者类都实现了update方法,这是事件触发的回调方法,包含了具体观察者对事件的不同反应。
   
   
     
public  class Hero extends Subject{
     void move(){
        System.out.println( "主角向前移动");
        notifyObservers();
    }
}
当主角移动时,通知所有已注册的观察者,执行具体观察者各自的update方法。
  
  
    
    
    
      
public  class Client {
     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();
    }
}
代码输出如下:
主角向前移动
怪物 对主角攻击!
陷阱 困住主角!
宝物 为主角加血!

更多精彩推荐

☞马斯克、李彦宏、姚期智等云端纵论AI,他们都说了什么?

☞GitHub 开源代码究竟受不受美国出口管制?Linux 基金会白皮书官宣答案!

对话诸葛 io 孔淼:数据分析如何做,才能圈住用户?

云计算与星辰大海的结合——不要回答,来自百亿光年外的未知信号

用机器学习还原《隐秘的角落》那些被修改的台词

一文速览 Eth2.0 的 7 大客户端进展

点分享
点点赞
点在看
登录查看更多
0

相关内容

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
【干货书】贝叶斯推断随机过程,449页pdf
专知会员服务
151+阅读 · 2020年8月27日
【干货书】Python 编程,480页pdf
专知会员服务
237+阅读 · 2020年8月14日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【Manning2020新书】Elm 实战,344页pdf,Elm in Action
专知会员服务
49+阅读 · 2020年4月14日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
67+阅读 · 2020年3月9日
【数字孪生】使用数字孪生体进行预测性维护
产业智能官
27+阅读 · 2019年7月22日
通过Docker安装谷歌足球游戏环境
CreateAMind
11+阅读 · 2019年7月7日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
Kong 1.1 带来声明式配置与无数据库部署模式
开源中国
8+阅读 · 2019年3月28日
推荐一些适合小白练手的Python项目
数据挖掘入门与实战
6+阅读 · 2018年5月17日
设计和实现一款轻量级的爬虫框架
架构文摘
13+阅读 · 2018年1月17日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
6 款特别强大的黑科技App
高效率工具搜罗
4+阅读 · 2017年10月11日
Arxiv
3+阅读 · 2018年10月11日
Arxiv
7+阅读 · 2018年2月26日
Arxiv
7+阅读 · 2018年1月24日
VIP会员
相关VIP内容
【干货书】贝叶斯推断随机过程,449页pdf
专知会员服务
151+阅读 · 2020年8月27日
【干货书】Python 编程,480页pdf
专知会员服务
237+阅读 · 2020年8月14日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【Manning2020新书】Elm 实战,344页pdf,Elm in Action
专知会员服务
49+阅读 · 2020年4月14日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
67+阅读 · 2020年3月9日
相关资讯
【数字孪生】使用数字孪生体进行预测性维护
产业智能官
27+阅读 · 2019年7月22日
通过Docker安装谷歌足球游戏环境
CreateAMind
11+阅读 · 2019年7月7日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
Kong 1.1 带来声明式配置与无数据库部署模式
开源中国
8+阅读 · 2019年3月28日
推荐一些适合小白练手的Python项目
数据挖掘入门与实战
6+阅读 · 2018年5月17日
设计和实现一款轻量级的爬虫框架
架构文摘
13+阅读 · 2018年1月17日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
6 款特别强大的黑科技App
高效率工具搜罗
4+阅读 · 2017年10月11日
Top
微信扫码咨询专知VIP会员